# WebAssembly

> Run an Alice program in the browser: create a wasm package, build a static site, and call between Alice and JavaScript with JSExport and JSImport.

Canonical: https://alice-lang.org/documentation/guides/webassembly/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

Since 0.13.2, an Alice package can target the browser. .NET compiles to WebAssembly, and Alice sets up the
project for you: no hand-written project file and no extra workload.

## Create and run

```bash
alice new web --wasm     # src/main.al, wwwroot/index.html, wwwroot/main.js
cd web
alice run                # builds, then runs the bundle under Node
alice build --release    # dist/wwwroot: the whole static site
```

`alice run` uses Node, which hosts the same .NET WebAssembly runtime as the browser. To see the page, serve
`dist/wwwroot` with any static web server and open it.

In `alice.toml`, the kind is all that changes:

```toml
[package]
name = "web"
kind = "wasm"
```

## Call Alice from JavaScript

Mark a method `@[JSExport]`:

```ruby
using System.Runtime.InteropServices.JavaScript

module App
  @[JSExport]
  def self.greet(who : String) : String
    "Hello, #{who}!"
  end
end

puts "web is running in WebAssembly"
```

The generated `wwwroot/main.js` boots the runtime, calls the export, then runs the program's top level:

```js
import { dotnet } from './_framework/dotnet.js';

const { getAssemblyExports, getConfig, runMain } = await dotnet.create();
const app = await getAssemblyExports(getConfig().mainAssemblyName);
document.getElementById('out').textContent = app.App.greet('browser');
await runMain();
```

## Call JavaScript from Alice

Declare a `partial def` with `@[JSImport]`, naming the JavaScript function:

```ruby
module App
  @[JSImport("globalThis.console.log")]
  partial def self.log(msg : String) : Nil
end
```

## Size and limits

- Release sites are trimmed: a hello world is about 2 MB over the wire with Brotli.
- `[runtime] globalization = "invariant"` drops the ICU locale data (about 2.5 MB uncompressed).
- Everything in `wwwroot/` is copied to the site root.
- The browser has no threads, files or native libraries: `par for` and `par` forks run serially, `gpu for` and
  `lib`/`fun` imports are not available, and `@[Native]` functions use their managed fallback.

## Continue reading

- Previous: [GPU loops](https://alice-lang.org/documentation/guides/gpu.md)
- Next: [Memory and value semantics](https://alice-lang.org/documentation/advanced/memory.md)
