Skip to content

AssemblyScript

AssemblyScript is a compiler that turns a strict subset of TypeScript into WebAssembly. If you already know TypeScript, you can be productive in AssemblyScript in minutes. There is no Rust borrow checker, no C memory management — just typed TypeScript with a few Wasm-specific annotations.

Terminal window
# Create a new Node.js project
mkdir as-demo && cd as-demo
npm init -y
# Install the AssemblyScript compiler
npm install --save-dev assemblyscript
# Scaffold the project (creates assembly/ and tsconfig.json)
npx asinit .

The assembly/ directory holds your .ts source files. asconfig.json configures the compiler.

Open assembly/index.ts:

// Integer addition — notice the explicit i32 types
export function add(a: i32, b: i32): i32 {
return a + b;
}
// Factorial — recursive, i64 to avoid overflow for larger inputs
export function factorial(n: i64): i64 {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
// Clamp a float value between lo and hi
export function clamp(value: f64, lo: f64, hi: f64): f64 {
if (value < lo) return lo;
if (value > hi) return hi;
return value;
}

Key differences from regular TypeScript:

  • Types like i32, i64, f32, f64 are Wasm-native numeric types, not TypeScript’s number.
  • There is no any, no unknown, and no implicit type coercion.
  • export makes functions accessible from JavaScript (same as WAT’s (export ...)).
Terminal window
# Development build (readable, not optimised)
npx asc assembly/index.ts --outFile build/release.wasm --textFile build/release.wat
# Release build (optimised, smaller binary)
npx asc assembly/index.ts --outFile build/release.wasm --optimize
# With bindings for use as an ES module
npx asc assembly/index.ts --outFile build/release.wasm --bindings esm
// Using the @assemblyscript/loader helper
import { instantiateStreaming } from '@assemblyscript/loader';
const { exports } = await instantiateStreaming(fetch('./build/release.wasm'));
console.log(exports.add(10, 32)); // 42
console.log(exports.factorial(BigInt(10))); // 3628800n (i64 → BigInt)
console.log(exports.clamp(1.5, 0.0, 1.0)); // 1

Or use the WebAssembly API directly without the loader:

const response = await fetch('./build/release.wasm');
const bytes = await response.arrayBuffer();
const { instance } = await WebAssembly.instantiate(bytes, {});
console.log(instance.exports.add(3, 4)); // 7

The editor below opens a live AssemblyScript project in StackBlitz where you can edit, compile, and run the code directly in your browser.

AssemblyScript

Needs the AssemblyScript toolchain — open in StackBlitz to build & run.

Which numeric type does AssemblyScript use for a 32-bit integer?
How do you make an AssemblyScript function callable from JavaScript?
What does 'npx asinit .' do when scaffolding an AssemblyScript project?
Why does AssemblyScript produce small Wasm binaries?