A Rust-based JavaScript interpreter and compiler infrastructure designed to execute JavaScript code within Rust environments and compile JS directly to Rust binaries.
RustyJS consists of two complementary components:
- JS Macro (
js_macro) - A procedural macro that parses JavaScript-like syntax and generates Rust code - JS Runtime (
js_runtime) - A complete JavaScript runtime implementation in pure Rust
The ultimate goal of RustyJS is to copy-paste any JavaScript code into a Rust macro and have it just work, eventually enabling:
- Direct execution of JS code within Rust applications
- Compilation of JavaScript to standalone Rust binaries
- Zero-dependency JavaScript execution in performance-critical systems
js_rust_dsl/
├── js_macro/ # Procedural macro for parsing JS syntax
├── js_runtime/ # Complete JS runtime implementation
└── js_example/ # Example usage and tests
- Purpose: Transforms JavaScript syntax into Rust bytecode instructions
- Features:
- Full expression parsing (binary ops, unary ops, logical ops, method calls)
- Statement parsing (declarations, control flow, exception handling)
- Function declarations and calls
- Object and array literals
- Member and index access with assignment support
- Compound assignment operators (
+=,-=,*=,/=,%=) - Increment/decrement operators (
++,--)
Usage:
use js_macro::js;
fn main() {
js! {
let x = 5;
let y = 10;
console.log(x + y); // Output: 15
}
}- Purpose: Executes compiled JavaScript bytecode with full JS semantics
- Capabilities:
- Variable binding with proper scoping (let/const semantics)
- Dynamic typing with JavaScript type coercion rules
- Function declarations and invocations
- Object and array manipulation
- Method calls with proper
thiscontext - Exception handling (try-catch-finally with proper flow control)
- Built-in functions and methods:
- Global constructors:
String(),Number(),Boolean(),Error(),TypeError() - Console:
console.log() - Math object:
max(),min(),floor(),ceil(),round(),abs(),pow() - Array methods:
push(),pop(),map(),filter(),reduce(),forEach(),includes(),join() - Object methods:
Object.keys(),Object.values(),Object.assign() - JSON:
JSON.stringify(),JSON.parse()
- Global constructors:
✅ Data Types
- Numbers, Strings, Booleans
- Arrays, Objects
- Functions (named & anonymous)
- Null, Undefined
- Error objects with stack traces
✅ Operators
- Arithmetic:
+,-,*,/,% - Comparison:
==,!=,===,!==,<,>,<=,>= - Logical:
&&,||,! - Assignment & Compound:
=,+=,-=,*=,/=,%= - Postfix:
++,--
✅ Control Flow
if/else if/elsestatementsforloops with full initialization, condition, incrementwhileanddo-whileloopsreturnstatementstry-catch-finallywith optional catch bindingthrowstatements
✅ Object-Oriented Features
- Object literals with shorthand properties
- Member access (dot notation & bracket notation)
- Method calls with
thiscontext binding - Function objects as first-class values
✅ Advanced Features
- Callback functions and higher-order functions
- Array methods (
map,filter,reduce) - String concatenation with type coercion
- Proper JavaScript truthiness/falsiness semantics
Execute user-provided JavaScript logic without spawning a separate JavaScript engine:
// User configuration scripts in JS
js! {
const config = {
maxRetries: 3,
timeout: 5000,
logLevel: "debug"
};
}Write game logic in familiar JavaScript, compile to high-performance Rust binaries:
js! {
const player = { x: 100, y: 100, health: 100 };
function update(deltaTime) {
player.x += deltaTime * player.velocity;
if (player.health <= 0) {
gameOver();
}
}
}Chain transformations using JavaScript array methods compiled to Rust:
js! {
const results = data
.filter(item => item.valid)
.map(item => ({ ...item, processed: true }))
.reduce((sum, item) => sum + item.value, 0);
}Deploy lightweight JS functions as Rust binaries without runtime overhead:
- Compile JS → Rust bytecode → Binary
- No JavaScript engine dependency
- Static typing guarantees from Rust
- Native performance
Execute JavaScript test scripts in a controlled Rust environment:
js! {
function testUserFlow() {
let user = authenticate("test@example.com");
user.updateProfile({ name: "Updated" });
return user.verified;
}
}Compile JavaScript to WebAssembly via Rust for browser execution with full type safety.
- Core JavaScript parsing and execution
- Basic built-in functions
- Exception handling
- Array and Object support
- Expand built-in library (String methods, Array methods)
- Arrow functions
- Async/await support
- Classes and inheritance
- Template literals
- Direct JS-to-Rust binary compilation
- WebAssembly code generation
- Optimization passes for generated code
- Module system (import/export)
- Full ECMAScript compatibility
- Debugger support
- Performance profiling tools
- Package manager integration
See js_example/src/main.rs for comprehensive examples covering:
- Functions and closures
- Control flow (if/else, loops)
- Arrays with methods (map, filter, reduce)
- Objects with methods
- Exception handling (try-catch-finally)
- Built-in functions (Math, JSON, Object, String, Number)
Compilation Pipeline:
JavaScript Code → Parser → IR → Bytecode → Runtime Execution
- Parser (
js_macro/src/lib.rs): Converts JS syntax to an AST - Intermediate Representation (
js_macro/src/ir.rs): Lowers AST to IR - Bytecode Compiler (
js_runtime/src/lib.rs): Compiles IR to stack-based bytecode - Execution Engine (
js_runtime/src/lib.rs): Interprets bytecode with proper scoping and control flow
| Aspect | Benefit |
|---|---|
| Performance | No external JS engine required; compile to native Rust binaries |
| Portability | Ship JavaScript logic as part of Rust binaries—no runtime dependency |
| Type Safety | Rust's type system ensures memory safety; compiled output is verifiable |
| Integration | Execute JS natively from Rust; call Rust from JavaScript (future) |
| Deployment | Single binary distribution with embedded JavaScript execution |
We're actively building toward full JavaScript compatibility. Contributions welcome for:
- Additional built-in functions
- Performance optimizations
- Syntax feature expansion
- Test coverage