diff --git a/content/wasm-languages/CONTRIBUTING.md b/content/wasm-languages/CONTRIBUTING.md new file mode 100644 index 000000000..772758ed9 --- /dev/null +++ b/content/wasm-languages/CONTRIBUTING.md @@ -0,0 +1,59 @@ +date = "2024-02-18T01:01:01Z" +title = "Contributing" +description = "Contributing the WebAssembly Language Guide" +tags = ["wasm", "webassembly"] +template = "page" +[extra] +author = "Fermyon Staff" +type = "page" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/CONTRIBUTING.md" + +--- + +We welcome contributors. To make changes or additions, create new pull requests against this repository. + +The [content template](https://github.com/fermyon/developer/tree/main/content/wasm-languages/tpl.md) provides the scaffolding for adding a new language. The [About Examples](./about-examples.md) explains how an example should work. (Examples are not required. But when provided, we like to keep them consistent.) + +All community members must abide by the [Code of Conduct](https://www.fermyon.com/code-of-conduct) + +### Adding New Languages + +The guide is arranged to break down languages into three categories: + +- Top Languages: This section is reserved for only the languages that trend into the [top RedMonk rankings](https://redmonk.com/sogrady/2021/08/05/language-rankings-6-21/). +- WebAssembly Languages: These are languages specifically built for WebAssembly. While we love research languages, we do require that languages in this category have reached certain stability levels as well as a moderate amount of usage. +- Other Notable Languages: This section is the most permissive. Usually, we focus on historically important languages, languages that didn't quite make the top 20, or languages that seem to be gaining momentum. + +To add a new language, open a PR that includes a new language page (see [tpl.md](https://github.com/fermyon/developer/tree/main/content/wasm-languages/tpl.md) for a template) and also add the language to either the [webassembly-specific-languages](./webassembly-language-support.md#webassembly-specific-languages) or [other-notable-languages](./webassembly-language-support.md#other-notable-languages) section of the [webassembly-language-support.md](./webassembly-language-support.md)` page. Please adhere to the format we have provided. Uniformity is an important quality of entries. + +#### Examples + +We have chosen a very specific example, which is explained in `about-examples.md`. Specifically, we want examples that can execute in `wasmtime` (the reference implementation of the Bytecode Alliance and WASI work), and that can run as [Wagi](https://github.com/deislabs/wagi) modules. Wagi is an important testbed for two reasons: + +1. Wagi only requires core Wasm and WASI support, and does not require any non-standard host runtime features +2. Fermyon's goal is to articulate how WebAssembly can run on the cloud, and Wagi is the easiest way to do so + +While we appreciate that other runtimes offer their own APIs and features, we do not accept examples that are based on those features. + +### Updating Existing Entries + +We are always interested in updates to the content on language pages. We do have a few brief guidelines: + +- *The pros and cons.* The tone of pros/cons is objective, oriented toward the developer, and friendly in tone. We will request changes on (or close) PRs that take a negative tone or attempt to use the pros/cons to air grievances or get really nit-picky. +- *Learn More:* Include new references, tutorials, or discussions that focus on compiling the language to WebAssembly or using WebAssembly-specific features in the language. + - For example, we would welcome the addition of a link to an article entitled "Compiling a C++ app to WebAssembly". + - While the text on the page should focus on core WebAssembly and WASI features, we allow linking to browser, cloud, and specialty projects that support the language on the page. +- *Examples:* Read the previous section and the [About Examples](./about-examples.md) document. + +There are some pieces of information that we are not interested in: + +- Whether a language _has a runtime_ for WebAssembly. We are not interested in "embedding a Wasm runtime in C++", for example. +- Non-language projects (like tools or other runtimes). In the future, we might add a section for these. But for now, the guide is focused exclusively on languages. + +## License + +The contents of this repository are licensed under the [Creative Commons 4.0 Attribution Share-Alike license](https://creativecommons.org/licenses/by-sa/4.0/legalcode), usually abbreviated _cc4.0-by-sa_. + +## Contributing Guide + +To learn more about formatting options, testing your new content, previewing your contributions locally before submitting etc. read the [Contributing guide](https://developer.fermyon.com/spin/v2/contributing-docs). diff --git a/content/wasm-languages/about-examples.md b/content/wasm-languages/about-examples.md new file mode 100644 index 000000000..c5ffc45b7 --- /dev/null +++ b/content/wasm-languages/about-examples.md @@ -0,0 +1,103 @@ +date = "2024-02-18T01:01:01Z" +title = "About WebAssembly Examples" +description = "The WebAssembly examples all follow some common patterns. This page explains them" +template = "page" +tags = ["webassembly", "examples"] +[extra] +author = "Fermyon Staff" # Use "Fermyon Staff" for general content +type = "page" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/about-examples.md" + +--- + +The [Fermyon WebAssembly Language Guide](/wasm-languages/webassembly-language-support) tracks languages that can be executed within a WebAssembly runtime. We do our best to keep things consistent across pages. This page explains how we create our examples. + +## The Typical Example + +Providing detailed language-specific examples is beyond the scope of the language guide. Instead, we try to provide the following pieces of relevant information: + +- How to get the tools necessary to work with the language +- How to create a simple "Hello World" style program +- How to compile that program +- How to execute that program + +Our canonical example is to build a simple web page that prints `Hello, World` in plain text. In order to serve it as a web page, we try to write the script using one of two tools: + +- [Spin](https://spin.fermyon.dev/), a framework for building WebAssembly-based web applications and microservices. +- [Wagi](https://github.com/deislabs/wagi), used in older content from before Spin was released. All Wagi applications run on Spin (though you must use a `spin.toml` instead of a `modules.toml`). + +For command line examples, the example runs with [wasmtime](https://wasmtime.dev/), which is committed to implementing the WASI specification. + +Other runtimes and execution environments are out of the scope of this documentation. However, you may find links to examples in the _Learn More_ section at the bottom of each language page + +To that end, the simplest example, written in Swift, looks like this: + +```swift +print("content-type: text/plain\n\n"); +print("Hello, World\n"); +``` + +When run on `wasmtime`, it should produce output like this: + +```console +$ wasmtime hello.wasm +content-type: text/plain + +Hello, World +``` + +When executed on Spin (or Wagi) and accessed via Curl, it should look like this: + +```console +$ curl localhost:3000 +Hello, World +``` + +## Libraries, SDKs, and Helpers + +Generally, if there is a useful library, SDK, or helper, examples will use the best one. Many times, a language's CGI library can be used with Wagi-style invocations on Spin or Wagi. Additionally, Spin has SDKs for a growing list of languages. + +In the end, though, every Wagi executor (on Spin) [uses the same CGI-like mechanism](https://github.com/deislabs/wagi/blob/main/docs/architecture.md) to read a request and write a response. + +## Spin Configuration + +Newer examples use a `spin.toml` to show how the program is executed with Spin. The generic `spin.toml` looks something like this: + +```toml +spin_manifest_version = 2 + +[application] +name = "spin-hello" +version = "0.1.0" +authors = ["Fermyon Engineering "] +description = "Hello world app." + +[[trigger.http]] +route = "/..." +component = "spin-hello" + +[component.spin-hello] +source = "target/wasm32-wasi/release/spin_hello.wasm" +allowed_outbound_hosts = [] +[component.spin-hello.build] +command = "cargo build --target wasm32-wasi --release" +watch = ["src/**/*.rs", "Cargo.toml"] +``` + +The format and fields are defined in the [official Spin configuration docs](https://developer.fermyon.com/spin/v2/manifest-reference). + +The command to build and start a Spin application is `spin build --up`. This will typically start a server on `http://localhost:3000` unless you specify otherwise. + +## Wagi Configuration + +Older examples us Wagi instead of Spin. They may provide examples that use a `modules.toml` file instead of a `spin.toml` file. A simple example looks like this: + +```toml +[[module]] +module = "hello.wasm" +route = "/" +``` + +Then we start `wagi` with `wagi -c modules.toml`. + +>> If you are interested in contributing to this guide, head on over to [the GitHub repo](https://github.com/fermyon/wasm-languages). diff --git a/content/wasm-languages/assemblyscript.md b/content/wasm-languages/assemblyscript.md new file mode 100644 index 000000000..1790bf7ea --- /dev/null +++ b/content/wasm-languages/assemblyscript.md @@ -0,0 +1,252 @@ +date = "2024-02-18T01:01:01Z" +title = "AssemblyScript in WebAssembly" +description = "AssemblyScript is a WebAssembly-centered language. It is one of the best languages if you want to target only WebAssembly." +tags = ["assemblyscript", "typescript", "javascript", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +last_modified = "2022-03-10T21:50:50Z" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/assemblyscript.md" + +--- + +Inspired by [TypeScript](./typescript.md), AssemblyScript is a strongly typed language. It was written specifically with WebAssembly in mind, and the entire toolchain is oriented around WebAssembly. + +Since it has a [WASI implementation](https://github.com/jedisct1/as-wasi), AssemblyScript can be used on the Fermyon Platform for writing Wagi or Spin apps. + +It is also well-suited for browser-based applications. And it can run inside of Wasmtime and other CLIs. + +## Available Implementations + +AssemblyScript has an [official implementation](https://www.assemblyscript.org/). + +## Usage + +To get started with AssemblyScript, you will need to have a [Node.js environment](https://nodejs.org/en/), including NPM. + +From there, you can get started by creating a new Node project. + +## Pros and Cons + +Things we like about AssemblyScript: + +- Familiar to TypeScript and JavaScript developers +- Because of that, we can use our normal tools for dev +- Good integration with NPM and the Node ecosystem +- Support for common JS idioms (like `Console.log` instead of `println`) + +We're neutral about: + +- File sizes, which are larger than we expected, but not enough to be a problem +- The automatic generation of WAT files, unoptimized binaries, and things we don't normally use + +Things we're not big fans of: + +- It's just different enough from TypeScript to be frustrating at times. +- AssemblyScript WTF-16 instead of the more common UTF-8/UTF-16. This is a hotly debated issue, but our preference is for UTF-8. + +## Example + +This section provides a basic example of building AssemblyScript from source. + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +Set up the project like this: + +```console +$ npm init +# Answer questions +$ npm install --save @assemblyscript/loader + +added 1 package, and audited 2 packages in 986ms + +found 0 vulnerabilities +$ npm install --save-dev assemblyscript + +added 6 packages, and audited 8 packages in 2s + +1 package is looking for funding + run `npm fund` for details + +found 0 vulnerabilities +``` + +Now use `npx` to scaffold out your new project: + +```console +$ npx asinit . +Version: 0.19.23 + +This command will make sure that the following files exist in the project +directory '/Users/technosophos/Code/AssemblyScript/hello': + + ./assembly + Directory holding the AssemblyScript sources being compiled to WebAssembly. + + ./assembly/tsconfig.json + TypeScript configuration inheriting recommended AssemblyScript settings. + + ./assembly/index.ts + Example entry file being compiled to WebAssembly to get you started. + + ./build + Build artifact directory where compiled WebAssembly files are stored. + + ./build/.gitignore + Git configuration that excludes compiled binaries from source control. + + ./asconfig.json + Configuration file defining both a 'debug' and a 'release' target. + + ./package.json + Package info containing the necessary commands to compile to WebAssembly. + + ./index.js + Main file loading the WebAssembly module and exporting its exports. + + ./tests/index.js + Example test to check that your module is indeed working. + +The command will try to update existing files to match the correct settings +for this instance of the compiler in '/Users/technosophos/Code/AssemblyScript/hello/node_modules/assemblyscript'. + +Do you want to proceed? [Y/n] y +# More output that is similar to above +``` + +At this point you should have a directory structure that looks like this: + +```console +$ tree -L 2 +. +├── asconfig.json +├── assembly +│   ├── index.ts +│   └── tsconfig.json +├── build +├── index.js +├── node_modules +│   ├── @assemblyscript +│   ├── assemblyscript +│   ├── binaryen +│   ├── buffer-from +│   ├── long +│   ├── source-map +│   └── source-map-support +├── package-lock.json +├── package.json +└── tests + └── index.js + +11 directories, 7 files +``` + +The `assembly/` directory is where the code lives. + +Add WASI support by installing the `as-wasi` package: + +```console +$ npm install --save as-wasi + +added 1 package, and audited 9 packages in 1s + +1 package is looking for funding + run `npm fund` for details + +found 0 vulnerabilities +``` + +Now we can write a simple AssemblyScript module: + +```typescript +import "wasi"; +import { Console } from "as-wasi"; + +Console.log("content-type: text/plain"); +Console.log(""); +Console.log("Hello, World"); +``` + +While based on JavaScript and TypeScript, AssemblyScript is not a typical scripting language. It must be compiled before it can be executed. The AssemblyScript tools configure NPM to run the compiler for us: + +```console +$ npm run asbuild + +> hello@1.0.0 asbuild +> npm run asbuild:untouched && npm run asbuild:optimized + +> hello@1.0.0 asbuild:untouched +> asc assembly/index.ts --target debug + +> hello@1.0.0 asbuild:optimized +> asc assembly/index.ts --target release +``` + +This creates two builds in the `builds/` directory: + +```console +$ ls -lah build +total 1760 +drwxr-xr-x 9 technosophos staff 288B Mar 8 16:02 . +drwxr-xr-x 11 technosophos staff 352B Mar 8 16:07 .. +-rw-r--r-- 1 technosophos staff 27B Mar 8 14:27 .gitignore +-rw-r--r-- 1 technosophos staff 5.1K Mar 8 16:11 optimized.wasm +-rw-r--r-- 1 technosophos staff 373K Mar 8 16:11 optimized.wasm.map +-rw-r--r-- 1 technosophos staff 41K Mar 8 16:11 optimized.wat +-rw-r--r-- 1 technosophos staff 9.7K Mar 8 16:11 untouched.wasm +-rw-r--r-- 1 technosophos staff 375K Mar 8 16:11 untouched.wasm.map +-rw-r--r-- 1 technosophos staff 60K Mar 8 16:11 untouched.wat +``` + +Map files are for the browser. WAT files are large text file versions of the WebAssembly. The `.wasm` files are the ones we care about. In general, the `optimized.wasm` file is the one we use. + + +### Running in `wasmtime` + +This is how the module is run in [wasmtime](https://wasmtime.dev/): + +```console +$ wasmtime build/optimized.wasm +content-type: text/plain + +Hello, World +``` + +The module emits `content-type` information and an empty line, so it can be executed in any Wagi runtime such as Wagi, Spin, or Wagi.NET. + +Here's an example with [Wagi](https://github.com/deislabs/wagi). + +Create a simple `modules.toml`: + +```toml +[[module]] +module = "build/optimized.wasm" +route = "/" +``` + +Then run Wagi to serve our new module at `http://localhost:3000/`: + +```console +$ wagi -c modules.toml +No log_dir specified, using temporary directory /var/folders/rk/mkbs8vx12zs0gkm680h_gth00000gn/T/.tmpTxamNm for logs +Ready: serving on http://127.0.0.1:3000 +``` + +At this point you can use a web browser or curl to check the results: + +```console +$ curl localhost:3000 +Hello, World +``` + +For more on running AssemblyScript in the browser, read the [AssemblyScript documentation](https://www.assemblyscript.org/) + +## Learn More + +Here are some great resources: + +- Wasm-by-Example has a good [code walkthrough](https://wasmbyexample.dev/examples/wasi-hello-world/wasi-hello-world.assemblyscript.en-us.html) +- This [blog post](https://blog.ttulka.com/learning-webassembly-9-assemblyscript-basics) covers the basics. +- Here's an example of [A Wagi app written in AssemblyScript](https://github.com/deislabs/hello-wagi-as) +- Fastly's blog [also has an intro to AssemblyScript](https://www.fastly.com/blog/meet-assemblyscript-your-next-computing-language) +- [yo-wasm](https://github.com/deislabs/yo-wasm) can help you generate an AssemblyScript project \ No newline at end of file diff --git a/content/wasm-languages/c-lang.md b/content/wasm-languages/c-lang.md new file mode 100644 index 000000000..4d066a168 --- /dev/null +++ b/content/wasm-languages/c-lang.md @@ -0,0 +1,170 @@ +date = "2024-02-18T01:01:01Z" +title = "The C language in WebAssembly" +description = "C support for WebAssembly is great. As one of the earliest supported languages, it enjoys broad support." +tags = ["c", "c language", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +last_modified = "2022-03-10T21:50:50Z" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/c-lang.md" + +--- + +C is a low-level programming language that is typically compiled into a native executable. It is one of the most well-known and frequently used languages. + +C is one of the best-supported WebAssembly languages. The original developers of WebAssembly had C in mind as a target language, and have put significant work into C support. + +Because C++ (aka CPP) is a C language, it is frequently the case that C++ programs can also be compiled to WebAssembly. In addition to this document, there is also a WebAssembly Language Support page [specifically for C++](/wasm-languages/cpp). + +## Available Implementations + +There are a few ways to compile C (and C++) to WebAssembly. + +### WASI SDK and Clang/LLVM + +Using the [WASI SDK](https://github.com/WebAssembly/wasi-sdk), you can compile C code into WebAssembly with WASI support. Later in this guide, we show an example built this way. + +The repo above provides most of the tools you will need to build code this way. + +### Emscripten + +When developing Browser-oriented WebAssembly code, many developers use [Emscripten](https://emscripten.org/index.html). + +> Emscripten is a complete compiler toolchain to WebAssembly, using LLVM, with a special focus on speed, size, and the Web platform. + +Mozilla's [Compiling C/C++ Guide](https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm) is a great starting point. + +Since our guide is less interested in browser-specific applications of WebAssembly, we do not cover Emscripten in our examples below. + +## Usage + +C support for WebAssembly is in exceptional condition. It may be used to port old libraries to WebAssembly or to write new (especially performance-focused) code that can be run as WebAssembly. + +While C is a low-level language, not all of the `stdlib` is supported by WebAssembly's sandboxed runtime. Sockets, for example, are not currently supported. For that reason, not all C programs can be compiled to WebAssembly (and some that may appear to compile may not run as expected). + +It is good to be familiar with both [WASI](https://wasi.dev) and the WebAssembly runtime's host extensions when writing or porting C or C++ code. + +## Pros and Cons + +Things we like about C/C++ as a WebAssembly language: + +- For the most part, it works the same in WebAssembly as it does anywhere else +- Regular C/C++ tooling works well +- Binary sizes tend to be compact +- Over and above regular C/C++ code, compiling it to WebAssembly improves security +- Many C/C++ libraries can be compiled to WebAssembly + +We're neutral about: + +- The toolchain, which is neither better nor worse than the regular C/C++ tooling + +Things we're not big fans of: + +- It can be frustrating to figure out which existing libraries can be ported +- C++ exceptions are not yet supported, nor are threads + +## Examples + +Since it supports the WASI specification, C can be used on the Fermyon Platform with Wagi and Spin. Our example uses the [WASI SDK](https://github.com/WebAssembly/wasi-sdk). + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +The first step is to install the WASI SDK. If you use this broadly, it may be a good idea to install it in a common location. For our example, though, we will create a project and install the SDK inside of that project. + +You can download the latest version from the [WASI releases page](https://github.com/WebAssembly/wasi-sdk/releases). +At the time of this writing, the latest version is `14.0`. Here's a command line example for a Mac: + +```console +$ curl -O -sSL https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-14/wasi-sdk-14.0-macos.tar.gz +$ tar xf wasi-sdk-14.0-macos.tar.gz +``` + +Now we can write a simple C program using WASI. Here is the text ouf `hello.c`: + +```c +#include +#include + +int main() { + printf("Content-Type: text/plain\n\n"); + printf("Hello, World\n"); +} +``` + +To compile this, we will use the `clang` that comes with the WASI SDK. + +```console +./wasi-sdk-14.0/bin/clang --sysroot wasi-sdk-14.0/share/wasi-sysroot/ hello.c -o hello.wasm +``` + +>> Newer versions of Clang may only need the command `clang --target=wasm32-wasi --sysroot=wasi-sdk-14.0/share/wasi-sysroot/ hello.c -o hello.wasm` + +The above should produce a file named `hello.wasm`. We can execute that with Wasmtime: + +``` +$ wasmtime hello.wasm +Content-Type: text/plain + +Hello, World +``` + +To run this using Wagi, we need to create a simple `modules.toml`: + +```toml +[[module]] +module = "hello.wasm" +route = "/" +``` + +Then we can run Wagi: + +```console +$ wagi -c modules.toml +``` + +And using Curl or a web browser, we can hit `http://localhost:3000` and see the output: + +```console +$ curl localhost:3000 +Hello, World +``` + +### Compiling C Using the Zig Compiler Toolchain + +Users have reported that it is easier to compile C programs with Zig. With Zig, you will not need to separately install the WASI SDK, as it is included with the toolchain. + +Once again, here is our program: + +```c +#include +#include + +int main() { + printf("Content-Type: text/plain\n\n"); + printf("Hello, World\n"); +} +``` + +To compile with Zig, use a `zig build-exe` with the `-lc` ("library C") flag: + +```console +$ zig build-exe -O ReleaseSmall -target wasm32-wasi hello.c -lc +``` + +Now the `hello.wasm` can be run in `wasmtime` or `spin`: + +```console +$ wasmtime hello.wasm +Content-Type: text/plain + +Hello, World +``` + +## Learn More + +Here are some great resources: + +- Mozilla has a tutorial on [Compiling C/C++ to Wasm with Emscripten](https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm) +- The [yo-wasm](https://github.com/deislabs/yo-wasm) tool can help you get started faster. (Yes, we built `yo-wasm`.) +- Here's an example of a [Wagi fileserver written in C](https://github.com/deislabs/wagi-fileserver-c) +- If you want to work directly with the [Wasi libc](https://github.com/WebAssembly/wasi-libc), you can do that, too. \ No newline at end of file diff --git a/content/wasm-languages/c-sharp.md b/content/wasm-languages/c-sharp.md new file mode 100644 index 000000000..1f8fe665f --- /dev/null +++ b/content/wasm-languages/c-sharp.md @@ -0,0 +1,116 @@ +date = "2024-02-18T01:01:01Z" +title = "C# (and .NET) in WebAssembly" +description = "C# (C-sharp) is backed by the .NET (dotnet) ecosystem, whose Wasm support is rapidly maturing." +tags = ["c#", "csharp", "dotnet", ".net", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +last_modified = "2022-03-10T21:50:50Z" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/c-sharp.md" + +--- + +The .NET (aka dotnet) ecosystem supports a variety of languages, including C# (C sharp) and ASP.NET. Programs that target .NET are compiled to an intermediary bytecode format that runs in the .NET Common Language Runtime (CLR). This makes .NET an example of a [virtual machine language](https://www.fermyon.com/blog/scripts-vs-compiled-wasm). + +## Available Implementations + +The .NET ecosystem has long had support for browser-side WebAssembly via the [Blazor toolkit](https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor). + +The team at Microsoft is rapidly building out a number of WebAssembly tools. In 2022, it seems reasonable to expect that Microsoft will have new tooling for WebAssembly. C# compiled using the .NET toolchain will have access to these WebAssembly features. + +At the time of this writing, the closest we have seen to a full WASI runtime is Steve Sanderson's example [.NET WASI Runtime](https://github.com/SteveSandersonMS/dotnet-wasi-runtime). + +In addition, browser-based support also seems to be available in the [Elements compiler](https://www.elementscompiler.com/elements/) + +## Pros and Cons + +Things we like: + +- Blazor is enjoying a surge of popularity in the browser +- The .NET WASI Runtime looks excellent + +For the most part, though, it is too early to speculate on the rest of the .NET tooling. + +## Example + +Our example uses the [.NET WASI Runtime](https://github.com/SteveSandersonMS/dotnet-wasi-runtime). This is a preview and requires the supporting tools and build steps described in that repository. + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +The example requires a project file `ConsoleApp.csproj` that imports the .NET WASI SDK: + +```xml + + + + + + + Exe + net7.0 + enable + enable + + + + + + + + + +``` + +Now we can write a simple C# program using WASI. Here is the text of `Program.cs`: + +```csharp +Console.WriteLine("Content-Type: text/plain"); +Console.WriteLine(); +Console.WriteLine("Hello, World"); +``` + +To compile this, run the .NET 7 command line: + +```console +dotnet build +``` + +This produces a `ConsoleApp.wasm` file in the `bin/Debug/net7.0` directory. We can execute that with Wasmtime: + +``` +$ wasmtime ./bin/Debug/net7.0/ConsoleApp.wasm +Content-Type: text/plain + +Hello, World +``` + +To run this using Wagi, we need to create a simple `modules.toml`: + +```toml +[[module]] +route = "/" +module = "bin/Debug/net7.0/ConsoleApp.wasm" +``` + +Then we can run Wagi: + +```console +$ wagi -c modules.toml +``` + +And using Curl or a web browser, we can hit `http://localhost:3000` and see the output: + +```console +$ curl localhost:3000 +Hello, World +``` + +## Learn More + +Here are some great resources: + +- [Blazor](https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor) +- The .NET community call [previewed](https://www.youtube.com/watch?v=8gwSU3oaMV8&list=PLdo4fOcmZ0oX-DBuRG4u58ZTAJgBAeQ-t&t=3670s) `wasm32-wasi` with ASP.NET \ No newline at end of file diff --git a/content/wasm-languages/clojure.md b/content/wasm-languages/clojure.md new file mode 100644 index 000000000..1c5140b8b --- /dev/null +++ b/content/wasm-languages/clojure.md @@ -0,0 +1,37 @@ +date = "2024-02-18T01:01:01Z" +title = "Clojure in WebAssembly" +description = "Clojure can be compiled to WebAssembly via TeaVM." +tags = ["language", "webassembly"] +template = "page_lang" + +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/clojure.md" + +--- + +Clojure is a functional programming language that is part of the Java/JVM ecosystem. + +## Available Implementations + + + +The TeaVM can execute Java Bytecode inside of a WebAssembly runtime. Clojure is compiled to Java Bytecode. + +We track Java Bytecode execution in the [Java section of the WebAssembly Language Guide](java). + +It is also likely that you can take [Clojurescript](https://clojure.org/about/clojurescript), transform it to JavaScript (which is normal) and then [use a Javascript Wasm tool](https://clojure.org/about/clojurescript). In this case, it should be possible to use the full [Spin Javascript SDK](https://www.fermyon.com/blog/spin-js-sdk) within Clojurescript. + +## Learn More + +Here are some great resources: + +- There's a thread on [Reddit](https://www.reddit.com/r/Clojure/comments/jkznto/web_assembly_clojure_current_state/) about compiling Clojure to Wasm directly +- The [Spin Javascript SDK](https://www.fermyon.com/blog/spin-js-sdk) just so happens to be maintained by the same team working on [TeaVM support for Wasm and WASI](https://github.com/fermyon/teavm-wasi) + diff --git a/content/wasm-languages/cobol.md b/content/wasm-languages/cobol.md new file mode 100644 index 000000000..3e193f41f --- /dev/null +++ b/content/wasm-languages/cobol.md @@ -0,0 +1,44 @@ +date = "2024-02-18T01:01:01Z" +title = "COBOL in WebAssembly" +description = "COBOL can be compiled to WebAssembly." +tags = ["language", "webassembly", "cobol"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +last_modified = "2022-03-10T21:50:50Z" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/cobol.md" + +--- + +That venerable business language of the pre-2000 era is back. COBOL can be compiled to WebAssembly. We are not entirely sure, given the [blog's date](https://blog.cloudflare.com/cloudflare-workers-now-support-cobol/) whether this was originally an April Fool's Day joke. But... it does appear to work. This project has since been renamed to Cobweb. + +CloudFlare Workers execute on CloudFlare's edge service. This particular COBOL implementation appears to be intended for that use case. + +The Register summarized the project as follows: + +> Using the GNUCobol project, you can compile COBOL code to C and then use Emscripten to compile the C code to WebAssembly. Cloudflare offers a tool called cobaul [now Cobweb] to simplify this process + +## Available Implementations + +The only implementation of COBOL in Wasm that we know of is CloudFlare's. However, they appear to have achieved most of the work by [patching a few things in GnuCOBOL](https://github.com/cloudflare/cobweb/tree/master/deps). + +This version does not seem to have support for anything other than CloudFlare workers. For example, there is not Browser or WASI support. + +## Example + +While we could not generate an example for Wasmtime or Wagi, CloudFlare does have [an example for CloudFlare Workers](https://github.com/cloudflare/cobweb/tree/master/example). + +## Pros and Cons + +Things we like: +- Frankly, we think this project is hipster retro cool. + +Things we're not big fans of: +- Cobweb does not seem to support anything other than CloudFlare Workers. + +## Learn More + +Here are some great resources: + +- The [Cobweb project](https://github.com/cloudflare/cobweb) from CloudFlare +- El Reg wrote a [totally serious and not at all snarky review](https://www.theregister.com/2020/04/16/cloudflare_cobol/) \ No newline at end of file diff --git a/content/wasm-languages/cpp.md b/content/wasm-languages/cpp.md new file mode 100644 index 000000000..5cb7c942b --- /dev/null +++ b/content/wasm-languages/cpp.md @@ -0,0 +1,57 @@ +date = "2024-02-18T01:01:01Z" +title = "C++ in WebAssembly" +description = "C++ support is provided via C support." +tags = ["c++", "cpp", "webassembly", "qt"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +last_modified = "2022-03-10T21:50:50Z" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/cpp.md" + +--- + +C++ support for WebAssembly is handled by the [C language support](/wasm-languages/c-lang). And C language support is currently excellent. + +However, specific C++ tools are maturing quickly. For example, Cheerp targets compiling C++ to WebAssembly with generated JavaScript interop. + +>> Read the [C language guide](/wasm-languages/c-lang) for examples and more coverage of the WASI SDK, Clang, LLVM, and Emscripten + +## Usage + +For the most part, C++ support comes via C support. Both Emscripten and the C WASI SDK provide support for C++. Recent versions of LLVM and Clang support WebAssembly out of the box. + +For this reason, it should be possible to compile C++ code both for browser targets and WASI targets. One thing to be aware of with C++, though, is that exception handling is not yet supported. + +## Pros and Cons + +Things we like: + +- Because C is so well supported, C++ is among the better supported WebAssembly languages +- It is great that common compilers have added support +- We believe C++-centered tooling for WebAssembly is on the rise + +We're neutral about: + +- Setup is not easy, but it is doable + +Things we're not big fans of: + +- Features like exception handling are sorely missed + +## Examples + +See the [example on the C page](/wasm-languages/c-lang#examples). + +## Learn More + +Here are some great resources: + +- The [WebAssembly and C++](https://neugierig.org/software/blog/2022/06/wasm-c++.html) blog post by Evan Martin is a great analysis of the state of C++ dev for WebAssembly. +- Cheerp is an [LLVM-based toolchain for compiling C++ to Wasm and JavaScript](https://github.com/leaningtech/cheerp-compiler). An overview [blog post](https://medium.com/leaningtech/cheerp-2-7-compile-cpp-to-webassembly-plus-javascript-c9b3ef7e318b) explains the basics. +- Mozilla has a tutorial on [Compiling C++ to Wasm with Emscripten](https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm) +- We love this [really cool slide presentation](https://nxxm.github.io/cppcon2018/CPP_EVERYWHERE_WITH_WASM.html#/) with a code walk of C++ in the browser +- Example of building [C++ WebAssembly files with Clang](https://github.com/PetterS/clang-wasm) +- The [yo-wasm](https://github.com/deislabs/yo-wasm) tool can help you get started faster. (Yes, we built `yo-wasm`.) +- The [QT GUI toolkit](https://www.qt.io/) supports [compiling to WebAssembly](https://wiki.qt.io/Qt_for_WebAssembly) for the browser. (We blogged about [LibreOffice in the browser](https://www.fermyon.com/blog/qt-libreoffice-wasm). That uses QT.) +- An article showing how to use [Emscripten to compile C++ to Wasm](https://medium.com/@tdeniffel/pragmatic-compiling-from-c-to-webassembly-a-guide-a496cc5954b8) +- TutorialsPoint has a tutorial for [compiling C++ to WebAssembly using Emscripten](https://www.tutorialspoint.com/webassembly/webassembly_working_with_cplusplus.htm), but it focuses only on the browser case. \ No newline at end of file diff --git a/content/wasm-languages/dart.md b/content/wasm-languages/dart.md new file mode 100644 index 000000000..353544986 --- /dev/null +++ b/content/wasm-languages/dart.md @@ -0,0 +1,44 @@ +date = "2024-02-18T01:01:01Z" +title = "Dart in WebAssembly" +description = "Dart is experimenting with WebAssembly for the browser." +tags = ["dart", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +last_modified = "2023-10-26T00:50:50Z" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/dart.md" + +--- + +Dart is a programming language designed for client development. The Dart team is +actively developing support for Wasm along with the Chrome team's work on +[Wasm-GC](https://chromestatus.com/feature/6062715726462976). The source code +for this work-in-process can be found +[in the Dart SDK repository](https://github.com/dart-lang/sdk/tree/main/pkg/dart2wasm). + +Dart also supports loading and running Wasm modules via +[package:wasm](https://github.com/dart-lang/wasm). + +## Pros and Cons + +We will update this once `dart2wasm` has been released. + +## Examples + +We will update this once `dart2wasm` has been released. + +## Learn More + +Here are some great resources: + +- The [Dart2Wasm](https://github.com/dart-lang/sdk/tree/main/pkg/dart2wasm) tool + is in the official SDK +- This + [blog post](https://medium.com/dartlang/experimenting-with-dart-and-wasm-ef7f1c065577) + outlines the efforts to explore Dart and Wasm. +- There is a [tracking issue](https://github.com/dart-lang/sdk/issues/32894) for + Dart-to-Wasm work. +- [Source code](https://github.com/dart-lang/wasm) for `package:wasm`. +- Flutter now has [WebAssembly support for the browser](https://docs.flutter.dev/platform-integration/web/wasm) +- There was a great [presentation about Dart at Wasm I/O](https://youtu.be/Nkjc9r0WDNo?si=mWY8hJ7tw6mx3-Ne) +- In May, 2023, The New Stack ran an [article about WebAssembly in Dart 3 and Flutter 3.10](https://thenewstack.io/dev-news-dart-3-meets-wasm-flutter-3-10-and-qwik-streamable-javascript/) diff --git a/content/wasm-languages/erlang-beam.md b/content/wasm-languages/erlang-beam.md new file mode 100644 index 000000000..52d2e19ad --- /dev/null +++ b/content/wasm-languages/erlang-beam.md @@ -0,0 +1,45 @@ +date = "2024-02-18T01:01:01Z" +title = "Erlang (BEAM languages) in WebAssembly" +description = "BEAM-based languages are getting support for a WebAssembly runtime and compiler." +tags = ["language", "webassembly", "beam", "erlang", "elixir"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/erlang-beam.md" + +--- + +Erlang is the most prominent of the [BEAM languages](https://github.com/llaisdy/beam_languages). Elixir is another popular BEAM language. + +The Lumen project is endeavoring to create a BEAM runtime and a compiler so that the BEAM applications can be run in a WebAssembly host environment. + +## Available Implementations + +Lumen is a [compiler and runtime](https://github.com/lumen/lumen). + +## Usage + +It is not immediately clear what the intended usage pattern for Lumen and WebAssembly is. + +## Pros and Cons + +Things we like: + +- The idea of having both runtime and code compile is cool + +Things we're not big fans of: + +- We could not immediately figure out exactly how Lumen works, and builds appear to be failing +- The project might be stalled or unmaintained. It has not been updated in over a year. + +## Example + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +No example is available at this time. + +## Learn More + +Here are some great resources: + +- Erlang fans may also appreciate [Lunatic](https://lunatic.solutions/), a WebAssembly platform built using an Erlang-style OTP. It will soon support WASI. diff --git a/content/wasm-languages/go-lang.md b/content/wasm-languages/go-lang.md new file mode 100644 index 000000000..0276ba9e8 --- /dev/null +++ b/content/wasm-languages/go-lang.md @@ -0,0 +1,123 @@ +date = "2024-02-18T01:01:01Z" +title = "Go in WebAssembly" +description = "Go can be compiled to WebAssembly. TinyGo, an alternative implementation of Go, is the most promising" +tags = ["go", "golang", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/go-lang.md" + +--- + +Go was early to the WebAssembly game, with the Go compiler producing `wasm32` output alongside its regularly supported build targets. +But the core Go tools have fallen behind. +Instead, the alterative Go implementation called [TinyGo](https://tinygo.org/) seems to have taken the lead. + +## Available Implementations + +- Go supports browser-based WebAssembly +- TinyGo supports `wasm32-wasi` as a build target +- The [Elements compiler](https://www.elementscompiler.com/elements/) may also support compiling browser-oriented Wasm + +We have had the best luck with TinyGo. + +## Usage + +With TinyGo, it is possible to compile _most_ Go code into Wasm with WASI support. +That means you can write Go code targeting the Fermyon Platform. + +## Pros and Cons + +Things we like: + +- TinyGo works very well +- Spin has full support for Go + +We're neutral about: + +- The resulting binary sizes start at around 300k, but can rapidly climb + +Things we're not big fans of: + +- Upstream (mainline) Go does not have WASI support +- TinyGo is still missing (mostly reflection-based) features of Go + +## Example + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +TinyGo can compile to `wasm32-wasi`, and TinyGo apps can be [run on the Fermyon Platform](https://spin.fermyon.dev/go-components/). You will need to [install TinyGo](https://tinygo.org/getting-started/) to do this example. Note that you also have to have [Go installed](https://go.dev/learn/) + +As with any Go project, the first step is to create a `go.mod` file: + +``` +module github.com/fermyon/example-go + +go 1.17 +``` + +Since Spin has a Go SDK which is nice and easy to use, we'll fetch that and use it: + +```console +$ go mod download github.com/fermyon/spin/sdk/go +``` + +Next, create a simple Go program named `main.go`: + +```go +package main + +import ( + "fmt" + "net/http" + + spin "github.com/fermyon/spin/sdk/go/http" +) + +func main() { + spin.HandleRequest(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Hello, World!") + }) +} +``` + +When it comes to compiling, though, we will need to use TinyGo instead of Go. This particular set of flags has produced the best results for us: + +``` +tinygo build -wasm-abi=generic -target=wasi -gc=leaking -o main.wasm main.go +``` + +The above will output a `main.wasm` file. A simple `spin.toml` for running the above in Spin looks like this: + +```toml +spin_version = "1" +authors = ["Fermyon Engineering "] +description = "Hello world app." +name = "spin-go-hello" +trigger = { type = "http", base = "/" } +version = "1.0.0" + +[[component]] +id = "hello" +source = "main.wasm" +[component.trigger] +route = "/" +# Spin components written in Go use the Wagi HTTP executor +executor = { type = "wagi" } +``` + +From there, it's just a matter of using `spin up` to start the server. As usual, we can test using a web browser or Curl: + +```console +$ curl localhost:3000/ +Hello, World! +``` + +## Learn More + +Here are some great resources: + +- TinyGo has [a step-by-step walkthrough](https://tinygo.org/docs/guides/webassembly/) for building and running Go WebAssembly modules +- There are [instructions](https://spin.fermyon.dev/go-components/) and [examples](https://github.com/fermyon/spin-kitchensink) +- Get started quickly with [Yo-Wasm](https://github.com/deislabs/yo-wasm), which has support for Go as well as several other languages. +- A [short article](https://golangbot.com/webassembly-using-go/) on compiling to Go's "JS/Wasm" target \ No newline at end of file diff --git a/content/wasm-languages/grain.md b/content/wasm-languages/grain.md new file mode 100644 index 000000000..eb7e3d210 --- /dev/null +++ b/content/wasm-languages/grain.md @@ -0,0 +1,91 @@ +date = "2024-02-18T01:01:01Z" +title = "Grain in WebAssembly" +description = "Grain is a WebAssembly-first language. It supports both in-browser and WASI modes." +tags = ["grain", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/grain.md" + +--- + +Grain is a functional programming language that is designed specifically to compile to WebAssembly. +We have enjoyed using it because of its intuitive syntax and great tooling. + +## Available Implementations + +There is one official [implementation of Grain](https://grain-lang.org/) + +## Usage + +Grain can be used in the browser. It also supports WASI, so it can be used for the Fermyon Platform (Wagi and Spin) or with commandline runners like Wasmtime. + +## Pros and Cons + +Things we like: + +- Easy to learn +- Good toolchain +- Good documentation + +We're neutral about: + +- Compiled object size. +- Execution speed. + +Things we're not big fans of: + +- Not a lot of third party libraries yet + +## Example + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +To use Grain, you will need to [install the Grain toolkit](https://grain-lang.org/docs/getting_grain). + +Start with a `hello.gr` file: + +```grain +print("content-type: text/plain\n") +print("\n) +print("Hello, World!") +``` + +Compile the program with the `grain` compiler: + +```console +$ grain hello.gr +``` + +The above will produce a `hello.gr.wasm` file. As usual, you can run `wasmtime hello.gr.wasm` to see the output. The first time you compile a grain application, it will take a long time. After that, compiling is much faster. + +To run the WebAssembly app with Spin, create a `spin.toml` file: + +``` +spin_version = "1" +authors = ["Fermyon Engineering "] +description = "Grain example." +name = "spin-grain" +trigger = { type = "http", base = "/" } +version = "1.0.0" + +[[component]] +id = "grain-hello" +source = "hello.gr.wasm" +[component.trigger] +route = "/" +# Spin components written in Grain use the Wagi HTTP executor +executor = { type = "wagi" } +``` + +From there, you can use `spin up` to start a server, and see the results on `http://localhost:3000`. + +## Learn More + +Here are some great resources: + +- The official [Hello World example](https://grain-lang.org/docs/guide/hello_world) +- An InfoWorld article [on the basics of Grain](https://www.infoq.com/news/2021/05/grain-web-assembly-first/) +- An example [Wagi application in Grain](https://github.com/deislabs/hello-wagi-grain) +- A production-grade [Wagi file server in Grain](https://github.com/deislabs/wagi-fileserver) +- A French-language walk-thru video [of Grain, Wagi, and Wasmer](https://youtu.be/TDNxLGMDuVs) \ No newline at end of file diff --git a/content/wasm-languages/haskell.md b/content/wasm-languages/haskell.md new file mode 100644 index 000000000..59defbb44 --- /dev/null +++ b/content/wasm-languages/haskell.md @@ -0,0 +1,57 @@ +date = "2024-02-18T01:01:01Z" +title = "Haskell in WebAssembly" +description = "Haskell can be compiled to WebAssembly with Asterius." +tags = ["haskell", "webassembly", "asterius"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/haskell.md" + +--- + +[Haskell](https://www.haskell.org/) is a purely functional programming language. + +## Available Implementations + +The Asterius project compiles Haskell to WebAssembly. + +## Usage + +Asterius targets Node.js and the browser. +It also appears to support `wasm32-wasi`, though we have not tested it. + +## Pros and Cons + + +None yet. + +## Example + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +No example yet. + +## Learn More + +Here are some great resources: + +- The Asterius [main project page](https://github.com/tweag/asterius) discusses how Asterius works +- A blog post on using Asterius in [CloudFlare](https://www.tweag.io/blog/2020-10-09-asterius-cloudflare-worker/) +- The [roadmap](https://asterius.netlify.app/roadmap.html) provides a list of fixes, but it looks to not be updated recently \ No newline at end of file diff --git a/content/wasm-languages/index.md b/content/wasm-languages/index.md new file mode 100644 index 000000000..e54d59996 --- /dev/null +++ b/content/wasm-languages/index.md @@ -0,0 +1,26 @@ +date = "2024-02-18T01:01:01Z" +title = "WebAssembly Languages" +description = "A wide variety of languages can be compiled to WebAssembly. Our programming language guide focuses on the top 20 programming languages. It also covers interesting programming languages as well as programming languages written specifically for WebAssembly." +tags = ["webassembly", "programming languages"] +template = "page" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/index.md" + +--- + +A wide variety of languages can be compiled to WebAssembly. Our programming language guide focuses on the top 20 programming languages. It also covers interesting programming languages as well as programming languages written specifically for WebAssembly. + +The [Language Matrix](/wasm-languages/webassembly-language-support) provides an easy reference for which languages support what features of WebAssembly. It also links to detailed pages for each programming language that Fermyon tracks. + +Fermyon WebAssembly Languages does not track WebAssembly execution environments or runtimes. For example, we track ways to compile [PHP](/wasm-languages/php) to WebAssembly, but we do not track how to execute WebAssembly in a PHP program. + +## Help Us Stay Current + +We do our best to keep the information here up to date. But with so many languages, each evolving rapidly, we're bound to miss a thing or two. If you have a correction or update, ping us on Twitter [@fermyontech](https://twitter.com/fermyontech). + +>> If you are interested in contributing to this guide, head on over to [the GitHub repo](https://github.com/fermyon/developer/wasm-languages). + +## Adding Your Language to the Matrix + +If you are affiliated with a language project that adds WebAssembly support to a language, please consider [contributing](./CONTRIBUTING.md). We are particularly interested in WebAssembly-specific languages and WASI support for top-20 languages. When assessing new projects, we prefer stable and complete codebases over experimental ones. However, given how young the WebAssembly world is, this is not a requirement. \ No newline at end of file diff --git a/content/wasm-languages/java.md b/content/wasm-languages/java.md new file mode 100644 index 000000000..423734ebd --- /dev/null +++ b/content/wasm-languages/java.md @@ -0,0 +1,45 @@ +date = "2024-02-18T01:01:01Z" +title = "Java in WebAssembly" +description = "Java can be compiled to WebAssembly by a number of projects. Most are currently focused on the browser." +tags = ["java", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/java.md" + +--- + +Many exciting WebAssembly things are happening in the Java ecosystem. +There are a few projects that are rapidly maturing, and that can generate browser-oriented JS. + +The various projects handle memory management differently. +Their feature sets also differ. + +## Uses + +All of the existing Java implementations are browser oriented, and are designed to let developers write Java and link to it from JavaScript. + +## Available Implementations + +There is a working [Wasm plus WASI version of TeaVM](https://github.com/fermyon/teavm-wasi) that allows you to run Java apps in Spin and other WASI-compliant runtimes (like WasmTime). + +Here's a detailed video by Joel Dice: + + +- The [Bytecoder project](https://mirkosertic.github.io/Bytecoder/) cross-compiles Java to WebAssembly that can be executed in the browser +- The [TeaVM project](https://teavm.org/) has experimental support for browser-based WebAssembly +- A dedicate WebAssembly compiler called [JWebAssembly](https://github.com/i-net-software/JWebAssembly) can translate any JVM bytecode to WebAssembly, including Groovy, Clojure, and Kotlin. It, too, is browser-centric. +- [CheerpJ](https://leaningtech.com/cheerpj/) is much more ambitious, handling the UI as well + +## Learn More + +Here are some great resources: + +- [WebAssembly for the Java Geek](https://www.javaadvent.com/2022/12/webassembly-for-the-java-geek.html) details how Wasm's bytecodes and virtual machine differ from Java's, and why this makes a difference. +- An [in-depth blog](http://blog.dmitryalexandrov.net/webassembly-for-java-developers/) showing practical ways to run Java as Wasm +- Does Wasm remind you of Java Applets? Then read [this blog post](https://steveklabnik.com/writing/is-webassembly-the-return-of-java-applets-flash) +- [GraalVM](https://www.graalvm.org/reference-manual/wasm/) has gained a lot of momentum as a WebAssembly runtime, though it does not appear to support compiling from languages to WebAssembly. +- The New Stack wrote about [Java and WebAssembly](https://thenewstack.io/webassembly/javas-history-could-point-the-way-for-webassembly/) from a more historical perspective +- Fermyon posted about [the differences between different languages](https://www.fermyon.com/blog/complex-world-of-wasm-language-support) and how that makes a difference with WebAssembly +- Joel Dice's [WasmDay talk on JVM and WASI](https://youtu.be/MFruf7aqcbE?si=ZfvfuZIL6-JwFJMN) +- [Hands on with Java and Wasm](https://www.infoworld.com/article/3692456/hands-on-with-java-and-wasm.html) at InfoWorld provides a TeaVM example targeted for the browser. diff --git a/content/wasm-languages/javascript.md b/content/wasm-languages/javascript.md new file mode 100644 index 000000000..2326c0b42 --- /dev/null +++ b/content/wasm-languages/javascript.md @@ -0,0 +1,40 @@ +date = "2024-02-18T01:01:01Z" +title = "JavaScript in WebAssembly" +description = "JavaScript can be compiled to WebAssembly. There are even multiple implementations of JavaScript WebAssembly runtimes." +template = "page_lang" +tags = ["javascript","webassembly"] +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/javascript.md" + +--- + +Compiling JavaScript to WebAssembly is different than using JavaScript to talk to a WebAssembly module. +This article is focused on how to take JavaScript code and build it into a WebAssembly module. + +## Uses + +JavaScript in WebAssembly is a recent development. Shopify's platform can generate and run Wasm modules. If Shopify's `javy` tool is built with `--feature standalone-wasi`, then it can create `wasm32-wasi` modules that can be run on the Fermyon platform. While SpiderMonkey can be compiled into JavaScript, only proof-of-concept code exists for building and running WASM this way. However, we expect the SpiderMonkey implementation to mature rapidly. + +## Available JavaScript Implementations + +There are three popular ways of building JavaScript into WebAssembly. + +1. Use the Mozilla SpiderMonkey engine +2. Use the QuickJS implementation and compile the runtime and script into a Wasm module +3. Use the Ducktape implementation of a JavaScript runtime, usually to "safe eval" JS inside of JS using Wasm as an indirection layer + +Recently, Suborbital has introduced a version of [Javy](https://github.com/suborbital/javy) that supports some of their extensions. + +## Learn More + +Here are some great resources: + +- Shopify has created an easy-to-use builder that uses QuickJS. It is called [Javy](https://github.com/Shopify/javy) +- A short article on Wasm.Builders covers [JavaScript, MessagePack, and Javy](https://www.wasm.builders/deepanshu1484/javascript-and-wasi-24k8) +- Bytecode Alliance's [builder for Spidermonkey](https://github.com/bytecodealliance/spidermonkey-wasm-build) provides binary releases +- [QuickJS](https://bellard.org/quickjs/) is a tiny JavaScript runtime that can be compiled to Wasm. +- [Making JavaScript Run Fast on WebAssembly](https://bytecodealliance.org/articles/making-javascript-run-fast-on-webassembly) from Bytecode Alliance explains how SpiderMonkey and Wasm work together. +- [wasm-jseval](https://github.com/maple3142/wasm-jseval) uses Ducktape compiled to Wasm to `eval()` JavaScript inside of JavaScript. Think of it as sandboxed JS +- [QuickJS-Emscripten](https://github.com/justjake/quickjs-emscripten) does something similar to Wasm-JSEval, but with QuickJS instead of Ducktape +- While much conversation is dominated by JS devs who use Wasm in-browser, there is good discussion on the WebAssembly Discord server's `#javascript` channel. \ No newline at end of file diff --git a/content/wasm-languages/kotlin.md b/content/wasm-languages/kotlin.md new file mode 100644 index 000000000..8582d1d45 --- /dev/null +++ b/content/wasm-languages/kotlin.md @@ -0,0 +1,51 @@ +date = "2024-02-18T01:01:01Z" +title = "Kotlin in WebAssembly" +description = "Kotlin support for WebAssembly is in the Alpha stage of development" +tags = ["kotlin", "jvm", "java", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/kotlin.md" + +--- + +Kotlin, like .NET, has an interesting history with WebAssembly. + +## Kotlin Wasm + +A few years ago, the Kotlin team introduced experimental WebAssembly support for the browser: A Kotlin Native `wasm32` LLVM-based compiler target. +However, in 2019 they began a rewrite of the feature. +In late 2020, they demoed the upcoming version, called "Kotlin/Wasm". +In early 2023, the new version was released as experimental, and required the Wasm runtime to support the then-experimental Wasm-GC proposal. Kotlin Native `wasm32` target was deprecated. +In late 2023, Wasm-GC was enabled by default in Chrome and Firefox, and [Kotlin/Wasm went Alpha](https://blog.jetbrains.com/kotlin/2023/12/kotlin-for-webassembly-goes-alpha/). + +## Kotlin on JRE + +Kotlin compiled to Java bytecode can be executed by the [Java-to-Webassembly tools](/wasm-languages/java). + +## Uses + +Kotlin/Wasm can be used in browsers. +At the time of this writing, KoWasm (see below) has WASI support. But because it requires the new Wasm-GC extension, Spin will not support it until [Wasmtime supports Wasm-GC](https://github.com/bytecodealliance/wasmtime/issues/5032). +Therefore, we do not know whether Kotlin can be used to create Fermyon Cloud applications. + +## Available Implementations + +- Kotlin/Wasm is [in Alpha](https://kotlinlang.org/docs/whatsnew-eap.html#new-kotlin-wasm-target), but requires a version of the Wasm runtime that supports Wasm Garbage Collection (Wasm-GC). +- Sebastian Deleuze is working on WASI Kotlin support as [KoWasm](https://github.com/sdeleuze/kowasm). + +## Learn More + +Here are some great resources: + +- Official [Kotlin/Wasm page](https://kotl.in/wasm) +- Official [GitHub repository](https://github.com/Kotlin/kotlin-wasm-examples/), containing a collection of examples demonstrating how to use Kotlin with WebAssembly. +- Sebastian Deleuze's [excellent article](https://seb.deleuze.fr/the-huge-potential-of-kotlin-wasm/) on the potential for Wasm GC and Kotlin (covering Kotlin 1.8.20 Beta) +- A Feb. 2023 Devclass blog post covering [the new Kotlin Wasm compiler](https://devclass.com/2023/02/14/kotlin-debuts-experimental-kotlin-wasm-target-in-new-beta-a-new-approach-to-frontend-development/) +- JetBrains' [Kotlin for WebAssembly Goes Alpha](https://blog.jetbrains.com/kotlin/2023/12/kotlin-for-webassembly-goes-alpha/) announcement. +- The official [preview video](https://www.youtube.com/watch?v=-pqz9sKXatw) of the next-gen Wasm compiler. +- For the latest feature plan, the [Kotlin Roadmap](https://kotlinlang.org/docs/roadmap.html#roadmap-details) is a good source of information. + - The key issue is [KT-46773](https://youtrack.jetbrains.com/issue/KT-46773?_gl=1*srzlan*_ga*NzQzMDU1MDYwLjE2NDI1NTgwMDE.*_ga_J6T75801PF*MTY0MjU1ODAwMS4xLjEuMTY0MjU1ODAxNC4w&_ga=2.168897505.1369047405.1642558002-743055060.1642558001) + - The WASI support issue is [KT-36172](https://youtrack.jetbrains.com/issue/KT-36172/Support-WASI) + - The compiler code is [in GitHub](https://github.com/JetBrains/kotlin/tree/master/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm) +- Wasmtime [tracking issue](https://github.com/bytecodealliance/wasmtime/issues/5032) for Wasm GC diff --git a/content/wasm-languages/lisp.md b/content/wasm-languages/lisp.md new file mode 100644 index 000000000..1694792db --- /dev/null +++ b/content/wasm-languages/lisp.md @@ -0,0 +1,28 @@ +date = "2024-02-18T01:01:01Z" +title = "Lisp in WebAssembly" +description = "Lisp can be compiled to WebAssembly." +tags = ["language", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/lisp.md" + +--- + +The famous functional programming language Lisp has some interesting properties that has intrigued developers. A few projects are work-in-progress ports of Lisp in WebAssembly. Nothing appears to be production-ready yet, but the progress is promising. + +## Uses + +Currently, environments are mainly for R&D usage, and are not entirely complete for either in-browser or out-of-browser usage. + +## Available Implementations + +The [Wisp project][https://github.com/mbrock/wisp] is a Lisp-to-Wasm compiler that is currently being (re-)written in [Zig](/wasm-languages/zig). + +## Learn More + +Here are some great resources: + +- The [Wisp project](https://github.com/mbrock/wisp) is making steady progress +- Wisp appears to be part of a [larger project](https://github.com/nodfur/os) +- [Wasm-Lisp](https://github.com/rolfrm/wasm-lisp) is not as actively maintained, and did not (as far as we know) implement the entire compiler. \ No newline at end of file diff --git a/content/wasm-languages/lua.md b/content/wasm-languages/lua.md new file mode 100644 index 000000000..d532d420d --- /dev/null +++ b/content/wasm-languages/lua.md @@ -0,0 +1,43 @@ +date = "2024-02-18T01:01:01Z" +title = "Lua in WebAssembly" +description = "Lua has several interesting WebAssembly projects." +tags = ["lua", "language", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/lua.md" + +--- + +[Lua](https://www.lua.org/) is a lightweight scripting language designed to be easily embedded. It enjoys broad usage as a plugin-and-extension language, and has a large ecosystem. But it is not generally considered one of the top programming languages. + +## Available Implementations + +Lua does not have an official implementation of a Lua-to-Wasm compiler. + +The following unofficial projects compile or run Lua in WebAssembly: + +- [Wasmoon](https://github.com/ceifa/wasmoon) runs [Lua as a script](https://www.fermyon.com/blog/scripts-vs-compiled-wasm) in the browser via a Lua engine compiled to Wasm. It also works with Node.js and Deno, but does not appear to have WASI bindings. +- [WebAssembly-Lua](https://github.com/ysugimoto/webassembly-lua) - Likely unmaintained emscripted-based compilation. +- [Wasm_Lua](https://github.com/vvanders/wasm_lua) is a project that compiles the Lua engine to WebAssembly, allowing you to run [Lua as a script](https://www.fermyon.com/blog/scripts-vs-compiled-wasm). It also appears to be unmaintained + +It should also be possible to compile Lua interpreters written in Wasm-supported languages. For example, [Hematita](https://crates.io/crates/hematita), written in Rust, should be compilable to Wasm. This is the +same technique [Bartholomew](https://developer.fermyon.com/bartholomew/index) uses for Rhai scripting. + +## Usage + +Wasmoon, the most promising of the above projects, is used to run Lua scripts (uncompiled) inside of browsers, Node, or Deno. The [documentation](https://github.com/ceifa/wasmoon#api-usage) describes usage. + +## Pros and Cons + +No details. + +## Example + +Currently, there are no examples. None of the known implementations have WASI support. + +## Learn More + +Resources: + +- [Wasm2Lua](https://github.com/SwadicalRag/wasm2lua) is an interesting project that translates Wasm modules to Lua code. diff --git a/content/wasm-languages/motoko.md b/content/wasm-languages/motoko.md new file mode 100644 index 000000000..799b867d9 --- /dev/null +++ b/content/wasm-languages/motoko.md @@ -0,0 +1,29 @@ +date = "2024-02-18T01:01:01Z" +title = "Motoko in WebAssembly" +description = "Motoko is a WebAssembly-first language that supports creating Internet Computer canisters." +tags = ["motoko", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/motoko.md" + +--- + +Motoko is a high-level programming language that is designed for writing Internet Computer canisters. It leverages a simple design for everyday programmers and supports an underlying Wasm and IC execution model. + +## Uses + +Motoko can be used to develop Internet Computer canisters. The Internet Computer is the world’s first blockchain that runs at web speed and can increase its capacity without bound. + +## Available Implementations + +Motoko has an [official implementation](https://github.com/dfinity/motoko) that supports Wasm and WASI out of the box. + +## Learn More + +Here are some great resources: + +- An StackOverflow article [on the benifits of Motoko](https://stackoverflow.blog/2020/08/24/motoko-the-language-that-turns-the-web-into-a-computer/) +- An example [IC implementation in Motoko](https://github.com/dfinity/motoko/blob/master/samples/pa_cars.mo) +- A an introductory [YouTube video about Motoko](https://www.youtube.com/watch?v=4eSceDOS-Ms&feature=emb_title) +- A hands-on [Motoko Playground](https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/) \ No newline at end of file diff --git a/content/wasm-languages/objective-c.md b/content/wasm-languages/objective-c.md new file mode 100644 index 000000000..e01f1ca13 --- /dev/null +++ b/content/wasm-languages/objective-c.md @@ -0,0 +1,21 @@ +date = "2024-02-18T01:01:01Z" +title = "Objective-C in WebAssembly" +description = "Apple may be working on Objective-C to Wasm compilation." +tags = ["objective-c", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/objective-c.md" + +--- + +It seems like Objective-C to WebAssembly should be possible in no small part because of LLVM. +However, we haven't tracked down any examples or implementations. + +Apple is hinting that not only do they have such a tool, but they use it in their apps. + +According to [this tweet](https://twitter.com/lrz/status/1250453967957561344?s=20): + +> What have I been working on lately? Just a few days ago, iWork 10.0 shipped with iCloud apps that now include features extracted from the native codebase (C++/ObjC), using WebAssembly! + +(See the rest of the thread for more info.) diff --git a/content/wasm-languages/perl.md b/content/wasm-languages/perl.md new file mode 100644 index 000000000..21e178529 --- /dev/null +++ b/content/wasm-languages/perl.md @@ -0,0 +1,54 @@ +date = "2024-02-18T01:01:01Z" +title = "Perl in WebAssembly" +description = "A Perl interpreter in WebAssembly is available." +tags = ["perl", "language", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +last_modified = "2023-10-26T00:50:50Z" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/perl.md" + +--- + +Perl (Practical Extraction and Reporting Language) was the _lingua franca_ of the early web. +A powerful scripting language, it became a popular way to write CGI. + +Larry Wall, its creator, once called it the "first post-modern programming language" +because it was driven more by a desire to add the things developers liked than to follow specific academic strictures. +Its regular expressions have lived on, influencing the designs of countless +other programming languages. + +## Available Implementations + +There is no official Perl distribution that is WebAssembly-capable. + +The [WebPerl project](https://webperl.zero-g.net/) provides a browser-centered Perl interpreter in Wasm. +Build instructions support Perl 5.26 and newer. + +WebPerl does not provide a WASI implementation, and does not appear to be runnable outside of a browser. +But the maintainer has suggested he'd [like to add WASI support](https://github.com/haukex/webperl/issues/23). + +## Usage + +WebPerl describes [usage inside of a browser](https://webperl.zero-g.net/using.html). + +## Pros and Cons + +Things we like: + +- The project supports a tremendous number of features, including a way to bundle PMs. +- The project is impressively well thought out +- Documentation covers a wide variety of cases and uses +- There is even a sample IDE + +Things we're not big fans of: + +- It runs only in the browser +- The project seems to be stagnant + +## Learn More + +Here are some great resources: + +- The [source code of WebPerl](https://github.com/haukex/webperl) +- We [asked](https://github.com/haukex/webperl/issues/23) if there are plans for a WASI version of WebPerl diff --git a/content/wasm-languages/php.md b/content/wasm-languages/php.md new file mode 100644 index 000000000..a1fe86b04 --- /dev/null +++ b/content/wasm-languages/php.md @@ -0,0 +1,37 @@ +date = "2024-02-18T01:01:01Z" +title = "PHP in WebAssembly" +description = "PHP can be compiled to WebAssembly and run in the browser." +tags = ["PHP", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/php.md" + +--- + +PHP is a popular web scripting language. +So it is unsurprising that one PHP project attempts to make it possible to run PHP inside of the web browser. + +There have been a few iterations of _PHP-in-Browser_ (PIB), but Sean Morris' [PHP-Wasm](https://github.com/seanmorris/php-wasm) +looks to be the most active. + +## Uses + +Right now, this is specific to the browser environment. +The implementation is impressive, as it contains a lot of PHP features such as +access to a database (SQLite) and file system access. + +## Available Implementations + +- [PHP-Wasm](https://github.com/seanmorris/php-wasm) +- The original version of PHP-In-Browser (PIB) was [Oraoto's version](https://oraoto.github.io/pib/) +- Another version of PIB is [Soyuka's fork](https://github.com/soyuka/php-wasm) +- [`wasm32-wasi` PHP releases](https://github.com/vmware-labs/webassembly-language-runtimes/releases?q=php&expanded=true) provided by the Wasm Labs team at VMware + +## Learn More + +Here are some great resources: + +- Try it out [in-browser](https://seanmorris.github.io/php-wasm/) +- The [examples](https://github.com/seanmorris/php-wasm#examples) even include running Drupal 7! +- If you are looking for a way to run Wasm inside of PHP, [Wasmer has bindings](https://github.com/wasmerio/wasmer-php) diff --git a/content/wasm-languages/powershell.md b/content/wasm-languages/powershell.md new file mode 100644 index 000000000..90bb22c85 --- /dev/null +++ b/content/wasm-languages/powershell.md @@ -0,0 +1,24 @@ +date = "2024-02-18T01:01:01Z" +title = "PowerShell and WebAssembly" +description = "PowerShell cannot be compiled to WebAssembly." +tags = ["powershell", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/powershell.md" + +--- + +PowerShell is consistently ranked among the top programming languages. +However, it is not generally considered to be a general-purpose language like [C](./c-lang.md) or [Python](./python.md). +So we were a little surprised to find at least some information about PowerShell and WebAssembly. + +Most of it stems from the fact that the Blazor WebAssembly framework frequently uses PowerShell [in the examples](https://stackshare.io/stackups/powershell-vs-webassembly). + +We think it is unlikely that PowerShell will ever be compiled to WebAssembly. + +## Learn More + +Here are some great resources: + +- A comparison of [PowerShell and WebAssembly](https://stackshare.io/stackups/powershell-vs-webassembly), though it is probably autogenerated and wasn't particularly insightful. \ No newline at end of file diff --git a/content/wasm-languages/prolog.md b/content/wasm-languages/prolog.md new file mode 100644 index 000000000..598884469 --- /dev/null +++ b/content/wasm-languages/prolog.md @@ -0,0 +1,136 @@ +date = "2024-02-18T01:01:01Z" +title = "Prolog in WebAssembly" +description = "Prolog can be compiled to WebAssembly, and there are many supporting projects." +tags = ["language", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/prolog.md" + +--- + + + +[Prolog](https://prolog.readthedocs.io/) is a logic programming language with several different implementations. +Trealla Prolog is the one most frequently associated with WebAssembly. + +## Available Implementations + + + +* [Trealla Prolog](https://github.com/trealla-prolog/trealla) has Wasm and WASI support +* [Guregu's Trealla Prolog](https://github.com/guregu/trealla) was (I believe) the origin of Trealla's support +* [Trealla Spin](https://github.com/guregu/trealla-spin), also by [Guregu](https://github.com/guregu), adds a Spin SDK for Prolog + +## Usage + + + +The easiest way to use Trealla Prolog is with the Spin plugin. It will manage the Prolog runtime for you. + +Install the Spin plugin: + +```console +$ spin templates install --git https://github.com/guregu/trealla-spin --update +``` + +Otherwise, you can follow the installation and build instructions on the [Trealla Prolog](https://github.com/trealla-prolog/trealla) GitHub page. + +## Pros and Cons + + +Things we like: + +- It is super easy to use +- [A Spin SDK!](https://github.com/guregu/trealla-spin) + +## Example + + Create a new app: + +```console +$ spin new http-prolog hello-prolog --accept-defaults +``` + +Run the app: + +``` +$ cd hello-prolog +$ spin up + +Logging component stdio to ".spin/logs/" +Storing default key-value data to ".spin/sqlite_key_value.db" + +Serving http://127.0.0.1:3000 +Available Routes: + hello-prolog: http://127.0.0.1:3000 (wildcard) +``` + +Doing `spin up` fetches the prolog interpreter, so there is no `spin build` step. + +The scaffolded code looks like this: + +```prolog +:- use_module(library(spin)). + +% See library/spin.pl for all the predicates built-in +% https://github.com/guregu/trealla/blob/main/library/spin.pl + +%% http_handler(+Spec, +Headers, +Body, -Status) + +http_handler(get("/", _QueryParams), _RequestHeaders, _RequestBody, 200) :- + html_content, + setup_call_cleanup( + store_open(default, Store), + ( + ( store_get(Store, counter, N0) + -> true + ; N0 = 0 + ), + succ(N0, N), + store_set(Store, counter, N) + ), + store_close(Store) + ), + http_header_set("x-powered-by", "memes"), + current_prolog_flag(dialect, Dialect), + % stream alias http_body is the response body + write(http_body, ''), + format(http_body, "

