RTS é um compilador + runtime que pega seu .ts e cospe um .exe nativo.
Não é transpilador, não é bundler, não é wrapper em volta do V8 — é Cranelift
gerando código de máquina direto a partir do AST do SWC, com um runtime mínimo
em Rust e ABI tipado sem boxing.
Dois caminhos, mesmo codegen:
| Modo | Comando | O que faz |
|---|---|---|
| 🚀 JIT | rts run app.ts |
Compila pra memória executável e roda. Zero disco. |
| 📦 AOT | rts compile -p app.ts out |
Object file → linker → binário standalone (~3 KB). |
Benchmarks executados no Windows 11 (100 runs, 5 warmups, mediana).
Bun91.8 msbaseline |
Node.js113.9 ms1.24× mais lento que Bun |
RTS AOT 🦅16.9 ms5.43× mais rápido que Bun 6.74× mais rápido que Node |
Bun Workers147.6 ms
|
RTS multi-thread 🦅30.3 ms4.87× mais rápido que Bun Workers |
Bun.serve~14k req/s
|
RTS http_server 🦅29k req/s2.07× mais rápido que Bun.serve 78% do actix puro Rust |
| Bench | Bun | Node | RTS AOT | RTS vs Bun | RTS vs Node |
|---|---|---|---|---|---|
| Monte Carlo 10M (1 thread) | 91.8 ms | 113.9 ms | 16.9 ms | 5.43× | 6.74× |
| Monte Carlo 10M (8 threads) | 147.6 ms | — | 30.3 ms | 4.87× | — |
| HTTP throughput | ~14k req/s | — | 29k req/s | 2.07× | — |
Por que mais rápido? RTS compila TS para binário nativo via Cranelift —
sem JIT warmup, sem GC pause, sem dispatch dinâmico nos hot paths. Loops
comuns reescrevem automaticamente para parallel.* (rayon) sem o user
mencionar threads (silent parallelism). HandleTable shard-aware (32 shards
lock-free) escala alocação em paralelo.
Você escreve isso:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum = 0;
for (const x of arr) sum = sum + x;E o codegen vê o padrão de acumulador associativo e reescreve, antes de baixar IR:
sum = parallel.reduce(arr, 0, __par_reduce_0); // rayon, transparenteCobre for...of puro, arr.map/.forEach/.reduce, e o padrão clássico
s = s + EXPR. 96 funções já marcadas como pure: true (math, string, num,
fmt, path, hash, mem) alimentam o reconhecimento. Detalhes em
docs/specs/silent-parallelism.md.
37 namespaces. Sem dependência de OpenSSL, schannel, libuv ou qualquer runtime externo.
| Família | Namespaces |
|---|---|
| I/O & FS | io fs path process env os |
| Compute | math num bigfloat fmt hash crypto |
| Memória | gc buffer mem alloc ptr ffi |
| Concorrência | thread atomic sync parallel |
| Rede | net tls http_server (actix-web embutido) |
| Dados | collections string regex json date |
| Async | events (EventEmitter), Promise + Function nativos |
| UI | ui (FLTK 1.x bindings) |
| Meta | runtime test trace hint |
🌐 HTTPS sem dor: rustls + webpki-roots (Mozilla CAs embutidos no binário)
🧵 Threading: 4 mecanismos coexistindo — spawn/join, spawn_async,
spawn_detached (pool 8 workers, 5M spawn/s), scope auto-join
🔒 HandleTable shard-aware: 32 shards lock-free entre si
✅ Controle de fluxo — if/else, while, do-while, for, switch
(jump table nativa via br_table quando todos os cases são literais inteiros)
✅ Funções — declaração, expression, arrow, tail call optimization
(return f(x) vira return_call), ponteiros de função first-class
✅ Classes — constructor, métodos, this, extends, super(...),
super.method(...), static, getters/setters, dispatch virtual real,
operator overload Rust-style (a + b vira a.add(b) em compile-time)
✅ async / await — pipeline Promise-centric com tokio compartilhado.
Promise.create faz spawn_blocking, settle automático via thread-local
error slot. Function class completa (call/apply/bind/toString/new Function).
✅ Big decimal — bigfloat em i128 fixed-point, ~30 dígitos. π via Machin
bate 29 dígitos corretos (f64 entrega 16).
✅ Containers — object/array literals via collections.map_*/vec_*,
member access, atribuição, aninhamento livre
✅ try/catch/finally (fase 1) — slot de erro thread-local; unwind real ainda não (#128)
✅ Outros — enum, destructuring nested+rename, spread em literals,
regex, default params, exports/imports, JSON, Date, console.*, Map/Set v0,
Array/String prototypes essenciais
❌ Não suportado ainda — generators, decorators, generics completos,
satisfies, call spread f(...args), closures com captura mutável real
(#195 em fase 1)
src/
├─ parser/ SWC parse → AST interno
├─ type_system/ type checker, registry, resolver
├─ codegen/ Cranelift codegen direto sobre o AST (sem HIR/MIR)
│ ├─ lower/ lowering de expr/stmt/func
│ ├─ emit.rs ObjectModule (AOT)
│ └─ jit.rs JITModule (rts run)
├─ abi/ ⚡ contrato único — SPECS, AbiType, Intrinsic, símbolos
├─ namespaces/ 37 namespaces builtin (impl operacional)
├─ runtime/ bootstrap, async_rt (tokio compartilhado), eval
├─ module/ resolver + grafo de dependências
├─ linker/ link nativo (system linker + fallback object)
├─ pipeline.rs orquestra build/run/JIT
└─ cli/ run · compile · apis · init · repl · eval · ir
ABI sem boxing: cada função de namespace é um símbolo
#[no_mangle] extern "C" fn __RTS_FN_NS_<NS>_<NAME>(...). Nada de JsValue,
nada de dispatcher central. i64/f64 em bits nativos, strings como
(ptr, len) UTF-8, handles u64 opacos para recursos.
# Instalar
git clone https://github.com/UrubuCode/rts && cd rts
cargo build --release
# Rodar
./target/release/rts run examples/console.ts
# Compilar pra binário (~3 KB, sem runtime DLL)
./target/release/rts compile -p examples/console.ts hello
./hellorts run file.ts # JIT in-memory
rts compile -p file.ts out # AOT com slicing por uso
rts apis # listar APIs registradas em abi::SPECS
rts ir file.ts # dump do IR Cranelift (pra debug de codegen)
rts init my-app # scaffolding de projetoQuer ver exatamente o que o Cranelift está gerando?
rts ir file.ts 2>&1 | head -50Imprime o IR de cada user fn + __RTS_MAIN sem executar. Bom pra caçar
loads/stores redundantes em hot loops, calls extern desnecessários, e
oportunidades de intrinsic. Ver CLAUDE.md § Debug do codegen.
- 📘
BLOG_POST.md— visão geral pra dev externo - 🛠️
CLAUDE.md— arquitetura interna + regras do codebase - 📖
docs/specs/— specs técnicas de features - 🗺️
ROAD_MAP.md— direção estratégica - ✅
NEXT_STEPS.md— próximos passos concretos - 🐛 Issues: tracker mestre de paridade JS/TS em #226
- ✋ Sem
xtask— build écargopuro - ✋ Sem download de runtime support em build time
- ✋ Sem dependência de Rust/Cargo no ambiente final do binário AOT
- ✋ Single binary distribuído, roda em qualquer Windows/Linux/macOS sem instalar nada
Feito com 🦅 por UrubuCode
Se Bun é foguete, RTS é ave de rapina.
