## File: README.md

## What is Spin?

Spin is an open source framework for building and running fast, secure, and
composable cloud microservices with WebAssembly. It aims to be the easiest way
to get started with WebAssembly microservices, and takes advantage of the latest
developments in the
[WebAssembly component model](https://github.com/WebAssembly/component-model)
and [Wasmtime](https://wasmtime.dev/) runtime.

Spin offers a simple CLI that helps you create, distribute, and execute
applications, and in the next sections we will learn more about Spin
applications and how to get started.

## Getting started

See the [Install Spin](https://spinframework.dev/install) page of the [Spin documentation](https://spinframework.dev) for a detailed
guide on installing and configuring Spin, but in short run the following commands:
```bash
curl -fsSL https://spinframework.dev/downloads/install.sh | bash
sudo mv ./spin /usr/local/bin/spin
```

Alternatively, you could [build Spin from source](https://spinframework.dev/contributing-spin).

To get started writing apps, follow the [quickstart guide](https://spinframework.dev/quickstart/),
and then follow the
[Rust](https://spinframework.dev/rust-components/), [JavaScript](https://spinframework.dev/javascript-components), [Python](https://spinframework.dev/python-components), or [Go](https://spinframework.dev/go-components/)
language guides, and the [guide on writing Spin applications](https://spinframework.dev/writing-apps/).

## Language support

WebAssembly is a language-agnostic runtime: you can build WebAssembly components from a variety of source languages. Spin SDKs are available for several languages, including:

* JavaScript: https://github.com/spinframework/spin-js-sdk
* Rust: https://crates.io/crates/spin-sdk
* Go: https://pkg.go.dev/github.com/fermyon/spin/sdk/go/v2
* Python: https://github.com/spinframework/spin-python-sdk
* Zig: https://github.com/dasimmet/zig-spin (third party)
* Moonbit: https://github.com/gmlewis/spin-moonbit-sdk (third party)

> The Spin framework team supports the JavaScript, Rust, Go, and Python SDKs. Other language integrations are supported by their authors, and we're grateful to them for their work!

## Usage

Below is an example of using the `spin` CLI to create a new Spin application.  To run the example you will need to install the `wasm32-wasip2` target for Rust.

```bash
$ rustup target add wasm32-wasip2
```

First, run the `spin new` command to create a Spin application from a template.
```bash
# Create a new Spin application named 'hello-rust' based on the Rust http template, accepting all defaults
$ spin new --accept-defaults -t http-rust hello-rust
```
Running the `spin new` command created a `hello-rust` directory with all the necessary files for your application. Change to the `hello-rust` directory and build the application with `spin build`, then run it locally with `spin up`:

```bash
# Compile to Wasm by executing the `build` command.
$ spin build
Executing the build command for component hello-rust: cargo build --target wasm32-wasip2 --release
    Finished release [optimized] target(s) in 0.03s
Successfully ran the build command for the Spin components.

# Run the application locally.
$ spin up
Logging component stdio to ".spin/logs/"

Serving http://127.0.0.1:3000
Available Routes:
  hello-rust: http://127.0.0.1:3000 (wildcard)
```

That's it! Now that the application is running, use your browser or cURL in another shell to try it out:

```bash
# Send a request to the application.
$ curl -i 127.0.0.1:3000
HTTP/1.1 200 OK
content-type: text/plain
transfer-encoding: chunked
date: Sun, 02 Mar 2025 20:09:11 GMT

Hello World!
```

You can make the app do more by editting the `src/lib.rs` file in the `hello-rust` directory using your favorite editor or IDE. To learn more about writing Spin applications see [Writing Applications](https://spinframework.dev/writing-apps) in the Spin documentation.  To learn how to publish and distribute your application see the [Publishing and Distribution](https://spinframework.dev/distributing-apps) guide in the Spin documentation.

## Language Support for Spin Features

The table below summarizes the [feature support](https://spinframework.dev/language-support-overview) in each of the language SDKs.

| Feature | Rust SDK Supported? | TypeScript SDK Supported? | Python SDK Supported? | Tiny Go SDK Supported? | C# SDK Supported? |
|-----|-----|-----|-----|-----|-----|
| **Triggers** |
| [HTTP](https://spinframework.dev/http-trigger) | Supported | Supported | Supported | Supported | Supported |
| [Redis](https://spinframework.dev/redis-trigger) | Supported | Supported | Supported | Supported | Not Supported |
| **APIs** |
| [Outbound HTTP](https://spinframework.dev/rust-components.md#sending-outbound-http-requests) | Supported | Supported | Supported | Supported | Supported |
| [Configuration Variables](https://spinframework.dev/variables) | Supported | Supported | Supported | Supported | Supported |
| [Key Value Storage](https://spinframework.dev/kv-store-api-guide) | Supported | Supported | Supported | Supported | Not Supported |
| [SQLite Storage](https://spinframework.dev/sqlite-api-guide) | Supported | Supported | Supported | Supported | Not Supported |
| [MySQL](https://spinframework.dev/rdbms-storage#using-mysql-and-postgresql-from-applications) | Supported | Supported | Not Supported | Supported | Not Supported |
| [PostgreSQL](https://spinframework.dev/rdbms-storage#using-mysql-and-postgresql-from-applications) | Supported | Supported | Not Supported | Supported | Supported |
| [Outbound Redis](https://spinframework.dev/rust-components.md#storing-data-in-redis-from-rust-components) | Supported | Supported | Supported | Supported | Supported |
| [Serverless AI](https://spinframework.dev/serverless-ai-api-guide) | Supported | Supported | Supported | Supported | Not Supported |
| **Extensibility** |
| [Authoring Custom Triggers](https://spinframework.dev/extending-and-embedding) | Supported | Not Supported | Not Supported | Not Supported | Not Supported |

## Getting Involved and Contributing

We are delighted that you are interested in making Spin better! Thank you!

Each Monday at 9:00pm UTC, we meet to discuss Spin issues, roadmap, and ideas in our Spin Project Meetings. Demos are welcome. Link to the meeting can be found in the Spin Project Meeting agenda below.
If this meeting time does not work for you, please propose a one-off meeting at a different time or a new recurring time in the [Spin Slack Channel](https://cloud-native.slack.com/archives/C089NJ9G1V0) or in the issue queue. We will do our best to accommodate.

The [Spin Project Meeting agenda](https://docs.google.com/document/d/1EG392gb8Eg-1ZEPDy18pgFZvMMrdAEybpCSufFXoe00/edit?usp=sharing) is a public document. The document contains a rolling agenda with the date and time of each meeting, the Zoom link, and topics of discussion for the day. You will also find the meeting minutes for each meeting and the link to the recording. If you have something you would like to demo or discuss at the project meeting, we encourage you to add it to the agenda.

You can find the contributing guide [here](https://spinframework.dev/contributing-spin).

## Stay in Touch

Follow us on Twitter: [@spinframework](https://twitter.com/spinframework)

You can join the Spin community in the [Spin CNCF Slack channel](https://cloud-native.slack.com/archives/C089NJ9G1V0) where you can ask questions, get help, and show off the cool things you are doing with Spin!

---

## File: crates/test-codegen-macro/README.md

# Test Codegen Macro

A macro for automatically producing `#[test]` annotated functions based on file directory structure. This is used by the runtime tests so that when adding a runtime test, you're not required to also add a test function corresponding to that runtime test.

---

## File: crates/componentize/adapters/README.md

# Adapters

The componentize process uses adapters to adapt plain wasm modules to wasi preview 2 compatible wasm components. There are three adapters that are built and stored as wasm binaries in this repository:

* The upstream wasi preview1 adapters for both commands and reactors for use with newer versions of wit-bindgen (v0.5 and above).
    * These are currently [the wasmtime 18.0.1 release](https://github.com/bytecodealliance/wasmtime/releases/tag/v18.0.1).
* A modified adapter that has knowledge of Spin APIs for use with v0.2 of wit-bindgen which has a different ABI than newer wit-bindgen based modules.
    * This is currently built using commit [603fb3e](https://github.com/rylev/wasmtime/commit/603fb3e14fb0eb7468b832711fee5ff7e7ce7012) on the github.com/rylev/wasmtime fork of wasmtime.
    * You can see a diff between the upstream wasmtime 18.0.1 compatible adapter and this custom adapter [here](https://github.com/bytecodealliance/wasmtime/compare/release-18.0.0...rylev:wasmtime:v18.0.1-spin).

---

## File: crates/componentize/README.md

# spin-componentize

This library converts a Spin module to a
[component](https://github.com/WebAssembly/component-model/).

Note that although the world specifies both `inbound-redis` and `inbound-http`
exports, `spin-componentize` will only export either or both according to what
the original module exported.

## Building

This crate requires a [Rust](https://rustup.rs/) installation v1.68 or later and a couple of Wasm targets:

```shell
rustup target add wasm32-wasip1
rustup target add wasm32-unknown-unknown
```

Note that this is currently only a library and does not yet have a CLI interface, although that 
would be easy to add if desired.

## Testing

To test whether the spin componentize process produces wasm components that can be used with wasmtime, we run "abi conformance" testing. These tests are run with a plain `cargo test` invocation.

## Wit and Adapters

spin-componentize and the abi conformance tests use component adapters built from wasmtime.

See the [adapters README](./adapters/README.md) for more information.

---

## File: cross/README.md

# Polyfill for missing SIMD intrinsics in `cross-rs` image for target `aarch64-unknown-linux-musl`

A transitive dependency of spin (`llama.cpp` via `ggml`) uses the `vld1q_s8_x4` and `vld1q_u8_x4` compiler built-in SIMD intrinsics.
These intrinsics are missing for `aarch64` in `gcc < 10.3`, while `cross-rs` ships with `gcc 9` for `aarch64-unknown-linux-musl` as of writing.

The code in this folder does a feature check and patches the `arm_neon.h` header with polyfills if the functions are missing.

See https://github.com/spinframework/spin/issues/1786 for the upstream issue.

---

## File: deploy/README.md

# Deployments

The [Spin Docs](https://spin.fermyon.dev) website is deployed via the [deploy-website.yaml](../.github/workflows/deploy-website.yml) GitHub workflow.

(Note: currently this website consists of redirects to the Spin Docs hosted at [spinframework.dev](https://spinframework.dev))

## Auto Deploys

The production version of the website is deployed whenever commits are pushed to the `main` branch.

## Manual Deploys

Deployments may also be [triggered manually](https://github.com/spinframework/spin/actions/workflows/deploy-website.yml), providing a choice of `ref` and `sha`.

## Nomad jobs

We currently deploy the website via its Nomad job directly. (In the future, we envision running the website as a Fermyon Cloud app.)

The [spin-docs](./spin-docs.nomad) Nomad job contains configuration for the running website, including the OCI reference to run from.

---

## File: docs/content/sips/001-spin-deploy.md

title = "SIP 001 - Spin Deploy"
template = "main"
date = "2022-03-18T14:53:30Z"
---

Summary: A Spin CLI command that will deploy a Spin application to the cloud

Owner: michelle@fermyon.com

Created: March 18, 2022

Updated: March 31, 2022

## Background

A Spin application — (currently described as a spin.toml file) — is a collection of one or more components, each invoked as a result of an event generated by a trigger. The Spin CLI currently enables running a Spin application locally via the `spin up` command. The Spin CLI also offers a set of commands enabling users to package and push a Spin application to a [Bindle](https://github.com/deislabs/bindle) registry.

[Hippo](https://github.com/deislabs/hippo) is a self-hosted, open source, Web Assembly PaaS that allows users to deploy and scale Web Assembly applications. Hippo takes a reference to a bindle, deploys it to the cloud and makes it publicly available. Hippo currently only works with Wagi applications and can currently deploy Wagi applications on a Nomad cluster with Traefik for routing. Additionally, Hippo has a concept called “channels” enabling users to track different version categories of an application (ex. alpha, beta, stable, pre-releases, minor versions, etc.).

A desired feature is to be able to deploy a Spin application to the cloud using Hippo so that it is accessible via a publicly available domain or IP address.

## Proposal

Create a `spin deploy` command. This command packages a Spin application as a bindle, pushes it to a bindle registry and instructs Hippo to deploy the application to the cloud.

### Configuration

This command needs the following configuration to be passed via either flags or environment variables or config file (config file to be defined at a later date) to deploy the application properly and to the right place:

- Bindle server information
  - Environment variable: BINDLE_SERVER_URL
  - Flag: --bindle-server
- Hippo URL information
  - Environment variable: HIPPO_URL
  - Flag: --hippo-url

#### Authentication with Hippo

Hippo authentication information. A token is needed to communicate with the Hippo server. This can be
retrieved either from requesting it from the Hippo server with a username and password, from the Hippo config file on the system (if a user has already logged in) or from the user if they already know the
token information. The following flags and environment variables support authenticating with Hippo.

- Hippo token
  - Environment variable: HIPPO_TOKEN
  - Flag: --hippo-token
- Hippo username
  - Environment variable: HIPPO_USERNAME
  - Flag: --hippo-username
- Hippo password
  - Environment variable: HIPPO_PASSWORD
  - Flag: --hippo-password

The `--hippo-token` flag cannot be set in combination with the `--hippo-username` and `--hippo-password` flags. If so, Spin will return an error. If the username/password flags are set, Spin will request a token from the Hippo server and use it. If the username flag was provided but the password was not, Spin will prompt the user for a password. If none of the Hippo auth flags are provided, Spin will find the Hippo token in the Hippo config file on disk. If Hippo cannot find the file or the token in the file is expired, Spin will prompt the user for username/password.

### Flow

As part of the deploy flow, Spin will:

1. Create and push a bindle for the Spin app
2. Create a Hippo app with the name given in the Spin.toml file. If app exists, it will use the existing app's ID for the next step. _Note: Should we even be re-using an app? or should we create a unique app per deploy? I'm leaning towards the latter?_
3. Create a Hippo channel called "spin-deploy" (might be something we should allow for configuration via a flag). If the channel already exists, ensure that revision information is configured to pick up the new bindle version.
4. Register a revision with Hippo so that the relevant channel(s) deploy the application.

#### Pre-requsites

In order to use the `spin deploy` command, a user must already have Hippo installed and running using the nomad scheduler and a bindle url.

#### Bindle versioning

A bindle is immutable once pushed and the tag cannot be overwritten. Therefore, we'll need a way to construct unique tags. One way to do this is to hash the bindle invoice that is generated.
_Note: I believe Hippo only allows semver versions though and in that case, this would not work or we'd need to see if we can make Hippo pick up non-semver bindle tags._

### Assumptions about the Hippo Platform

The following is a list of assumptions we are making about the Hippo platform that we would need to build in order for this command to work.

- There needs to be a single endpoint on the Hippo API Server that takes the Spin application information and creates a Hippo application with a default channel configured to watch the correct bindle reference. See [hippo-cli issue #97](https://github.com/deislabs/hippo-cli/issues/97).
- Hippo needs to support running Spin applications and not only Wagi applications. See [hippo issue #579](https://github.com/deislabs/hippo/issues/579).

### Additional Consideration: Plugin Model

In the future, we should make this command a plugin for the Spin CLI. People may not want to use the Spin deploy command to deploy to Hippo. They may want to deploy to a different target using a different platform. They should be able to do that via plugins. However, there is no plugin system in Spin at this time and that may require further debate and discussion and consideration, so it's best to continue with `spin deploy` as a built-in subcommand for the time being to be focused about the scope of work.

---

## File: docs/content/sips/002-app-config.md

title = "SIP 002 - Application Configuration"
template = "main"
date = "2022-03-22T14:53:30Z"
---

Summary: A configuration system for Spin applications.

Owner: lann.martin@fermyon.com

Created: March 22, 2022

Updated: July 19, 2022

## Background

It is common for applications to require configuration at runtime that isn't known at build time or is too sensitive to be stored with build artifacts:

- Logging configuration
- Per-channel (production, staging, etc) service dependency URLs
- Database secrets

## Proposal

### Configuration schema is defined by components and applications

Configuration within a "parent" (component or application) consists of a number of configuration "slots":
- Slots are identified by a string "key"; in order to allow unambiguous conversion to environment variables or file paths, keys are constrained:
  - Keys must start with a letter (required for env vars)
  - Keys consist of only lowercase ascii alphanum and `_` (`[a-z0-9_]`)
    - Only one `_` at a time and not at the end (to allow delimiting in env vars with `__`)
- Slot keys must be unique within their parent, but to allow independent development of components different parents may have identical keys
- A slot must _either_ be marked as "required" _or_ must be given a default value
- A slot may be marked as "secret", in which case any associated value should be handled with care (e.g. not logged)

```toml
[variables]
required_key = { required = true }
optional_key = { default = "default_value" }
secret_key = { required = true, secret = true }
```

Default values can use template strings to reference other slots.
```toml
[variables]
key1 = { required = true }
key2 = { default = "prefix-{{ key1 }}-suffix" }
```

### Components and applications set configuration values of their dependencies

In dependency configuration, templates strings can reference top-level config keys (those in `[variables]`), "sibling" keys within the same dependency, and "ancestor" dependant configs.

- Top-level references use just the key name: `{{ top_level_key }}`
- "Sibling" references use a single `.` prefix: `{{ .sibling_key }}`
- "Ancestor" references use multiple `.`s: `{{ ..parent_dep_key }}`, `{{ ...grandparent_key }}`
- Circular / infinitely recursive references are not permitted

`spin.toml`:
```toml
[variables]
app_root = { default = "/app" }
log_file = { default = "{{ app_root }}/log.txt" }
...
[[component.config]]
work_root = "{{ app_root }}/work"      # -> "/app/work"
work_out = "{{ .work_root }}/output"   # -> "/app/work/output"
[[component.dependencies.dep1.config]]
dep_root = "{{ ..work_root }}/dep"     # -> "/app/work/dep"
```

### Configuration "providers" resolve application configuration

When resolving the value of an application configuration slot, providers will be queried in-order for a value. If no value is returned by any provider, the resolution will either use the default value or fail (if the slot is "required").

Provider configuration is handled by spin at instantiation time (`spin up`).

_Note: Provider configuration is TBD; as TOML it could look like:_

```toml
[[config-provider]]
type = "json_file"
path = "config.json"

[[config-provider]]
type = "env"
prefix = "MY_APP_"
```

#### Example providers

- Environment provider
  - Configured with a prefix, e.g. `SPIN_CONFIG_`
  - `key_one` -> `SPIN_CONFIG_KEY_ONE`
- File provider
  ```json
  {"key_one": "value-one"}
  ```
- Vault provider

### Configuration is exposed via component interface

`spin-config.wit`
```
// Unknown key is a runtime error
get-config: function(key: string) -> expect<string>
```
- Since each component gets its own instance of the `spin-config` import, the executor can resolve keys automatically and only expose a component's own config to it.

### Future design options

_This section contains possible future features which are not fully defined here._

#### Typed configuration

The above assumes only string values, but we could include some typing:
```toml
# Type can be inferred from default value:
number_key = { default = 123 }
# equivalent to:
number_key = { type = "number", default = 123 }

required_string = { type = "string", required = true }
# "bytes" would require e.g. base64 encoding in some places
encryption_key = { type = "bytes", required = true, secret = true}
```

#### WASI "configfs"

For languages without component support, we could expose config as synthetic mounted files:

```ruby
key1_value = File.read("/config/key1")

# Typed config; `.json` encodes values to JSON
key1_value = JSON.parse(File.read("/config/key1.json"))

# "bytes" type; `.raw` decodes from base64
encryption_key = File.read("/config/encryption_key.raw")
```

---

## File: docs/content/sips/003-trigger-executors.md

title = "SIP 003 - Trigger Executors"
template = "main"
date = "2022-04-29T14:53:30Z"
---

Summary: A new architecture for Spin trigger executors.

Owner: lann.martin@fermyon.com

Created: April 29, 2022

Updated: May 5, 2022

## Background

Spin currently includes built-in implementations for two trigger types: HTTP, and Redis (PubSub).
We want to allow for additional trigger types in the future, whether they are "internal" types developed and
supported within the Spin codebase, or "external" types developed by the broader community.

While it is currently possible to build external trigger types - as in the
[TimerTrigger example](https://github.com/fermyon/spin/blob/main/examples/spin-timer/src/main.rs) - it requires replicating much of the
functionality provided by the `spin up` command.

## Proposal

### Trigger types are implemented as "trigger executors"

These executors are regular subcommands/binaries, but are not normally executed directly by
users.

* "Internal" triggers use `spin` subcommands, e.g. `spin trigger http`
* "External" triggers use external binaries, e.g. `spin-trigger-timer`
* Trigger executors share common code, including common CLI options in a `spin-trigger` crate

### The `spin up` command changes

It remains the primary entrypoint for starting a Spin app, but its behavior is changed to:

1. Load the application manifest
1. Find a trigger executor for the application (e.g. check the `PATH` for `"spin-trigger-${trigger.type}"`)
1. Set some environment variables:
   * `SPIN_MANIFEST_URL`: a URL pointing to the application manifest (e.g. `file:///path/to/spin.toml` or `bindle+https://bindle-server?id=bindle-id`)
   * `SPIN_TRIGGER_TYPE` the spin trigger type (e.g. `http`) being executed
1. `exec` the trigger executor, forwarding its own CLI arguments

## Future design options

_This section contains possible future features which are not fully defined here._

### Multi-trigger orchestration

If multiple trigger types were to be supported by a single application, the role of `spin up` could
grow to include trigger orchestration:

* Finding executors for _all_ required trigger types
* Forking a child process for each trigger executor
* Managing the child processes (restarts, graceful shutdowns, etc.)

## Potential disadvantages

If the "Multi-trigger orchestration" option is taken, having separate processes for different triggers
might have some disadvantages:

* Multiple triggers types would use more system resources implemented as multiple processes rather than as
  multiple async tasks in the same process, especially if a single module implements multiple trigger type
  handlers.
* There has been discussion the possibility of trigger handlers making optimized "in-memory" calls to
  other triggers. This design would make cross-trigger-type calls of this sort more complex at best.