Compatibilidade JS spec validada contra Bun e Node em 609 fixtures TS standalone.
[▰▰▰▰▰▰▰▱▱▱▱▱▱▱▱▱▱▱▱▱] 34.6% 205/592 fixtures passam
| Métrica | Valor |
|---|---|
| Paridade | 34.6% (205/592) |
| ✅ RTS = Bun = Node | 205 |
| ❌ RTS diverge | 78 |
| 💥 RTS runtime error | 309 |
| 🛠️ Falta corrigir | 387 |
| 17 | |
| 🚫 Rejeitados (RTS-only) | 0 |
| 📦 Total fixtures | 609 |
Atualizado: 2026-06-26 — como adicionar fixture
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.
⚠️ Motor antigo (congelado). Os 3 passes de reescrita silenciosa vivem norts-codegen-olde NÃO são carregados no motor novo sem rejustificação. Descrito aqui como capacidade histórica; o motor novo prioriza o piso de solidez primeiro.
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 |
| 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)
Redesign em andamento (strangler-fig). O motor de codegen está sendo reescrito do zero atrás do antigo, congelado. O motor novo ativo é
crates/rts-codegen-new/(caminho único HIR→Cranelift, sem MIR; valorPolyValueNaN-boxed; shapes + inline caches de dado; dispatch data-driven). O antigocrates/rts-codegen-old/(dual HIR→MIR / AST, valori64sobrecarregado) está congelado e some no cutover. Plano canônico:docs/specs/rts-codegen-new-design.md.
Workspace Cargo em crates/. O src/ é a fachada do bin rts (re-exporta os
crates); paths reais sob crates/<crate>/src/.
crates/
├─ rts-ast/ AST interno
├─ rts-parser/ SWC parse → AST
├─ rts-diagnostics/ erros estruturados
├─ rts-engine/ ⚡ heap GC + contrato ABI (SPECS, AbiType, Intrinsic, símbolos) + Registry
├─ rts-hir/ HIR tipado (I8..I128/F32/F64/Bool/Str/Handle/Array/Function/Class/Object/Any)
├─ rts-mir/ MIR SSA — usado SÓ pelo rts-codegen-old (congelado); some no cutover
├─ rts-codegen-old/ motor CONGELADO (dual MIR/AST, switchboard, add_fn! manual)
├─ rts-codegen-new/ motor ATIVO — value.rs (PolyValue), repr.rs, shape.rs, ic.rs,
│ dispatch.rs (data-driven), abi_gen.rs (ABI gerada de SPECS), lower/ (single path)
├─ rts-primitives/ classes PRIMORDIAIS (String/Object/Array/Function/Promise/Boolean/Number/Error)
├─ rts-shared/ não-primordial universal (math/num/collections(Map/Set)/json/globals + stdlib/*.ts)
├─ rts-std/ backend (io/net/tokio/console/promise/audio)
├─ rts-runtime/ fachada fina (pub use dos quatro acima) + staticlib AOT
├─ rts-node/ shims node:* (fs, os, path, process, crypto, util)
├─ rts-napi/ N-API (.node addons) via libloading + HandleTable
├─ rts-linker/ link nativo (system linker + fallback object)
└─ rts-cli/ run · compile · apis · init · repl · eval · ir
TS → SWC → AST → HIR (rts-hir) → lower/ (HIR → Cranelift IR, UM caminho) → egraph Cranelift → JIT/AOT
Não há tier MIR nem dual AST/MIR no motor novo. O egraph do Cranelift
(use_egraphs=true) é o ÚNICO otimizador (const-fold, CSE, DCE, FMA, strength
reduction, inline intraprocedural). O front-end só faz o que o Cranelift não pode
(semântica JS): coerções ToNumber/ToString/ToBoolean, o + polimórfico,
inserção de box/unbox (IR pura que o egraph dobra), emissão de sites de shape/IC,
wrap de int estreito, arestas de exceção. AOT/JIT compartilham compile_program
(FnCtx.module é &mut dyn Module).
Doutrina PRIMORDIAL-vs-Registry (central ao motor novo): o motor NOMEIA só as
classes primordiais; todo o resto resolve via Registry data-driven — nada de
nome não-primordial hardcoded no front, nem em "allow-list" (ver
CLAUDE.md § anti-hardcode). Os globais não-primordiais (console,
Map/Set, JSON, Date) vivem como .ts de prelude (rts-shared/stdlib/*.ts) e
chamam pontes privadas engine.*; o front não os nomeia.
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. No motor novo a tabela de
símbolos JIT é DERIVADA de SPECS (abi_gen.rs), não add_fn! manual.
# 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.
Número honesto: a paridade cross-runtime real do motor novo é a do bloco 🌐 Cross-runtime parity no topo (gerado pelo CI contra Bun+Node). O motor antigo chegou a 100% (372/372) na tag
v0.0-202606072107— um máximo local de uma abordagem hardcoded sobre um modelo de valor insólido; o redesign existe para furar essa parede, não para repetir o número. NÃO cite "1015/1015"/"100%" como estado atual.
O que o motor novo já cobre (em construção, paridade subindo):
- Sintaxe core: classes (extends/super/static/getters/setters), destructuring, spread em literais, optional chaining, nullish coalescing, arrow/function expressions, template literals
- Async: Promise + async/await (caminho síncrono sem
await; event loop real ainda aberto, #207) - JS globals como
.tsde prelude (data-driven): Object + statics, Boolean/Number/String prototypes, Error family, console.*, Map/Set, JSON, Date — nenhum nomeado no front - Operadores: divisão JS spec (
/SEMPRE f64 —44100/48000 === 0.91875, inclusive atribuído aconst), comparações, ternário, bitwise, shifts - try/catch/finally fase 1 (slot de erro thread-local; finally roda e re-propaga o erro corretamente)
- Diagnóstico: identificador não-resolvido vira erro de compilação, nunca segfault — e nunca um valor errado (o piso de solidez do redesign)
Itens pesados ainda abertos (alguns em fase de redesign): event loop async real (#207), closures com captura mutável (#195), TCO, Proxy (#218), typed arrays/DataView/ArrayBuffer, Symbol/Reflect/BigInt (#216/#219). Tracker mestre de paridade JS/TS: #226.
- 🛠️
CLAUDE.md— arquitetura interna + regras do codebase (inclui § anti-hardcode) - 📖
docs/specs/— specs técnicas de features - 🗺️
docs/specs/rts-codegen-new-design.md— plano canônico do redesign do motor - 🐛 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.
