# AssemblyScript: a TypeScript-like language for WebAssembly, and when it is the right compiler

> AssemblyScript compiles a typed subset of TypeScript to WebAssembly through Binaryen, with an npm install as the entry point. It suits JavaScript-side teams that need a small wasm module, and it is the wrong tool when you need the full TypeScript type system or the Rust and C++ ecosystem.

**AssemblyScript/assemblyscript** — A TypeScript-like language for WebAssembly.

- Repository: https://github.com/AssemblyScript/assemblyscript
- Website: https://www.assemblyscript.org
- Stars: 18,027 · Forks: 690
- Language: WebAssembly
- License: Apache-2.0
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/assemblyscript-assemblyscript

## The gap AssemblyScript fills: typed source that becomes a wasm module

WebAssembly gives you a portable binary format, but writing it by hand is not practical. The usual route is Rust or C++ with a wasm target, which means a second toolchain, a second build system and a second set of language skills in a JavaScript codebase. AssemblyScript takes the other route. The README describes it as compiling "a variant of TypeScript (basically JavaScript with types) to WebAssembly using Binaryen", and it presents the whole thing as being "just an npm install away".

That sentence is the product. The compiler is distributed as the npm package assemblyscript, the CLI binaries are asc and asinit, and the output is a .wasm module you load the same way you load any other wasm file. Nothing about the runtime requires Node.js: the module runs in browsers, in Node.js, or inside a WASI host, provided the host supplies the imports the module declares.

The audience is therefore narrow and specific. It is for teams whose source of truth is already TypeScript and who want a compiled module for a hot path, a parser, a codec, a math kernel, an image filter. It is not for people who want to run their existing TypeScript application inside a wasm sandbox. The compiler accepts a subset, and the README points readers to the language documentation rather than claiming full compatibility.

## How the compiler pipeline works, from .ts entry file to binary

The package.json names the moving parts. The runtime dependency is binaryen at version 131.0.0-nightly.20260721, plus long for 64-bit integer handling. Binaryen is the WebAssembly toolchain that does the actual code generation and optimisation; AssemblyScript is the front end that parses a TypeScript-like language and lowers it into Binaryen's intermediate representation.

The repository layout reflects that split. src holds the compiler, std holds the standard library that ships with the language, lib wraps Binaryen, and cli and bin expose the command line. The std directory is not incidental: AssemblyScript programs do not get JavaScript's built-in objects. There is no Array.prototype.map, no JSON, no console, no Math object in the JavaScript sense. Those come from the standard library as explicit imports, and the runtime that backs them lives under std/assembly/rt.

That design is what makes the output small. A JavaScript engine carries its object model, garbage collector and built-ins into every program. An AssemblyScript module carries only what it references, and the runtime pieces it needs are linked in from the standard library. The trade-off is symmetric: you get a lean module, and you give up the ambient environment that TypeScript programmers take for granted.

## Installing AssemblyScript and compiling a first module

The README's development instructions clone the repository and link it globally, but that path is for working on the compiler itself. For using it, the project's getting-started page is the canonical walkthrough, and the README links to it alongside the examples page. The CLI binaries declared in package.json are asc and asinit, and the package is published as assemblyscript.

A development environment, according to the README, is set up by cloning the repository and installing its dependencies:

```sh
git clone https://github.com/AssemblyScript/assemblyscript.git
cd assemblyscript
npm install
npm link
```

The README notes that the link step is optional and makes the development instance available globally. For the compiler's own development, the README points to the compiler instructions under src, the runtime instructions under std/assembly/rt, and the test instructions under tests. The README does not document a separate scaffolding command, a starter template or an output layout, so the getting-started page is where the first-project walkthrough lives.

What you should expect from the published compiler is a .wasm artifact whose size depends on what the module references, not on the size of the compiler, because the standard library links in only the pieces the program uses. If a compile fails, the error will point at a type the compiler does not accept, which is the normal first encounter with the subset.

## The type system is TypeScript-shaped, not TypeScript

The most common misconception about AssemblyScript is that it is TypeScript with a different backend. It is not. The compiler accepts a variant, and the variant is stricter about representation because every value has to fit a WebAssembly type. A number in AssemblyScript is not a double by default the way it is in JavaScript, and the types the compiler accepts are the ones that map onto machine representations.

This shows up in places that surprise people. Structural typing, declaration merging, conditional types and the rest of TypeScript's type-level programming are not part of the language. Dynamic property access on arbitrary objects does not translate, because there is no dynamic object model to translate it into. Libraries written for JavaScript cannot simply be imported, since they depend on built-ins that do not exist here.

The compiler is honest about this rather than pretending otherwise. It rejects what it cannot represent, which means porting an existing TypeScript file is usually a rewrite of the parts that touch objects, strings and arrays, not a recompile. Teams that plan for that do fine. Teams that expect a flag to make their application compile to wasm will spend the first day discovering the boundary.

## Where AssemblyScript is the wrong choice

If your goal is maximum runtime performance on a numerically heavy workload, Rust and C++ remain the safer bet. They have mature optimisers, decades of numeric libraries, and a large body of published work on wasm code generation. AssemblyScript's optimiser is Binaryen, which is the same backend used by other toolchains, but the front end offers fewer guarantees to the optimiser and the surrounding library ecosystem is far smaller. Choosing AssemblyScript for a compute kernel that has an existing Rust implementation is usually a step backwards.

