JavaScript Code Generation
Vais can compile to JavaScript (ESM modules), enabling Vais code to run in browsers and Node.js environments.
Overview
The vais-codegen-js crate provides a JavaScript backend alongside the primary LLVM backend. It generates clean, readable ES module output.
Usage
# Compile to JavaScript
vaisc --target js input.vais -o output.js
# Compile to JavaScript module
vaisc --target js --module input.vais -o output.mjs
Features
- ES Module output — generates standard
import/exportsyntax - Type-safe codegen — preserves Vais type semantics in JavaScript
- Struct mapping — Vais structs compile to JavaScript classes
- Enum support — tagged unions with pattern matching
- String interpolation — maps to template literals
- Operator overloading — preserves Vais operator semantics
Example
Vais source:
S Point { x: f64, y: f64 }
F dist(p: Point) -> f64 {
sqrt(p.x * p.x + p.y * p.y)
}
F main() -> i64 {
p := Point { x: 3.0, y: 4.0 }
puts("distance = {dist(p)}")
0
}
Generated JavaScript:
export class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
export function dist(p) {
return Math.sqrt(p.x * p.x + p.y * p.y);
}
export function main() {
const p = new Point(3.0, 4.0);
console.log(`distance = ${dist(p)}`);
return 0;
}
Architecture
The JS codegen pipeline:
AST → Type Checker → JsCodegen → ESM output (.js/.mjs)
Key components in crates/vais-codegen-js/:
lib.rs— main entry point and module generationexpr.rs— expression code generationstmt.rs— statement code generationtypes.rs— type mapping (Vais types → JS representations)
Limitations
- No direct memory management (pointers compile to references)
- Integer arithmetic uses JavaScript's
Numbertype (no true i64 for values > 2^53) - FFI/extern functions are not supported in JS target
- GPU codegen is not available for JS target
See Also
- WASM JS Interop — using
#[wasm_import]and#[wasm_export] - Architecture — compiler pipeline overview