README.md

typestrip #

A TypeScript type stripper in a small, dependency-free WebAssembly module.

typestrip erases types the way ts-blank-space and Node's type stripping do. Every JavaScript character stays where it was, so the output needs no source map. It streams, so memory stays flat at any input size. The engine is written in Zena and compiled to WasmGC with zero imports. It is 13.6 kB gzipped.

import { transform, transformSync } from "@nibling/typestrip";

await transform("let x: number = 1;"); // "let x         = 1;"
transformSync("let x: number = 1;"); // the same, synchronously

// Stream chunks, a Node Readable, or a web ReadableStream.
for await (const piece of transform(fs.createReadStream("input.ts"))) out += piece;

Modes #

Mode Does Preserves
erase (default) Erases erasable syntax. Reports enum, instantiated namespace, parameter properties, import =, export =, and <T>x casts. Every offset
downlevel Also down-levels that syntax, matching ts.transpileModule at runtime. Every line; columns outside converted constructs
await transform(src, { mode: "downlevel" });

Pass jsx: true for .tsx input, in either mode. Erase mode keeps the JSX. Downlevel mode writes it for the classic runtime (React.createElement, or the pragma and pragmaFrag you pass, or a file's @jsx and @jsxFrag comments).

Unsupported syntax throws an UnsupportedSyntaxError with Node's ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX code. Pass onError to collect it instead. docs/modes.md has the full rules and examples of downlevel output.

Size #

Each mode loads its own engine, lazily, on its first call. Nothing loads at import.

What you ship Raw gzip -9 brotli -11
Erase mode: erase.wasm + wrapper 32.8 + 6.4 kB 13.6 + 2.9 kB 12.4 + 2.6 kB
Downlevel mode: downlevel.wasm + wrapper 52.1 + 6.4 kB 22.2 + 2.9 kB 19.9 + 2.6 kB

The wrapper is src/index.js bundled with esbuild --bundle --minify --format=esm. The browser entry is the same size. Both engines need WasmGC and wasm SIMD.

Speed #

On a 20MB sample of real-world TypeScript from 17 open-source projects (Apple M1, Node 24):

Tool MB/s gzip
typestrip 69.6 15.1kB
@swc/wasm-typescript (strip-only) 27.3 1.39MB
amaro (strip-only) 25.5 1.12MB
ts-blank-space 16.9 1.03MB

typestrip also beats oxc-transform, a native addon, in downlevel mode. It does less work per byte: one forward pass over the bytes, no syntax tree, and no code generation. docs/benchmarks.md has every tool, both modes, and the method.

Correctness #

Erase mode is judged against ts-blank-space, on positions, parsed JavaScript, error positions, and streamed output. It passes all 11,736 files of TypeScript 6's own sources and test suites. Downlevel mode is judged against ts.transpileModule by evaluating both outputs. docs/correctness.md lists every suite, its last result, and the open bugs.

Docs #

Contributing #

CONTRIBUTING.md covers setup, building, testing, and the debug tools.

License #

MIT