LambdaJS

March 25, 2026 · View on GitHub

LambdaJS is Lambda's built-in JavaScript JIT and browser DOM engine (~18K LOC). It transpiles JavaScript source code into MIR IR which is then compiled to native machine code, enabling near-native execution of JavaScript programs within the Lambda runtime.

Status: Experimental. LambdaJS passes 60/60 JS baseline tests (677/677 total) and runs all 53/53 benchmarks across 5 suites. It covers ES6 classes, prototype-based OOP, closures, typed arrays, template literals, try/catch/finally, destructuring, regex via RE2, optional chaining, Map/Set collections, and error subclasses. 5-suite geometric mean: 2.2× vs Node.js (V8) (JetStream standalone: 6.3×).

Usage

./lambda.exe script.js              # Run a JavaScript file with LambdaJS JIT

Supported JavaScript Features

Language Syntax

FeatureStatusNotes
Variable declarations (var, let, const)Hoisting for var; block scoping for let/const
Function declarations & expressionsIncluding hoisting
Arrow functionsLexical this
Template literalsBacktick strings with ${expr} interpolation
Spread operator (...)In function calls and array literals
Rest parameters (...args)
Default parameters
Destructuring — arraysconst [a, b] = arr
Destructuring — objectsconst {x, y} = obj, rename {x: px}, for-of
Destructuring — rest (...rest)Object rest {a, ...rest} and array rest [a, ...rest]
ES6 classesclass, extends, super(), static, getters/setters
Prototype-based OOPFoo.prototype.method = fn, new Foo()
ClosuresMulti-level transitive capture, shared scope env
typeof operatorAll JS quirks (null → "object")
instanceof operator
in operator
delete operatorSets property to null (simplified)
Nullish coalescing (??)
Conditional (ternary) ? :
switch / caseWith fallthrough support
for...of
for...in
do...while
try / catch / finallyIncluding return-in-try
throw
IIFE (function(){...})()
Regex literalsVia RE2 backend; .test(), .exec()
Sequence expressions (comma)
Labeled statementsbreak label, continue label
Nullish/logical assignment (??=, &&=, ||=)
Optional chaining (?.)Property, method, computed, nested chains
Map / Set collectionsnew Map(), new Set() with full method API
Generators / yield
async / await / Promise
import / export (ES modules)
WeakMap / WeakSet
Symbol APISymbol(), Symbol.for(), Symbol.keyFor(), well-known symbols
Proxy / Reflect
setTimeout / setInterval
encodeURIComponent / decodeURIComponentRFC 3986 percent-encoding via lib/url.c
structuredClone
globalThisSingleton global object with undefined, NaN, Infinity
Intl

Operators

CategoryOperatorsStatus
Arithmetic+, -, *, /, %, **
Comparison==, !=, ===, !==, <, <=, >, >=
Logical&&, ||, !
Bitwise&, |, ^, ~, <<, >>, >>>
Unary+x, -x, ++, --, typeof, void, delete
Assignment=, +=, -=, *=, /=, %=, **=, &=, |=, ^=, <<=, >>=, >>>=

DOM Bridge

LambdaJS includes a DOM bridge for use with the Radiant layout engine:

Document Methods

MethodStatusNotes
getElementById
getElementsByClassName
getElementsByTagName
querySelector
querySelectorAll
createElement
createTextNode
createElementNSNamespace ignored, delegates to createElement
write / writelnSimplified; appends text to body
normalizeMerges adjacent text nodes at root
createDocumentFragmentLightweight container; children transfer on append
createCommentCreates comment DOM node
importNodeDeep clone from external tree
adoptNodeDetaches node from current parent

Document Properties

PropertyStatusNotes
body
documentElement
head
title
cookie
readyState
URL / locationURL returns href string; location object with .href, .hostname, .pathname, etc.

Element Properties

PropertyStatusNotes
tagName
id
className
textContent
children
parentElement
parentNode
firstChild
lastChild
nextSibling
previousSibling
childNodes
childElementCount
nodeType
nodeNameTag name or "#text"
nodeValueAlias for text node .data
firstElementChildSkips text nodes
lastElementChildSkips text nodes
nextElementSiblingSkips text nodes
previousElementSiblingSkips text nodes
innerHTMLGetter and setter; setter parses HTML fragment
offsetWidthReturns 0 (JS runs before layout)
offsetHeightReturns 0 (JS runs before layout)
clientWidthReturns 0 (JS runs before layout)
clientHeightReturns 0 (JS runs before layout)
outerHTMLGetter only
classListadd, remove, toggle, contains, item, replace, length, value
datasetdata-* attribute proxy with camelCase ↔ kebab-case conversion
scrollTop / scrollLeft
getBoundingClientRect

Element Methods

