AssemblyScript
A TypeScript-like language that compiles directly to WebAssembly, bringing near-native performance to the web without leaving the npm ecosystem.
Created by Daniel Wirtz (dcodeIO)
AssemblyScript is a statically typed, compiled language whose syntax closely mirrors TypeScript, targeting WebAssembly as its output format. Rather than transpiling to JavaScript like TypeScript does, AssemblyScript compiles ahead-of-time to .wasm binary modules that run directly in the WebAssembly virtual machine. This unique positioning makes it the most accessible on-ramp to WebAssembly for the millions of developers already familiar with TypeScript.
History & Origins
AssemblyScript was created in 2017 by Daniel Wirtz, known in the open-source community by his GitHub handle dcodeIO. The first public release, v0.1.0, appeared on npm in July 2017. Wirtz’s stated motivation was pragmatic: he wanted “something you can npm install to compile to WebAssembly instead of installing and setting up more complex tool chains.” At the time, the main paths to WebAssembly required learning C, C++, or Rust — languages with steep learning curves and unfamiliar ecosystems.
The timing was significant. WebAssembly had only received cross-browser support in 2017 (all four major browsers shipped it that year), and the community was actively exploring what languages and toolchains could target the new format. AssemblyScript entered that space with a radical premise: what if the type annotations that TypeScript developers already wrote could be used — with minimal modification — to generate native WebAssembly?
The project grew organically from an open-source experiment into a community effort. Over subsequent years it attracted meaningful organizational backing from Shopify (which began using it in 2019), Fastly (which announced edge computing support in 2020), NEAR Protocol (which granted funding in Q1 2021), and The Graph Protocol. As of late 2024, the project had reportedly raised over $250,000 via OpenCollective from approximately 98 sponsors, including a reported $830 donation from Alon Zakai, the creator of Emscripten.
Design Philosophy
AssemblyScript’s design is driven by a central tension: the language must be familiar enough for TypeScript developers to adopt without a steep learning curve, yet it must expose the actual machine-level type system that WebAssembly provides. TypeScript’s type system exists only at compile time and erases to JavaScript’s single number type at runtime. WebAssembly, by contrast, has distinct 32-bit and 64-bit integer and floating-point types.
The official documentation describes AssemblyScript as “part a subset, part a superset — a variant” of TypeScript. It is not a TypeScript compiler producing WebAssembly output; it is a distinct language that borrows TypeScript’s surface syntax and tooling ecosystem while building a different semantic model underneath.
This design choice has real benefits:
- Developers can author AssemblyScript in any TypeScript-aware editor with syntax highlighting, autocomplete, and error feedback
- The mental model transfers: classes, generics, interfaces, decorators — all look familiar
- The
npmecosystem is the delivery mechanism, so no new package manager is required
But the limitations are deliberate too. Features that cannot map cleanly to WebAssembly’s current capabilities — closures, dynamic property access, reflection, async/await, try-catch — are either unsupported or not yet implemented pending WebAssembly standards proposals.
Key Features
WebAssembly-Native Type System
AssemblyScript exposes WebAssembly’s native primitive types directly, rather than abstracting them away:
| Type | Description |
|---|---|
i32 / u32 | 32-bit signed/unsigned integer |
i64 / u64 | 64-bit signed/unsigned integer |
i8, u8, i16, u16 | Smaller integer types |
f32 | 32-bit IEEE 754 float |
f64 | 64-bit IEEE 754 float (equivalent to JS number) |
isize / usize | Platform pointer-width integer |
v128 | 128-bit SIMD vector type |
bool | Boolean |
This differs sharply from TypeScript, where number covers all numeric cases. In AssemblyScript, choosing the right numeric type is the developer’s responsibility and has direct performance implications.
| |
Generics as Monomorphized Templates
AssemblyScript supports generic functions and classes, but implements them as monomorphized templates — each unique instantiation generates specialized code — rather than the type-erased generics of Java or TypeScript. This is more similar to C++ templates or Rust generics.
| |
Memory Management and Runtime Flavors
Unlike TypeScript (which relies entirely on JavaScript’s garbage collector), AssemblyScript modules bring their own memory management. Developers choose a runtime flavor at compile time:
incremental(default): TLSF allocator with incremental garbage collection — suitable for most applicationsminimal: TLSF allocator with a lightweight, manually-invoked GC — for performance-sensitive use casesstub: Bump allocator that never frees memory — appropriate for short-lived modulesnone: No runtime at all — the developer manually manages memory viamemory.allocate()andmemory.free()
This explicit control is valuable for performance tuning and for environments where predictable memory behavior is critical.
Decorators as Compiler Annotations
AssemblyScript uses TypeScript-style decorators as compiler directives rather than runtime metadata:
| |
Standard Library
AssemblyScript provides a standard library that mirrors JavaScript APIs where practical:
Math— standard mathematical functionsArray<T>,TypedArrayvariants — typed arrays with familiar APIString— WTF-16 encoded strings (matching JavaScript’s string semantics for Web interop)Map<K,V>,Set<T>— standard collection typesInt8Array,Uint8Array,Float64Array, etc. — typed array views
Notably absent are JSON, RegExp, and the Date API — these are too dynamic or platform-dependent for AOT compilation. Community packages fill some of these gaps.
How It Compiles
The AssemblyScript compiler (asc) uses Binaryen — the WebAssembly compiler infrastructure maintained by the WebAssembly project — as its backend optimizer. The compilation pipeline:
- Source
.tsfiles are parsed into an abstract syntax tree - Type checking and program initialization occur
- The AST is lowered to Binaryen’s internal IR
- Binaryen optimization passes run (controlled by
-O0through-O3, or-Os/-Ozfor size) - The final
.wasmbinary is emitted, along with optional.wattext format, JavaScript glue code, and TypeScript type definitions
A typical project setup looks like:
| |
The asinit tool creates the recommended project structure: an assembly/ directory for AssemblyScript source, a build/ directory for compiled output, and configuration files for both the compiler and test runner.
What AssemblyScript Is Not
It is worth being explicit about AssemblyScript’s limitations, since they shape where the language is appropriate:
- No closures (functions capturing local variables) — pending WebAssembly GC and Function References proposals
- No
async/await— WebAssembly has no event loop - No
try-catchexceptions — throwing aborts the module - No union types like
string | number— only nullable references (T | null) - No
any,undefined, dynamic dispatch — the type system is strict - No iterators or
for...ofloops on custom objects - No
BigInt— use nativei64/u64instead
These are not design oversights; they reflect the underlying constraints of WebAssembly as a compilation target. Many of these limitations are expected to be lifted as WebAssembly standards evolve.
Performance Characteristics
AssemblyScript’s performance relative to JavaScript is highly context-dependent. The most credible published benchmarks show mixed results:
In a 2021 study by Surma (published on surma.dev), image processing benchmarks showed AssemblyScript with the -O3 speed-optimization flag running approximately 14% faster than equivalent JavaScript. However, with the size-optimization flag (-O3s), the same workload ran approximately 56% slower — results varied significantly based on compiler flags. Additionally, data-structure-heavy algorithms (binary heap operations) showed JavaScript significantly outperforming AssemblyScript due to memory allocation patterns.
A sort benchmark published by Ecostack.dev comparing WebAssembly languages in Chrome found AssemblyScript slower than both Rust/Wasm and native JavaScript for array sorting workloads, while producing significantly smaller output: approximately 4.7 KB versus 74 KB for an equivalent Rust module.
Benchmarks specifically measuring the JavaScript-to-WebAssembly function call overhead (the FFI boundary cost) show that AssemblyScript performs worse than JavaScript for fine-grained, high-frequency calls due to marshaling overhead.
The practical conclusion is that AssemblyScript delivers meaningful performance advantages for computation-intensive workloads that process data locally within the module — image processing, hashing, numerical computation, data segmentation. It offers less benefit — or can be slower — for tasks that require frequent data exchange with JavaScript, or for workloads where JavaScript’s JIT compiler already performs well.
Relationship to the WebAssembly Ecosystem
AssemblyScript occupies a distinct position among languages that compile to WebAssembly:
| Language | Learning Curve | Output Size | Ecosystem | Primary Use Case |
|---|---|---|---|---|
| AssemblyScript | Low (TypeScript-like) | Small | npm | Web/JS integration |
| Rust | High | Medium | cargo | Systems, performance-critical |
| C/C++ (via Emscripten) | High | Large | existing | Porting existing codebases |
| TinyGo | Medium | Small | go modules | Embedded, scripts |
AssemblyScript’s niche is specifically the web developer who wants WebAssembly output without adopting a new language ecosystem. It produces smaller binaries than Rust for most tasks and integrates naturally with bundlers like webpack and Vite.
Current State and Community
As of early 2026, AssemblyScript is under active development, with nine releases shipped in 2025 alone, the latest being v0.28.9 (October 2025). The project remains in the 0.x version series — no 1.0 release has been announced — accurately signaling that the team considers the language still maturing. Breaking changes between minor versions (e.g., 0.18 to 0.19) have occurred as the compiler evolves.
The project has approximately 17,000 or more GitHub stars and is used by over 29,000 GitHub projects. Weekly npm downloads are in the range of 50,000–68,000. The most active production foothold is in the blockchain/Web3 space through The Graph Protocol, which has made AssemblyScript a required language for subgraph development, and the NEAR Protocol smart contract ecosystem.
Shopify’s ongoing contributions — including work on a language server and progress toward closure support — suggest the language has backing from a major production user committed to improving its capabilities. The single most anticipated feature, closure support, awaits upstream progress in the WebAssembly standards process.
Why AssemblyScript Matters
AssemblyScript represents an important experiment: can a language designed entirely around a compilation target — rather than evolved for general computation — achieve the usability of a high-level language while retaining low-level performance guarantees? Its TypeScript syntax is not accidental; it is a deliberate bid to lower the barrier to WebAssembly adoption for the web’s largest developer community.
Whether it achieves mainstream status depends on how WebAssembly itself evolves. Each new WebAssembly proposal — GC, function references, SIMD, threads — potentially unlocks new language features for AssemblyScript. The language is, in a meaningful sense, a living benchmark of WebAssembly’s current capabilities.
For developers targeting compute-intensive web tasks, edge computing, or cross-platform SDK portability, AssemblyScript offers a path that no other language currently provides: WebAssembly output from a TypeScript-familiar syntax, installable with a single npm install.
Timeline
Notable Uses & Legacy
The Graph Protocol
The decentralized blockchain indexing protocol requires developers to write subgraph data mapping logic in AssemblyScript, making it one of the largest ecosystems built on the language.
webpack
The popular JavaScript bundler uses AssemblyScript-compiled WebAssembly modules for its xxhash64 and MD4 hash implementations, eliminating native binary dependencies in the build pipeline.
DevCycle
The feature flag platform rewrote its core TypeScript bucketing and segmentation library in AssemblyScript; the resulting WASM module now powers their Cloudflare Workers API and multiple server-side SDKs.
NEAR Protocol
The proof-of-stake blockchain platform provided an official AssemblyScript SDK (near-sdk-as) for writing smart contracts, and has been the project's largest financial backer.
Shopify
Shopify has used AssemblyScript internally since 2019, contributed a language server implementation, made progress on closure support, and donated $25,000 to the project's open collective.