Paserati is an experimental (mad scientist kind of experimental) TypeScript runtime: it parses + type-checks TypeScript and compiles it directly to bytecode for a register VM. And then it executes the bytecode.
TypeScript is a superset of JavaScript, so if you can execute TypeScript, you’re building an ES2025 runtime too (by definition, plus a lot of pain).
Under the hood: TS/JS → bytecode → register VM, with inline caches, shape-based objects (a.k.a. “hidden classes”-style), and a pluggable async executor with microtask scheduling.
Right now it prioritizes correctness over raw speed, but the architecture is designed for type-driven optimization later (specialization, monomorphization, unchecked fast paths).
- Test262 language suite: 98.4% (see details below)
- Native TS execution: no
tsc, no TS→JS transpilation - TCO: tail call optimization (elite feature)
- Shapes + ICs: fast-ish property access without a JIT
- Runtime type reflection:
Paserati.reflect<T>()(generate a type object / JSON Schema at runtime) - Small-ish footprint:
- ~16MB static binary (unstripped, includes lexer/parser/checker/compiler/VM/builtins)
- ~5MB BSS idle (approx; depends on build/OS)
- Pure Go, no CGO, no WASM blobs, two simple dependencies (
golang.org/x/text,github.com/dlclark/regexp2)
Paserati has a long way to go performance-wise, but it’s already at the point where it can beat dop251/goja and QJS on a couple of simple microbenches.
Results from hyperfine (see bench/hyperfine.sh):
| Benchmark | paserati (Mean) | goja (Mean) | QJS(Mean) | Relative |
|---|---|---|---|---|
bench/bench.js |
3.924 ± 0.097 s | 5.207 ± 0.093 s | 4.945 ± 0.092 s | paserati 1.33× faster than gojac, 1.26× faster than quickjs |
bench/objects.js |
6.169 ± 0.092 s | 7.015 ± 0.151 s | 8.135 ± 0.130 s | paserati 1.14× faster than gojac, 1.32× faster than quickjs |
Paserati also runs V8 benchmarks, beating Goja in several.
If your favorite pure Go JavaScript engine is reading this: skill issue.
- Runtime type reflection / JSON Schema:
examples/reflect.ts - Proxy + classes + async:
examples/reactive.ts - Async/await + generators:
examples/async.ts - Classes (private fields, inheritance, statics):
examples/classes.ts - Typed recursion (Y combinator):
examples/ycomb.ts - “Look ma, generics”:
examples/generics.ts
Examples may or may not work at every commit, but they should work at least once in a while.
- A TypeScript build toolchain replacement: see microsoft/typescript-go
- A JIT in Go: I’ll stop just short of that (for now)
- Perfect “legacy weirdness”: modern ES is the target; some dusty corners (like
with) are still incomplete
# Build
go build -o paserati ./cmd/paserati/
# Run the REPL
./paserati
# Run a snippet
./paserati -e 'console.log("hello from paserati")'
# Execute a script
./paserati path/to/script.ts
# Run the test suite
go test ./tests/...From a recent run:
language (TOTAL) 23523 23155 365 0 3 98.4%
Weak spots:
language/module-code/namespace: 52.8% (36)language/eval-code/indirect: 77.0% (61)language/statements/using: 72.2% (36)language/statements/await-using: 85.7% (35)language/module-code/top-level-await: 87.6% (251)language/literals/regexp: 94.1% (238)
At 98.4% Test262 language compliance, Paserati handles the vast majority of modern JavaScript/TypeScript semantics correctly. It's still evolving, but it's past the "toy project" phase.
Core language features that work well:
- Async/await, TLA, Promises, microtasks (incl. top-level await, async generators)
- ESM modules (plus dynamic
import(), pluggable resolution) - Classes (private fields, statics, inheritance, super expressions, decorators)
- (Async) Generators (
yield,yield*) - Modern operators (
?.,??, logical assignment) - Destructuring (arrays/objects/rest/spread)
- Built-ins (Proxy/Reflect/Map/Set/TypedArrays/ArrayBuffer/RegExp/Symbol/BigInt)
- Advanced types (generics, conditional/mapped types, template literal types,
infer)
It runs real-world TypeScript libraries like date-fns from source.
Remaining gaps:
import defer(stage 3 proposal; mostly unimplemented)- Some edge cases in
evaland module namespaces - Import attributes (experimental ES feature)
See docs/bucketlist.md for the exhaustive yet messy feature inventory.
Seriously, why would you want to contribute to this? …But if you do, I'm both terrified and thrilled. PRs and issues are welcome.
This project is licensed under the MIT License.
This is a one-person project developed in my free time with the help of AI. It is also an experiment in large scale software engineering with AI, aimed at speedrunning a production-quality open source project.
Google Gemini 2.5/3.0 Pro and Claude Sonnet/Opus 4/4.5 wrote almost all the code so far under more or less careful direction and scrutiny - also known as "vibe coding but when you know what you're doing".
That fun sticker at the top of the README? It's made with GPT-4o's image generation.
Remember: Pedal to the metal, or just pedal faster.