If your goal is to reuse an existing TypeScript codebase, this is also the wrong tool. The subset boundary described above means the reuse is partial at best, and the parts that fail are exactly the parts that make application code application code: object graphs, dynamic dispatch, string manipulation through JavaScript APIs.

There is a third case worth naming. AssemblyScript modules are not sandboxed from the host in any special way beyond what WebAssembly itself provides. If you need the module to call back into JavaScript frequently, the boundary crossing has a cost, and a design that crosses it per element rather than per batch will not benefit from being compiled at all. The documentation does not present AssemblyScript as a general application runtime, and it should not be read that way.

## AssemblyScript compared with Rust and with plain TypeScript

Against Rust, the difference is not only language. Rust brings cargo, crates.io, wasm-bindgen for host interop, and a compiler that will refuse to build code with data races. AssemblyScript brings npm, a TypeScript-shaped syntax, and a standard library that is part of the compiler distribution. For a team already inside npm, the AssemblyScript path has fewer new concepts. For a team that needs an existing crate, the Rust path has no equivalent here.

Against plain TypeScript, the difference is the execution model. TypeScript is erased at runtime; what runs is JavaScript, interpreted or JIT-compiled by the engine, with the full object model available. AssemblyScript produces a binary that runs in a wasm engine with a small explicit runtime. You gain predictable startup, a smaller artifact and a sandbox boundary. You lose every JavaScript API and the ability to import arbitrary npm packages.

The honest summary is that AssemblyScript trades ecosystem for fit. It fits a JavaScript team that needs one compiled module. It does not fit a team that needs a compiled application.

## Maintenance, releases and the Apache-2.0 licence

The repository is not archived, and the last push was on 2026-09-14. Recent releases are v0.28.18 on 2026-06-02, v0.28.19 on 2026-06-12 and v0.28.20 on 2026-07-22, so the release cadence is roughly monthly and the version line is still 0.28.x. The leading zero matters for planning: a 0.x version line is not a stability promise, and minor releases can carry changes that require source edits.

That is the real upgrade cost. Because the language is a subset with its own standard library, an upgrade can change how a built-in behaves or how a type is accepted, and the fix is in your source rather than in a configuration file. Pinning the compiler version in package.json and reading the release notes before moving is the practical mitigation. The package.json engines field requires Node.js 20 or newer and npm 10 or newer, with engineStrict set, so the compiler will refuse to install on older Node.js rather than fail later.

The licence is Apache-2.0, which permits commercial and closed-source use and includes an explicit patent grant. The repository also carries a NOTICE file, and Apache-2.0 expects that notice to be preserved in distributions. Whether that obligation applies to your shipped .wasm artifact depends on your situation, and it is worth a lawyer's five minutes rather than an assumption.

## Conclusion

Adopt AssemblyScript when the team already writes TypeScript, the module is small and numeric, and the build should stay inside npm. Do not adopt it as a drop-in TypeScript replacement: the type system is narrower, the standard library replaces JavaScript globals, and the ecosystem is thin compared with Rust or C++. Before committing, run asc on your own entry file and check which of your library imports survive the compile, because the compiler only accepts what its own type definitions allow.

## FAQ

### What are the key differences between TypeScript and AssemblyScript?

AssemblyScript compiles a variant of TypeScript to WebAssembly using Binaryen, while TypeScript is erased at runtime and executes as JavaScript. The AssemblyScript type system is narrower and maps values onto WebAssembly types, and programs use the bundled standard library instead of JavaScript built-ins.

### What is AssemblyScript?

It is a compiler and language that accepts a TypeScript-like syntax and emits WebAssembly modules. The README describes it as compiling a variant of TypeScript to WebAssembly using Binaryen, distributed as an npm package.

### Is AssemblyScript dead?

The repository is not archived, the last push was on 2026-09-14, and the most recent release listed is v0.28.20 from 2026-07-22. The version line is still 0.28.x, so the project has not reached a 1.0 release.

### How does AssemblyScript compare with Rust for WebAssembly?

Both can produce WebAssembly, but the surrounding ecosystems differ. Rust brings cargo and crates.io, while AssemblyScript installs through npm and ships its standard library with the compiler. For numerically heavy work with existing Rust libraries, the Rust path has no equivalent in AssemblyScript.

### How does AssemblyScript compare with TypeScript in performance?

The two do not run the same way: TypeScript is erased and executes as JavaScript in an engine, while AssemblyScript produces a WebAssembly binary with a small explicit runtime. The compiler accepts a narrower type system, so the comparison is between a wasm module and a JavaScript program rather than between two builds of the same source.

### Does AssemblyScript work with a WebAssembly System Interface host?

The README says a module runs wherever the host supplies the imports it declares, and the compiler targets WebAssembly through Binaryen. The README does not document a WASI-specific build mode or flag, so the getting-started and language documentation are where that would be confirmed.

## Sources

- [AssemblyScript/assemblyscript on GitHub](https://github.com/AssemblyScript/assemblyscript)
- [License: Apache-2.0](https://github.com/AssemblyScript/assemblyscript/blob/main/LICENSE)
- [Project website](https://www.assemblyscript.org)
- [README](https://github.com/AssemblyScript/assemblyscript/blob/main/README.md)
- [Releases](https://github.com/AssemblyScript/assemblyscript/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/assemblyscript-assemblyscript