MethodStatusNotes
getAttribute
setAttribute
hasAttribute
removeAttribute
querySelector
querySelectorAll
matches
closest
appendChild
removeChild
insertBefore
hasChildNodes
cloneNode
normalizeMerges adjacent text nodes
replaceChild
insertAdjacentHTMLParses HTML fragment at position
insertAdjacentElementInserts element at position
removeSelf-removal from parent
containsSubtree containment check
toggleAttributeOptional force parameter

Style

FeatureStatusNotes
element.style.prop get/setcamelCase ↔ CSS conversion
getComputedStyle()Full cascade matching
element.style.cssTextGetter only
element.style.setProperty()Sets inline style property
element.style.removeProperty()Removes inline style property

Built-in Objects & Methods

String Methods (24)

indexOf, lastIndexOf, includes, startsWith, endsWith, trim, trimStart, trimEnd, toLowerCase, toUpperCase, split, substring, slice, replace, replaceAll, charAt, charCodeAt, concat, repeat, padStart, padEnd, at, search, toString

Missing: match, matchAll, normalize, localeCompare, codePointAt

Array Methods (29)

push, pop, indexOf, lastIndexOf, includes, join, reverse, slice, concat, map, filter, reduce, reduceRight, forEach, find, findIndex, some, every, sort, flat, flatMap, fill, splice, shift, unshift, at, toString, from (static), isArray (static)

Missing: copyWithin, findLast, findLastIndex, toReversed, toSorted

Object Methods (13)

Object.keys, Object.values, Object.entries, Object.create, Object.defineProperty, Object.assign, Object.freeze, Object.isFrozen, Object.getPrototypeOf, Object.setPrototypeOf, Object.is, Object.fromEntries, hasOwnProperty

Missing: Object.seal, Object.getOwnPropertyNames

Math (27 methods + 8 constants)

Methods: abs, floor, ceil, round, sqrt, pow, min, max, log, log2, log10, exp, sin, cos, tan, asin, acos, atan, atan2, sign, trunc, random, cbrt, hypot, clz32, imul, fround

Constants: PI, E, LN2, LN10, LOG2E, LOG10E, SQRT2, SQRT1_2

Missing: sinh, cosh, tanh

Number (6 methods + 8 properties)

Methods: toFixed, toString, Number.isInteger, Number.isFinite, Number.isNaN, Number.isSafeInteger

Properties: MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, MAX_VALUE, MIN_VALUE, POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, EPSILON

Missing: toExponential, toPrecision

Map / Set

new Map(), new Set()

Map methods (9): set, get, has, delete, clear, forEach, keys, values, entries + size property

Set methods (7): add, has, delete, clear, forEach, values, entries + size property

Missing: Constructor with iterable argument, Symbol.iterator support

Regex

Regex literals via RE2 backend. Methods: .test(), .exec() with capture groups.

Missing: match, matchAll, lookahead/lookbehind, backreferences (RE2 limitations)

JSON

JSON.parse, JSON.stringify

Backed by Lambda's native JSON parser and formatter. Reviver/replacer/space arguments not yet supported.

Function

.call(), .apply(), .bind()

Date

Date.now(), new Date()

Instance methods (10): getTime, getFullYear, getMonth, getDate, getHours, getMinutes, getSeconds, getMilliseconds, toISOString, toLocaleDateString

Missing: setFullYear, setMonth, setDate, setHours, toUTCString, toDateString, toTimeString

Error

Error, TypeError, RangeError, SyntaxError, ReferenceError

All support .message, .name, and instanceof checks.

Typed Arrays

Full support for all 8 standard typed array types:

Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array

Operations: new, get, set, length, fill, subarray

Global Functions

parseInt, parseFloat, isNaN, isFinite, console.log, performance.now(), alert, encodeURIComponent, decodeURIComponent, globalThis


Benchmark Results — LambdaJS vs Node.js (V8)

Platform: Apple Silicon MacBook Air (M4), macOS
Node.js: v22.13.0 (V8 JIT with TurboFan optimizing compiler)
Methodology: 3 runs per benchmark, median of self-reported execution time
Optimizations applied: P1 (return type propagation), P2 (bump-pointer alloc), P3 (direct ctor stores), P4 (typed instance property reads), P5 (module var arithmetic), P6 (function inlining), P7 (native method dispatch)

Ratio = LambdaJS / Node.js. Values < 1.0× mean LambdaJS is faster.

Summary by Suite

SuiteGeo. MeanLJS WinsNode WinsTotal
R7RS1.3×5510
AWFY4.7×21214
BENG0.3×6410
KOSTYA6.3×077
LARCENY3.8×21012
JetStream6.3×0911
Overall (5 suites)2.2×153853

Where LambdaJS Beats Node.js (15 benchmarks)