Hello, ~a prolog!

", [Dialect]), + format(http_body, "Welcome, visitor #~d!", [N]), + write(http_body, ''). + +http_handler(get("/json", _), _, _, 200) :- + wall_time(Time), + % json_content({"time": Time}) works too + json_content(pairs([string("time")-number(Time)])). +``` + +## Learn More + +Here are some great resources: + + +- Using [Trella Prolog in Spin](https://github.com/guregu/trealla-spin) +- Also fun: Check out the PHP ([Prolog Home Page](https://github.com/guregu/php)) project! diff --git a/content/wasm-languages/python.md b/content/wasm-languages/python.md new file mode 100644 index 000000000..d23dcc302 --- /dev/null +++ b/content/wasm-languages/python.md @@ -0,0 +1,93 @@ +date = "2024-02-18T01:01:01Z" +title = "Python in WebAssembly" +description = "Python can almost be compiled to WebAssembly. The implementations are now stable." +tags = ["python", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/python.md" + +--- + +Python is one of the most popular programming languages in the world, and its WebAssembly implementation seems to be coming along quickly. +While it is not yet ready for use, we anticipate it will be functional in the first half of 2022. + +The most momentum is in the CPython community, which is approaching both Emscripten-based and WASI-based implementations. + +## Available Implementations + +WebAssembly support is officially available in CPython 3.11 and after. The [GitHub CPython repo](https://github.com/python/cpython) has all of the code. + +There is also a [Spin SDK for Python](https://github.com/fermyon/spin-python-sdk) that uses CPython, but reduces startup time by preloading and initializing the scripts. There's a [detailed blog post about Python on Fermyon.com](https://www.fermyon.com/blog/spin-python-sdk) that explains this. + +## Usage + +The Spin SDK makes it very easy to build Python-based Wasm applications simply by using a Spin template that handles all of the heavy lifting. + +## Example + +Create a new project: + +```console +$ spin new http-py python-example --accept-defaults +``` + +Take a look at the scaffolded program in `app.py`: + +```python +from spin_http import Response + +def handle_request(request): + + return Response(200, + {"content-type": "text/plain"}, + bytes(f"Hello from the Python SDK", "utf-8")) +``` + +Compile a Wasm binary with the scripts preloaded, and then start up a local server: + +```console +$ spin build --up +Building component python-example with `spin py2wasm app -o app.wasm` +Spin-compatible module built successfully +Finished building all Spin components +Logging component stdio to ".spin/logs/" + +Serving http://127.0.0.1:3000 +Available Routes: + python-example: http://127.0.0.1:3000 (wildcard) +``` + +Test it with `curl`: + +```console +$ curl localhost:3000/ +Hello from the Python SDK +``` + +The file `app.wasm` contains both the interpreter (in an initialized state) and all of the userland code: + +```console +$ ls -lah app.wasm +-rw-r--r-- 1 technosophos staff 24M Oct 26 18:22 app.wasm +``` + +## Learn More + +Joel's video on Spin, Python, and Components: + + + +Here are some great resources: +- A tutorial for building [Python Wasm apps with Spin](https://dev.to/technosophos/building-a-serverless-webassembly-app-with-spin-5dh9) +- A tutorial doing [AI inferencing with Python and Spin](https://www.wasm.builders/technosophos/serverless-ai-inferencing-with-python-and-wasm-3lkd) +- The [Spin Python SDK](https://github.com/fermyon/spin-python-sdk) +- The [Spin Developer Docs](https://developer.fermyon.com/spin) fully document the Python SDKs +- [Python Wasm examples](https://developer.fermyon.com/hub) at Spin Up Hub +- The [Componentize-Py](https://pypi.org/project/componentize-py/) tooling +- VMware has a [distribution of CPython as Wasm](https://github.com/vmware-labs/webassembly-language-runtimes/tree/main/python) based on official CPython +- A detailed document about [the (once) current state and features of Wasm](https://pythondev.readthedocs.io/wasm.html) in the latest CPython version (Now outdated) +- Fermyon.com published a slightly more [in-depth Python and Wasm tutorial](https://www.fermyon.com/blog/python-wagi) +- An in-browser [Python shell in Wasm](https://github.com/ethanhs/python-wasm) (Not the preferred path) +- One version of [CPython + Wasm](https://github.com/ethanhs/python-wasm), where they are working on [WASI support](https://github.com/ethanhs/python-wasm/issues/18) +- [SingleStore's wasi-python project](https://github.com/singlestore-labs/python-wasi) is another approach diff --git a/content/wasm-languages/r-lang.md b/content/wasm-languages/r-lang.md new file mode 100644 index 000000000..559081893 --- /dev/null +++ b/content/wasm-languages/r-lang.md @@ -0,0 +1,24 @@ +date = "2024-02-18T01:01:01Z" +title = "R in WebAssembly" +description = "R cannot be compiled to WebAssembly yet, but we have seen a few conversations floating around." +tags = ["r language", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +last_modified = "2022-02-17T16:55:42Z" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/r-lang.md" + +--- + +R is a popular statistics-oriented language. An in-browser version of the language is now in development. This version patches the official R repository and adds browser tooling. We are unsure whether this version of R can be run in standalone WebAssembly runtimes like Wasmtime or Wamr. + +At one point there was an interesting [conversation about WebAssembly](https://www.reddit.com/r/Rlanguage/comments/b4izog/compile_r_to_webassembly_and_use_as_a_data/) on the R language Subreddit. As far as we know, nothing came of it. But to settle one of the debates on that thread, [yes, it appears Fortran can be compiled to Wasm](https://github.com/DirkWillem/WebAssembly-Fortran-Demo) + +## Learn More + +Here are some great resources: + +- [webR](https://github.com/georgestagg/webR), an in-browser implementation of R +- An excellent [blog post](https://blog.ouseful.info/2022/02/17/running-r-and-debian-linux-in-the-browser-via-wasm/) on webR. +- An [in-browser R console](https://www.mas.ncl.ac.uk/~ngs54/webR/) built using webR +- A [Fortran-to-Wasm](https://github.com/StarGate01/Full-Stack-Fortran) compiler toolchain. \ No newline at end of file diff --git a/content/wasm-languages/ruby.md b/content/wasm-languages/ruby.md new file mode 100644 index 000000000..e851662e3 --- /dev/null +++ b/content/wasm-languages/ruby.md @@ -0,0 +1,194 @@ +date = "2024-02-18T01:01:01Z" +title = "Ruby in WebAssembly" +description = "Ruby can be compiled to WebAssembly. While there are a number of projects to do so, none are complete." +tags = ["ruby", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/ruby.md" + +--- + +Ruby is one of the most popular scripting languages. +Famous for the Rails framework, it has been a stalwart for web developers. + +Ruby now has multiple WebAssembly-based projects, including an official release of CRuby. + +# Available Implementations + +There is an official [Wasm build of Ruby](https://github.com/ruby/ruby.wasm/). +It supports WASI and a wide array of features. +VMware provides a [release of the official Ruby runtime as Wasm](https://github.com/vmware-labs/webassembly-language-runtimes) +Shopify has a [Wizer-optimized version of Ruby](https://github.com/Shopify/ruvy), which they call Ruvy, that speeds up startup time. This, too, uses the official CRuby. + +In addition to the official Ruby distribution, [Artichoke](https://www.artichokeruby.org/) is a Rust implementation of Ruby that can compile to WebAssembly (`wasm32-unknown`). + +`rlang` (a subset of Ruby) can run Wasm32 code in a `wasm32-wasi` runtime like `wasmtime`. + +In this guide, we focus on the official release of Ruby (`ruby.wasm`). + +## Usage + +To use the official Ruby Wasm, [download a prebuilt binary](https://github.com/ruby/ruby.wasm/releases) and decompress the downloaded archive. + +Inside of the package, you will find a full distribution of Ruby: + +```console +$ tree -L 3 +. +├── usr +│   └── local +│   ├── bin +│   ├── include +│   ├── lib +│   └── share +└── var + └── lib + └── gems +``` + +The Wasm binaries are in `/usr/local/bin`. For example, to run the Ruby interpreter, you can use `wasmtime ./usr/local/bin/ruby`. The example section below illustrates usage. + +## Pros and Cons + +Things we like: + +- The toolchain has been very thoughtfully developed +- It is possible to use gems that do not have C code. (We suspect there might be a way to use C extensions, but we haven't figured it out) + +We're neutral about: + +- The size of the interpreter is large, and can take a moment to start +- Spin (and Wagi) need extra configuration to simulate a command line for Ruby + +Things we're not big fans of: + +- At this stage, users of the Wasm version will need to understand how Ruby loads its dependencies + +## Example + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +Ruby can run in either Spin or Wagi. Here, we show how to use Spin. + +Start out with a new directory: + +```console +$ mkdir hello-ruby +$ cd hello-ruby +``` + +Now fetch a copy of the Ruby source from the [official releases](https://github.com/ruby/ruby.wasm/releases). +For this example, we are downloading the `ruby-head-wasm32-unknown-wasi-full.tar.gz` version, +but one of the smaller versions works just as well. + +Now create a local `lib` dir where we will put our own source. +It is also a good idea to create `.gem/`, though we won't use it in this example. + +```console +$ mkdir lib +$ mkdir .gem +``` + +At this point, our directory should look like this: + +```console +$ tree -L 2 -a -d +. +├── .gem +├── head-wasm32-unknown-wasi-full +│   ├── usr +│   └── var +└── lib +``` + +Inside of `lib`, we can create `hello.rb`: + +```ruby +puts "content-type: text/plain" +puts "" +puts "Hello, World" +``` + +You can verify this works by using `ruby lib/hello.rb`. + +```console +$ ruby lib/hello.rb +content-type: text/plain + +Hello, World +``` + +Ruby is a scripting language, which means it will need to load a number of scripts (ours plus all of the built-in libraries) off of its filesystem. The `spin.toml` file for Ruby is more complex than most: + +```toml +spin_version = "1" +name = "example-ruby-app" +version = "0.1.0" +trigger = { type = "http", base = "/" } + +[[component]] +files = [ + { source = "lib", destination = "/lib" }, + { source = ".gem", destination = "/.gem" }, + { source = "head-wasm32-unknown-wasi-full/usr", destination = "/usr" }, +] +id = "ruby" +source = "head-wasm32-unknown-wasi-full/usr/local/bin/ruby" +[component.trigger] +executor = { type = "wagi", argv = "${SCRIPT_NAME} -v /lib/hello.rb ${SCRIPT_NAME} ${ARGS}" } +route = "/" +[component.environment] +HOME = "/" +GEM_HOME = "/.gem" +``` + +Note that we need to mount several sets of files: `lib`, `.gem`, and `usr`. This exposes all of Ruby's supporting files. +(Remember: Ruby is a scripting language, and only the interpreter is compiled to Wasm. The rest is Ruby source.) + +While `lib` and `.gem` should point to your local dev environment, you need to load `usr` from the Ruby project. + +A few environment variables also need to be set for the interpreter: `HOME` and `GEM_HOME`. +These should usually be set exactly as above. + +Next, running `spin up` will start the server. + +```console +$ spin up +Preparing Wasm modules is taking a few seconds... + +Serving HTTP on address http://127.0.0.1:3000 +``` + +Note that the first line occurs because when Spin starts up, it does take Ruby a few moments to load all of its supporting files. +_Using one of the [smaller instances](https://github.com/ruby/ruby.wasm/releases) will improve startup time +and overall performance._ + +From here, we can run our usual `curl` command or point a web browser to Spin: + +```console +$ curl localhost:3000 +Hello, World +``` + +And that's all there is to it. + +>> If you need help with Ruby and Spin/Wagi, [join our Discord](https://discord.gg/AAFNfS7NGf) and ask. We know it's not the easiest environment to get running. + +## Learn More + +Here are some great resources: + +- The [official project](https://github.com/ruby/ruby.wasm) explains building `ruby.wasm` +- [Ruvy](https://github.com/Shopify/ruvy) is the official Ruby, but optimized (via Wizer) for faster startup times, and to not load script files. This works similarly to Fermyon's JS and Python SDKs. +- VMware's [Ruby interpreter compiled to Wasm](https://github.com/vmware-labs/webassembly-language-runtimes) +- InfoWorld (Oct. 2023) explains Shopify's new [Ruvy runtime](https://www.infoworld.com/article/3709509/ruvy-converts-ruby-code-to-webassembly.html) +- An update on [the state of Ruby, Wasm, and WASI](https://medium.com/@kateinoigakukun/final-report-webassembly-wasi-support-in-ruby-4aface7d90c9) in March, 2022 +- Instructions for [building Ruby with wasm32-wasi support](https://github.com/ruby/ruby/pull/5407) +- A fun [dice roller browser app](https://repl-wasm.bcdice.org/) written in Ruby. Source is on [GitHub](https://github.com/bcdice/repl.wasm) +- [Rlang](https://github.com/ljulliar/rlang) compiles a subset of the Ruby language to Wasm +- [Artichoke](https://www.artichokeruby.org/) is a Rust implementation of Ruby that can compile to WebAssembly (`wasm32-unknown`) +- The [mruby](https://github.com/mruby/mruby) runtime has been compiled to WebAssembly, which means you can interpret a Ruby script inside of a Wasm module +- [Prism](https://github.com/prism-rb/prism) uses `mruby` to run Ruby inside of WebAssembly +- While it doesn't seem to be active anymore, [run.rb](https://runrb.io/) is a project for running Ruby in the browser as Wasm. +- [wruby](https://github.com/pannous/wruby) also no longer looks active, but it was an `mruby`-based in-browser Ruby interpreter. diff --git a/content/wasm-languages/rust.md b/content/wasm-languages/rust.md new file mode 100644 index 000000000..34f8283f5 --- /dev/null +++ b/content/wasm-languages/rust.md @@ -0,0 +1,150 @@ +date = "2024-02-18T01:01:01Z" +title = "Rust in WebAssembly" +description = "Rust supports a broad array of WebAssembly options." +tags = ["rust", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/rust.md" + +--- + +Rust is probably the best supported language of the WebAssembly ecosystem. +Not only does Rust support several WebAssembly compile targets, +but `wasmtime`, Spin, Wagi, and many other WebAssembly tools are written in Rust. +Rust can be used to create Fermyon Platform apps. + +## Available Implementations + +WebAssembly and WASI support are [officially supported](https://www.rust-lang.org/what/wasm) by the Rust project. + +## Usage + +While the WebAssembly compiler does not ship with the default Rust distribution, it can be easily added. +To add the `wasm32-wasi` compiler, simply use `rustup`: + +```console +$ rustup target add wasm32-wasi +``` + +Then to compile a program to rust, set the target when running `cargo build`: + +```console +$ cargo build --target wasm32-wasi --release +``` + +While `--release` is not required, doing so will drastically reduce the size of the output `.wasm` module. +WebAssembly binaries will be written to your project's `target/wasm32-wasi/release` directory. + +## Pros and Cons + +Things we like: + +- The Rust ecosystem for Wasm and WASI is fabulous +- Many of the Wasm tools are written in Rust, which means there is plenty of code to look at +- Spin usually has Rust support for features before it has support for other languages +- Wasmtime, written in Rust, often has cutting edge features before other runtimes +- We have used many Rust libraries off the shelf with WebAssembly +- Thanks to Cargo's flexible build system, some crates even have special feature flags to enable Wasm features (e.g. Chrono) +- Because of Rust's memory management techniques, Rust binary sizes are small compared to similar languages + +Things we're not big fans of: + +- Many Rust libraries do not work with Wasm. Most notably, anything that uses Tokio or `async` does not yet work. + +## Example + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +Rust can use Spin's native executor as well as Spin's Wagi executor. We strongly recommend the native one, as it has more features. + +When writing Spin applications in Rust, use `cargo init --lib` or `cargo new --lib`. Spin loads the `wasm` files as libraries, not as executables with a `main` function. + +Here is an example `lib.rs` that uses Spin's native executor: + +```rust +use anyhow::Result; +use spin_sdk::{ + http::{Request, Response}, + http_component, +}; + +/// A simple Spin HTTP component. +#[http_component] +fn hello_world(_req: Request) -> Result { + Ok(http::Response::builder() + .status(200) + .body(Some("Writing a very simple Spin component in Rust".into()))?) +} +``` + +Note that your `Cargo.toml` will need to include at least the Spin SDK. We recommend starting with something like this: + +```toml +[package] +name = "rust-hello" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = [ "cdylib" ] + +[dependencies] +# Useful crate to handle errors. +anyhow = "1" +# Crate to simplify working with bytes. +bytes = "1" +# General-purpose crate with common HTTP types. +http = "0.2" +# The Spin SDK. +spin-sdk = { git = "https://github.com/fermyon/spin" } +# Crate that generates Rust Wasm bindings from a WebAssembly interface. +wit-bindgen-rust = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "2f46ce4cc072107153da0cefe15bdc69aa5b84d0" } +``` + +To build a Spin app in rust, use `cargo build`: + +```console +$ cargo build --target wasm32-wasi --release +``` + +(Again, we suggest `--release` to keep binary sizes small.) + +The resulting binary can be run in Spin with a `spin.toml` that looks something like this: + +```toml +spin_version = "1" +authors = ["Fermyon Engineering "] +description = "Hello world app." +name = "spin-hello" +trigger = { type = "http", base = "/" } +version = "1.0.0" + +[[component]] +id = "hello" +source = "target/wasm32-wasi/release/hello.wasm" +[component.trigger] +route = "/" +``` + +Note that we do _not_ add an `executor` line at the bottom of this file as we do in many other examples. + +From there, running the app is as easy as `spin up`! + +### Writing Wagi-Based Rust Apps + +It is also possible to write a Wagi application in Rust and run it in Spin or Wagi. Examples of this exist [in the Wagi examples repository](https://github.com/deislabs/wagi-examples). + +## Learn More + +Here are some great resources: + +- The official [documentation for Spin](https://spin.fermyon.dev/rust-components/) has many examples, including creating Redis listeners. +- Rust has a [dedicated mini-site covering WebAssembly](https://www.rust-lang.org/what/wasm) +- The Rust Linz group did a [presentation on Rust and Wagi](https://www.youtube.com/watch?v=9NDwHBjLlhQ) and posted a GitHub [repo full of Wagi examples](https://github.com/rstropek/rust-samples) +- [Wasmtime](https://wasmtime.dev/) is the reference implementation of Wasm32-WASI. +- [egui](https://www.egui.rs/) provides a GUI toolkit that can be compiled into Wasm and run in the browser +- DeisLabs has some [Rust Wagi examples](https://github.com/deislabs/wagi-examples) +- The [Bartholomew CMS](https://github.com/fermyon/bartholomew) is written in Rust and runs in Spin or Wagi +- The [spin-fileserver](https://github.com/fermyon/spin-fileserver) is a simple Rust Spin-native app +- There are several rich examples in the [Spin Kitchen Sink repo](https://github.com/fermyon/spin-kitchensink) \ No newline at end of file diff --git a/content/wasm-languages/scala.md b/content/wasm-languages/scala.md new file mode 100644 index 000000000..8c536aa85 --- /dev/null +++ b/content/wasm-languages/scala.md @@ -0,0 +1,21 @@ +date = "2024-02-18T01:01:01Z" +title = "Scala in WebAssembly" +description = "Scala native can be compiled to WebAssembly with a somewhat lengthy process. Some Java tools work for compiling Scala to WebAssembly, too." +tags = ["scala", "java", "kotlin", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/scala.md" + +--- + +Like Kotlin, Scala began as a JVM-specific language and has moved toward other backends like LLVM. +Therefore, there are two paths for compiling Scala to WebAssembly: + +1. Use Java tools to compile Scala/bytecode to WebAssembly +2. Use Scala Native toolchains to compile Scala to WebAssembly + +If you are interested in the first way, we cover several tools in the [Java section](/wasm-languages/java). +Here, we'll look at the case for Scala Native. + +Thus far, the only hint we have seen of someone compiling Scala Native to WebAssembly is this [GitHub repository](https://github.com/shadaj/scala-native-wasm). diff --git a/content/wasm-languages/shell.md b/content/wasm-languages/shell.md new file mode 100644 index 000000000..e33e4a918 --- /dev/null +++ b/content/wasm-languages/shell.md @@ -0,0 +1,31 @@ +date = "2024-02-18T01:01:01Z" +title = "Shell in WebAssembly" +description = "Various projects are implementing shell-like implementations in WebAssembly" +tags = ["shell", "bash", "sh", "csh", "unix"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/shell.md" + +--- + +"Shell" refers to the class of UNIX-like languages that are designed for interactive prompts and shell scripts. +This includes sh (Borne Shell), bash (Borne Again Shell), csh (C Shell), and zsh (Z Shell) among others. + +Unlike many of the languages in this guide, we assume that shell scripting using these languages is unlikely to be a desirable development experience. This is in part because, by nature, shell is designed to call and run other programs, which WebAssembly typically does not allow. However, we are starting to see some shell-like languages appear on the scene. + +## Available Implementations + +- [WASI FS Access](https://github.com/GoogleChromeLabs/wasi-fs-access) provides an example shell that works similarly to bash +- [WebAssembly.sh](https://github.com/wasmerio/webassembly.sh) is a basic shell integrated with Wasmer. + +## Usage + +Both of the implementations above provide a shell-like in-browser experience. + +## Learn More + +Here are some great resources: + +- RReverser's blog post on [writing a shell in Wasm](https://rreverser.com/webassembly-shell-with-a-real-filesystem-access-in-a-browser/) +- Aaron Turner's [WebAssembly.sh](https://webassembly.sh/) - the actual program, not a resource diff --git a/content/wasm-languages/standards.md b/content/wasm-languages/standards.md new file mode 100644 index 000000000..3426f7a96 --- /dev/null +++ b/content/wasm-languages/standards.md @@ -0,0 +1,53 @@ +date = "2024-02-18T01:01:01Z" +title = "Related Standards" +description = "WebAssembly relies upon many different standards. This page catalogs standards and where to work on them." +tags = ["standards", "wasi", "webassembly", "wasm", "components"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +last_modified = "2022-07-25T21:50:50Z" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/standards.md" + +--- + +This page tracks WebAssembly standards along with useful resources for understanding those standards or getting involved. + +## WebAssembly Standard and W3 Working Group + +WebAssembly is standardized by W3C, the same group that standardizes CSS, HTML, and HTTP. + +- The [W3's official Wasm site](https://www.w3.org/wasm/) +- Almost all of the working drafts of proposed standards are [in the WebAssembly GitHub Org](https://github.com/WebAssembly) + - All proposals [are in one repo](https://github.com/WebAssembly/proposals) + - The [meetings repo](https://github.com/WebAssembly/meetings) is good to find out when things are happening +- The [W3 GitHub repo](https://github.com/w3c/wasm-wg/) +- The [W3 Community Page](https://www.w3.org/community/webassembly/) + +## WebAssembly System Interface (WASI) + +- The [WASI site](https://wasi.dev) is the main page +- The [WASI repo](https://github.com/WebAssembly/WASI) +- The working group [charter](https://github.com/WebAssembly/WASI/blob/main/Charter.md) +- Most of the WASI proposed standards are [in the WebAssembly GitHub](https://github.com/search?q=org%3AWebAssembly+wasi) +- The [WASI libc library](https://github.com/WebAssembly/wasi-libc) is the C library for core WASI + +### The Component Model + +One very important WebAssembly specification is the Component Model. + +- The [proposal](https://github.com/WebAssembly/component-model) +- The [design and specification](https://github.com/WebAssembly/component-model) +- A great [intro blog post](https://www.fermyon.com/blog/webassembly-component-model) +- The [Canonical ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md) + +## WebAssembly Gateway Interface (Wagi) + +DeisLabs (at Microsoft) proposed Wagi based on the CGI 1.1 specification. + +- The architecture document is [in the Wagi server repo](https://github.com/deislabs/wagi/blob/main/docs/architecture.md) +- The description of the [environment variables](https://github.com/deislabs/wagi/blob/main/docs/environment_variables.md) +- Spin's [Wagi support](https://developer.fermyon.com/spin/v2/http-trigger) + +## Spin Improvement Proposals (SIPs) + +- The [source repository](https://github.com/fermyon/spin/tree/main/docs/content/sips) diff --git a/content/wasm-languages/swift.md b/content/wasm-languages/swift.md new file mode 100644 index 000000000..5229f924d --- /dev/null +++ b/content/wasm-languages/swift.md @@ -0,0 +1,129 @@ +date = "2024-02-18T01:01:01Z" +title = "Swift in WebAssembly" +description = "Swift can be compiled to WebAssembly and run in-browser, at the CLI, and with WASI enabled." +tags = ["swift", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/swift.md" + +--- + +Swift is a popular language in the Apple ecosystem. +But it is no longer just for iOS apps. +Thanks to a recent community-led project, it is possible to [compile Swift into WebAssembly](https://swiftwasm.org/) +destined either for the browser or for a WASI environment. + +## Available Implementations + +The [SwiftWasm](https://swiftwasm.org/) project compiles Swift to WebAssembly. While this is a community-led project, the [stated goal](https://book.swiftwasm.org/index.html) of the project is: + +> [T]o fully support the WebAssembly target for Swift and to be merged into the upstream repository. + +It works like a drop-in replacement to the standard Swift tools. + +The [RemObjects Elements](https://www.elementscompiler.com/elements/) compiler (commercial license required) may support compiling Swift to WebAssembly, too. We have not tested it. + +## Usage + +SwiftWasm supports macOS and Linux operating systems. In addition to the standard Swift environment, you will need to [install the SwiftWasm tools](https://book.swiftwasm.org/getting-started/setup.html). + +Once that is done, the `swift` tool should report SwiftWasm support: + +``` +$ swift --version +SwiftWasm Swift version 5.5 (swiftlang-5.5.0) +Target: arm64-apple-darwin21.1.0 +``` + +From there, the `swift` tool works as usual. + +One of Fermyon's engineers has been working on a [Spin SDK for Swift](https://github.com/endocrimes/swiftwasm-test). It's in its early stages. + +### Optimizing + +You may find that optimizing Swift code with `wasm-opt` (part of [Binaryen](https://github.com/WebAssembly/binaryen)) can cut down binary size. The `hello.wasm` compiled below was 9.1M. Running it through `wasm-opt -Os` cut it down to 5.0M. + +## Pros and Cons + +Things we like: + +- Swift is a great language with many good core features +- The toolchain for Wasm feels no different than native tools +- The project documentation is very good + +We're neutral about: + +- The binary sizes can be quite large, so we recommend running `wasm-opt` on your `.wasm` files to trim out unused code. + +Things we're not big fans of: + +- There is no Windows support + +## Example + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +Once you have installed SwiftWasm, it is easy to build applications for the Fermyon Platform using Wagi. + +The simplest Swift program for Spin (or Wagi) looks like this: + +```swift +print("content-type: text/plain\n\n") +print("Hello, World!\n") +``` + +To compile, set the target to `wasm32-unknown-wasi` (which ensures that WASI support is enabled): + +```console +$ swiftc -target wasm32-unknown-wasi hello.swift -o hello.wasm +``` + +This binary can be executed with `wasmtime`: + +```console +$ wasmtime hello.wasm +content-type: text/plain + +Hello, World! +``` + +To run it as a Spin web application, we can add a `spin.toml` that looks like this: + +```toml +spin_version = "1" +authors = ["Fermyon Engineering "] +description = "Hello world app." +name = "spin-hello" +trigger = { type = "http", base = "/" } +version = "1.0.0" + +[[component]] +id = "hello" +source = "hello.wasm" +[component.trigger] +route = "/" +executor = { type = "wagi" } +``` + +Note that we use the `wagi` executor. + +And then, in the same directory, run `spin up`. Once the server is running, you can use either `curl` or a web browser to test it. + +```console +$ curl localhost:3000 + +Hello, World! +``` + +>> When the Swift Spin SDK is generally available, it will be possible to use many Fermyon Spin services like Key Value Store, SQLite Database, and Serverless AI. + +## Learn More + +Here are some great resources: + +- It is possible to use the [Swift Package Manager with Wasm](https://book.swiftwasm.org/getting-started/swift-package.html) +- There is a [Swift Spin SDK](https://github.com/endocrimes/swiftwasm-test) in development. +- The [SwiftWasm Book](https://book.swiftwasm.org/) has examples and info about compiling to Wasm32+WASI +- [yo-wasm](https://github.com/deislabs/yo-wasm) supports Swift +- Here is a [very quick quickstart](https://betterprogramming.pub/get-started-with-swift-for-webassembly-on-macos-with-swiftwasm-5d588a086120) if the docs look too verbose diff --git a/content/wasm-languages/tpl.md b/content/wasm-languages/tpl.md new file mode 100644 index 000000000..460ef21bb --- /dev/null +++ b/content/wasm-languages/tpl.md @@ -0,0 +1,84 @@ +# Create a Meaningful Title + +title = "Template Example" + +# Add Publish Date + +date = "2024-02-18T01:01:01Z" +description = "Python can be compiled to WebAssembly." +tags = ["language", "webassembly"] +template = "page_lang" + +# Remove Published + +published = false +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/tpl.md" + +--- + + + +## Available Implementations + + + +## Usage + + + +## Pros and Cons + + +Things we like: + +- + +We're neutral about: + +- + +Things we're not big fans of: + +- + +## Example + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + + + +## Learn More + +Here are some great resources: + + \ No newline at end of file diff --git a/content/wasm-languages/typescript.md b/content/wasm-languages/typescript.md new file mode 100644 index 000000000..643394cdf --- /dev/null +++ b/content/wasm-languages/typescript.md @@ -0,0 +1,22 @@ +date = "2024-02-18T01:01:01Z" +title = "Typescript in WebAssembly" +description = "TypeScript can be converted to JavaScript, and JS tools can be used to build Wasm binaries." +tags = ["typescript", "javascript", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/typescript.md" + +--- + +TypeScript is a popular language in its own right, but it is a very near relative of JavaScript. +In fact, most of the time, TS code is converted to JavaScript during the development cycle. +As such, the best approach to using TypeScript in WebAssembly is to convert it and [use JavaScript tools](/wasm-languages/javascript). + +Another potential solution is to [use AssemblyScript](/wasm-languages/assemblyscript), a subset of TypeScript tooled specifically for WebAssembly. + +## Learn More + +Here are some great resources: + +- A [detailed post](https://blog.bitsrc.io/typescript-to-webassembly-the-what-the-how-and-the-why-3916a2561d37) on moving from TypeScript to AssemblyScript \ No newline at end of file diff --git a/content/wasm-languages/webassembly-language-support.md b/content/wasm-languages/webassembly-language-support.md new file mode 100644 index 000000000..8efe66197 --- /dev/null +++ b/content/wasm-languages/webassembly-language-support.md @@ -0,0 +1,142 @@ +date = "2024-02-18T01:01:01Z" +title = "WebAssembly Language Support Matrix" +description = "Tracking the programming languages that compile to WebAssembly (Wasm). This page stays up to date with information about which languages can compile to Wasm, and what their language characteristics are." +template = "page" +tags = ["webassembly", "programming languages", "javascript", "python", "rust", "dotnet", "ruby"] +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/webassembly-language-support.md.md" + +--- + +This guide tracks support for compiling a language to WebAssembly. It is organized into three sections: Support for the top 20 languages, WebAssembly-specific languages, and other notable languages. We track whether the language can be compiled to run in the browser, in other non-browser environments, and in a [WASI](https://wasi.dev) environment. In the detail page for each language, we do our best to not only state the current level of support, but also point to an array of useful resources. + +## WebAssembly Support in Top 20 Languages + +This reports on the top 20 languages from [RedMonk's ranking](https://redmonk.com/sogrady/2022/03/28/language-rankings-1-22/). +Some languages, like CSS, PowerShell, and "Shell", don't really have a meaningful expression in Wasm. However, we have left them here for completeness. + +| Language | Core | Browser | WASI | Spin SDK | +|---------------------------| ----- | ------- | ---- | -------- | +| [JavaScript][JavaScript] | ✅ | ✅ | ✅ | ✅ | +| [Python][Python] | ✅ | ⏳ | ✅ | ✅ | +| [Java][Java] | ✅ | ✅ | ✅ | ⏳ | +| [PHP][PHP] | ✅ | ✅ | ✅ | ❌ | +| CSS | N/A | N/A | N/A | N/A | +| [C# and .NET][CSHARP] | ✅ | ✅ | ✅ | ✅ | +| [C++][CPLUSPLUS] | ✅ | ✅ | ✅ | ❌ | +| [TypeScript][TypeScript] | ✅ | ⏳ | ❌ | ✅ | +| [Ruby][Ruby] | ✅ | ✅ | ✅ | ❌ | +| [C][C] | ✅ | ✅ | ✅ | ❌ | +| [Swift][Swift] | ✅ | ✅ | ✅ | ⏳ | +| [R][R] | ❌ | ✅ | ❌ | ❌ | +| [Objective-C][ObjectiveC] | ? | ❌ | ❌ | ❌ | +| Shell | N/A | N/A | N/A | N/A | +| [Scala (JVM)][Scala] | ✅ | ✅ | ✅ | ⏳ | +| [Scala (native)][Scala] | ⏳ | ❌ | ❌ | ❌ | +| [Go][Go] | ✅ | ✅ | ✅ | ✅ | +| [PowerShell][PowerShell] | ❌ | ❌ | ❌ | ❌ | +| [Kotlin (JVM)][Kotlin] | ✅ | ✅ | ✅ | ⏳ | +| [Kotlin (Wasm)][Kotlin] | ⏳ | ✅ | ⏳ | ❌ | +| [Rust][Rust] | ✅ | ✅ | ✅ | ✅ | +| [Dart][Dart] | ❌ | ⏳ | ❌ | ❌ | + +* _Core_ means there is an implementation of WebAssembly 1.0 +* _Browser_ means there is at least one browser implementation +* _WASI_ means the language supports at least Preview 1 of the WASI proposal +* _Spin SDK_ indicates there is a Spin SDK for the language + +Anything with WASI or Spin SDK support runs on Fermyon Cloud, Spin, and Fermyon Platform. + +## WebAssembly Specific Languages + +| Language | Browser | CLI | WASI | Spin SDK | +| -------------------------------- | ------- | --- | ---- | -------- | +| [AssemblyScript][AssemblyScript] | ✅ | ✅ | ✅ | ❌ | +| [Grain][Grain] | ✅ | ✅ | ✅ | ❌ | +| [Motoko][Motoko] | ✅ | ✅ | ✅ | ❌ | + +* _Browser_ means there is at least one browser implementation +* _CLI_ means the language has a CLI runtime mode +* _WASI_ means the language supports at least Preview 1 of the WASI proposal +* _Spin SDK_ indicates there is a Spin SDK for the language + +## Other Notable Languages + +These languages enjoy broad use (though perhaps not in the top 20) and have at least some degree of WebAssembly Support + +| Language | Browser | CLI | WASI | Spin SDK | +| ------------------------- | ------- | --- | ---- | -------- | +| [Clojure][Clojure] | ✅ | ✅ | ✅ | ⏳ | +| [COBOL][Cobol] | ⏳ | ✅ | ⏳ | ❌ | +| [Erlang (BEAM)][Erlang] | ⏳ | ⏳ | ⏳ | ❌ | +| [Haskell][Haskell] | ✅ | ✅ | ✅ | ❌ | +| [Lisp][Lisp] | ⏳ | ⏳ | ⏳ | ❌ | +| [Lua][Lua] | ✅ | ❌ | ❌ | ❌ | +| [Perl][Perl] | ✅ | ❌ | ❌ | ❌ | +| [Prolog][Prolog] | ✅ | ❌ | ❌ | ✅ | +| [Zig][Zig] | ✅ | ✅ | ✅ | ❌ | + +* _Browser_ means there is at least one browser implementation +* _CLI_ means the language has a CLI runtime mode +* _WASI_ means the language supports at least Preview 1 of the WASI proposal +* _Spin SDK_ indicates there is a Spin SDK for the language + +## How To Read These Charts + +For each environment, we use the following icons to indicate a level of support: + +- ✅ Usable +- ⏳ In progress +- ❌ Not implemented +- `N/A` Not applicable + +Spin, Fermyon Platform and Fermyon Cloud require [WASI](https://wasi.dev) support. Any language that has a ✅ for WASI should be supported on the Fermyon Platform. The *Spin SDK* indicates that there is additional libraries available for Spin. + +We are often asked which languages are best supported for production-grade WebAssembly. We suggest [C][C]/[C++][CPLUSPLUS], [Rust][Rust], and [AssemblyScript][AssemblyScript]. + +## Updates and Additions + +The source for the WebAssembly Language Guide is located in a [public GitHub project](https://github.com/fermyon/developer/wasm-languages). If you find errors, want to make additions, or have further corrections for us, the [issue queue](https://github.com/fermyon/developer/issues) is a great place to discuss. + +If you're more interested in chatting about things, check out our [Discord server](https://discord.gg/AAFNfS7NGf) or hit us up a [@FermyonTech on Twitter](https://twitter.com/fermyontech) + +## Relevant Standards + +Throughout our pages, we talk about technologies like WASI, Wagi, and Spin. Many of these are backed by formal documents. See the [Standards] page for links to the relevant texts along with helpful resources. + +[JavaScript]: /wasm-languages/javascript +[Python]: /wasm-languages/python +[Java]: /wasm-languages/java +[PHP]: /wasm-languages/php +[CPLUSPLUS]: /wasm-languages/cpp +[CSHARP]: /wasm-languages/c-sharp +[TypeScript]: /wasm-languages/typescript +[Ruby]: /wasm-languages/ruby +[C]: /wasm-languages/c-lang +[Swift]: /wasm-languages/swift +[R]: /wasm-languages/r-lang +[ObjectiveC]: /wasm-languages/objective-c +[Shell]: /wasm-languages/shell +[Scala]: /wasm-languages/scala +[Go]: /wasm-languages/go-lang +[PowerShell]: /wasm-languages/powershell +[Kotlin]: /wasm-languages/kotlin +[Rust]: /wasm-languages/rust +[Dart]: /wasm-languages/dart + +[AssemblyScript]: /wasm-languages/assemblyscript +[Grain]: /wasm-languages/grain +[Motoko]: /wasm-languages/motoko + +[Cobol]: /wasm-languages/cobol +[Clojure]: /wasm-languages/clojure +[Erlang]: /wasm-languages/erlang-beam +[Haskell]: /wasm-languages/haskell +[Lisp]: /wasm-languages/lisp +[Lua]: /wasm-languages/lua +[perl]: /wasm-languages/perl +[prolog]: /wasm-languages/prolog +[Zig]: /wasm-languages/zig + +[Standards]: /wasm-languages/standards diff --git a/content/wasm-languages/zig.md b/content/wasm-languages/zig.md new file mode 100644 index 000000000..1911bdd5b --- /dev/null +++ b/content/wasm-languages/zig.md @@ -0,0 +1,111 @@ +date = "2024-02-18T01:01:01Z" +title = "Zig in WebAssembly" +description = "Zig can be compiled to WebAssembly." +tags = ["zig", "webassembly"] +template = "page_lang" +[extra] +author = "Fermyon Staff" +url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/zig.md" + +--- + +Zig, a systems language, has official support for WebAssembly. +Zig's implementation uses LLVM to supply the compile target. + +## Available Implementations + +Zig's official implementation [supports WebAssembly](https://ziglang.org/download/0.4.0/release-notes.html#WebAssembly-Support). + +## Usage + +LLVM has a `wasm32-wasi` target, so Zig should be usable to build Fermyon Platform applications. +It can also be used in the browser. + +For the most part, write your Zig code as usual. When compiling, use the target `wasm32-wasi`. + +## Pros and Cons + +Things we like: + +- The Zig compiler is so nice, we now use it to compile our C as well as our Zig. + +Things we're not big fans of: + +- When we get Wasm-related errors, they can be really terse. + +## Example + +>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples). + +You must have [Zig](https://ziglang.org/learn/) installed. + +Create a new Zig program: + +```console +$ mkdir hello-zig +$ cd hello-zig +$ zig init-exe +``` + +Inside of the `src/` directory is a file named `main.zig`. Edit it as follows: + +```zig +const std = @import("std"); + +pub fn main() !void { + const stdout = std.io.getStdOut().writer(); + try stdout.print("content-type: text/plain\n\n", .{}); + try stdout.print("Hello, World!\n", .{}); +} +``` + +Now compile the program: + +```console +zig build-exe -O ReleaseSmall -target wasm32-wasi src/main.zig +``` + +You can verify that it runs using `wasmtime`: + +```console +$ wasmtime main.wasm +content-type: text/plain + +Hello +``` + +Now you should have a `main.wasm` file. Create a `spin.toml` file to load the Zig program: + +```toml +spin_version = "1" +authors = ["Fermyon Engineering "] +description = "A Spin example HTTP application for Zig." +name = "spin-hello-zig" +trigger = { type = "http", base = "/" } +version = "1.0.0" + +[[component]] +source = "main.wasm" +id = "zig-hello" +[component.trigger] +route = "/zig-hello" +executor = { type = "wagi" } # Note: We are running this using the Wagi spec +``` + +Run `spin up` and then use `curl` or a web browser to send a request: + +```curl localhost:3000/zig-hello +Hello, World! +``` + +## Learn More + +Here are some great resources: + +## Learn More + +Here are some great resources: + +- The official [release notes](https://ziglang.org/download/0.4.0/release-notes.html#WebAssembly-Support) on WebAssembly support in Zig +- An example repo that shows how to [access the browser DOM](https://github.com/shritesh/zig-wasm-dom) in Zig +- A [short video](https://youtu.be/gJLIiF15wjQ) on Zig \ No newline at end of file diff --git a/spin.toml b/spin.toml index 042dee46e..2a241df43 100644 --- a/spin.toml +++ b/spin.toml @@ -154,6 +154,11 @@ id = "trigger-bartholomew-spin-v2" component = "bartholomew-spin-v2" route = "/spin/v2/..." +[[trigger.http]] +id = "trigger-redirect-wasm-langs-root" +component = "redirect-wasm-langs-root" +route = "/wasm-languages/" + [component.bartholomew] # Using build from bartholomew main source = "modules/bartholomew.wasm" @@ -291,6 +296,11 @@ environment = { DESTINATION = "https://developer.fermyon.com/spin/ai-sentiment-a source = "modules/redirect.wasm" environment = { DESTINATION = "https://developer.fermyon.com/spin/serverless-ai-hello-world.md" } +# Redirect /wasm-languages to /wasm-languages/webassembly-language-support +[component.redirect-wasm-langs-root] +source = "modules/redirect.wasm" +environment = { DESTINATION = "/wasm-languages/webassembly-language-support" } + # Component to give us clean versioned URLs for spin from the root [component.spin-version-proxy] source = "modules/spin-redirecter.wasm" diff --git a/templates/cloud_sidebar.hbs b/templates/cloud_sidebar.hbs index 589af9b9e..77f700a79 100644 --- a/templates/cloud_sidebar.hbs +++ b/templates/cloud_sidebar.hbs @@ -97,6 +97,9 @@ Command Reference
  • Changelog
  • +
  • WebAssembly Language Support Matrix +
  • diff --git a/templates/page.hbs b/templates/page.hbs new file mode 100644 index 000000000..c62daac31 --- /dev/null +++ b/templates/page.hbs @@ -0,0 +1,24 @@ +{{! This adds the HTML head section and the beginning of the body. See content_top.hbs. }} +{{> content_top }} + +
    +
    + +
    +
    +

    {{{page.head.title}}}

    + {{! Since this is HTML, we use the triple-curly }} + {{{page.body}}} + {{! Remove the `!` on the line below to see how to call a Rhai script }} + {{! echo "world" }} +
    +
    + +
    +
    + +{{! This closes the body. See content_bottom.hbs. }} + +{{> content_cta }} + +{{> content_bottom }} \ No newline at end of file diff --git a/templates/page_lang.hbs b/templates/page_lang.hbs new file mode 100644 index 000000000..e2b1f7c55 --- /dev/null +++ b/templates/page_lang.hbs @@ -0,0 +1,57 @@ +{{! This adds the HTML head section and the beginning of the body. See content_top.hbs. }} +{{> content_top }} + +
    +
    + + {{! This adds the sidebar }} + + +
    +
    + {{! This adds an archival notice - needs to styled }} + {{#if (active_project request.spin-full-url "/spin/v1" )}} +
    This page refers to an older version of Spin. Go to the + latest version.
    + {{/if}} +

    {{page.head.title}}

    + + + + {{{page.body}}} + +
    + {{> doc_feedback }} +
    + +
    + + {{> content_footer }} +
    + +
    + {{> doc_feedback }} +
    + + +{{! This closes the body. See content_bottom.hbs. }} +{{> content_bottom }} + + + + \ No newline at end of file diff --git a/templates/spin_sidebar.hbs b/templates/spin_sidebar.hbs index 0748361f5..a482a1e62 100644 --- a/templates/spin_sidebar.hbs +++ b/templates/spin_sidebar.hbs @@ -195,6 +195,9 @@ Manifest Reference +
  • WebAssembly Language Support Matrix +
  • diff --git a/templates/spin_sidebar_v2.hbs b/templates/spin_sidebar_v2.hbs index ce41a1a8c..67bc4b240 100644 --- a/templates/spin_sidebar_v2.hbs +++ b/templates/spin_sidebar_v2.hbs @@ -202,6 +202,9 @@ Manifest Reference +
  • WebAssembly Language Support Matrix +