BenchmarkSuiteLambdaJSNode.jsRatio
revcompBENG0.001ms3.4ms0.0003×
knucleotideBENG0.016ms5.0ms0.003×
pidigitsBENG0.015ms2.0ms0.008×
jsonAWFY0.167ms2.8ms0.06×
divrecLARCENY0.823ms7.9ms0.10×
regexreduxBENG0.305ms2.5ms0.12×
fannkuchBENG0.529ms4.1ms0.13×
takR7RS0.117ms0.80ms0.15×
fastaBENG1.21ms6.2ms0.20×
cpstakR7RS0.233ms1.00ms0.23×
array1LARCENY0.580ms1.8ms0.31×
sieveAWFY0.136ms0.376ms0.36×
fibR7RS1.20ms2.0ms0.60×
ackR7RS9.33ms13.7ms0.68×
fibfpR7RS1.25ms1.77ms0.70×

Strengths:

  • Delegating to Lambda's native engines (revcomp, knucleotide, regexredux, pidigits) bypasses JS-level overhead entirely.
  • Simple recursive functions (tak, cpstak, fib, ack): MIR JIT generates efficient code for monomorphic call sites.
  • Small array/permutation code (divrec, array1, fannkuch, sieve): tight-loop compilation with P5/P6 inlining.
  • AWFY json and sieve added as wins after P3/P4/P5 property-access and module-var optimizations.

Where Node.js is Faster

TierCountKey Bottleneck
Comparable (1–2×)8nqueens (1.0×), fft (1.6×), primes/larceny (1.7×), primes/kostya (1.8×), paraffins (1.2×), fasta/fib/fibfp
Node 2–5× faster10json_gen (2.5×), storage (2.8×), bounce (3.2×), ray (3.2×), list (3.3×), levenshtein (3.5×), queens (3.6×), permute (3.6×), collatz (4.4×), towers (4.9×)
Node 5–20× faster12sumfp (5.3×), base64 (6.2×), binarytrees (7.2×), spectralnorm (7.5×), brainfuck (11×), deltablue (12×), deriv (13×), triangl (15×), richards (16×), havlak (18×), diviter (23×), quicksort (5.8×)
Node >20× faster8sum (18×), mbrot (10×), puzzle (4.6×), pnpoly (12×), gcbench (29×), nbody/beng (38×), mandelbrot/beng (54×), cd (54×), nbody/awfy (67×), matmul (83×)

Where V8 dominates and why:

  • Numeric-heavy loops (sum, nbody, mandelbrot): V8's TurboFan performs type specialization and SIMD optimizations.
  • OOP/class-heavy code (richards, deltablue, havlak): V8's hidden classes, inline caches, and on-stack replacement.
  • GC-intensive (gcbench, binarytrees, cd): V8's generational GC with concurrent marking.
  • String/data processing (base64, brainfuck, json): V8's optimized string representations.

JetStream Benchmarks (Original JS Files)

Measured after v11 Track A performance optimizations (property hash table, array fast path, float prescan widening, integer index fast path, constructor shape pre-allocation, property name interning).

BenchmarkCategoryLambdaJS (ms)Node.js (ms)Ratio
deltabluemacro11.05.81.9×
regex_dnastring2.4
cube3d3D29.911.72.6×
splaydata22.07.72.9×
crypto_sha1crypto22.37.53.0×
crypto_md5crypto21.7
richardsmacro81.45.116.0×
crypto_aescrypto38.8
nbodynumeric260.83.184.1×
navier_stokesnumeric569.27.575.9×
base64string390.3
hashmapdataTIMEOUT12.0
raytrace3d3DFAIL9.1

Geometric mean (exec): LambdaJS 45.0ms vs Node.js 7.2ms → 6.3× (improved from 8.8× in v10).

11 of 13 JetStream JS files run successfully. hashmap times out (GC pressure from 90K constructor calls). raytrace3d has a pre-existing closure capture bug.


Architecture

JavaScript Source


  Tree-sitter Parser (tree-sitter-javascript)


  AST Builder (build_js_ast.cpp) ─── 40+ AST node types


  MIR Transpiler (transpile_js_mir.cpp)
       │  ├── Capture analysis (multi-level closures)
       │  ├── Type inference (native fast paths)
       │  └── Tail call optimization


  MIR IR ──► Native Code (via MIR JIT)


  JS Runtime (js_runtime.cpp + js_globals.cpp)
       ├── 24 string methods
       ├── 29 array methods
       ├── 27 math methods
       ├── Prototype chain (max depth 32)
       ├── Typed arrays (8 types)
       └── DOM bridge (Radiant integration)
ComponentFileLines
AST definitionslambda/js/js_ast.hpp495
AST builderlambda/js/build_js_ast.cpp1,741
MIR transpilerlambda/js/transpile_js_mir.cpp9,614
Runtimelambda/js/js_runtime.cpp2,170
Globalslambda/js/js_globals.cpp819
Runtime headerlambda/js/js_runtime.h298
DOM bridgelambda/js/js_dom.cpp1,772
Typed arrayslambda/js/js_typed_array.cpp199
Scopinglambda/js/js_scope.cpp248
Total~18,000