From concept to crates.io - How I built a JavaScript-compatible runtime that brings familiar Node.js patterns to the Rust ecosystem
The Journey Begins
As a developer who loves both JavaScript's expressiveness and Rust's performance guarantees, I've always wondered: "What if we could have the best of both worlds?"
Today, I'm excited to share Zano v0.1.1 - a Node.js-like runtime built entirely in Rust that makes this dream a reality.
Try it now: cargo install zano
Crates.io: https://crates.io/crates/zano
GitHub: https://github.com/sazalo101/zano
What is Zano?
Zano is a high-performance backend runtime that provides a familiar Node.js development experience while leveraging Rust's memory safety and zero-cost abstractions. Think of it as "Node.js syntax with Rust performance."
// This is valid Zano code!
const fs = require('fs')
try {
fs.writeFile('hello.txt', 'Hello from Zano!')
let content = fs.readFile('hello.txt')
console.log('File content:', content)
} catch (error) {
console.error('Operation failed:', error)
}
The Technical Challenge
Building a JavaScript-compatible runtime in Rust presented several fascinating challenges:
1. Language Design
Creating a parser that understands JavaScript syntax while maintaining Rust's type safety required careful design decisions. I built a custom lexer and recursive descent parser that handles:
- Variables (
let
,const
,var
) - Functions with parameters and return values
- Objects and arrays with familiar access patterns
- Control flow (
if/else
,while
,try/catch
)
2. Async Runtime Architecture
Node.js's event loop is legendary for its performance. I replicated this using Tokio:
pub struct ZanoRuntime {
globals: Arc<RwLock<HashMap<String, ZanoValue>>>,
functions: Arc<RwLock<HashMap<String, Arc<dyn ZanoFunction>>>>,
modules: Arc<RwLock<HashMap<String, ZanoValue>>>,
}
3. Module System
Implementing require()
functionality meant building a complete module resolution system with built-in modules like:
const fs = require('fs') // File system operations
const http = require('http') // HTTP client/server
const path = require('path') // Path manipulation
// Global console object available everywhere
Key Features That Make Zano Special
Familiar Syntax
let user = {name: "Alice", age: 30}
let numbers = [1, 2, 3, 4, 5]
function calculateAge(birthYear) {
return 2025 - birthYear
}
console.log("User:", user.name, "Age:", calculateAge(1995))
Robust Error Handling
try {
console.log("Attempting risky operation...")
throw "Something went wrong!"
} catch (error) {
console.error("Caught:", error)
}
console.log("Program continues safely!")
Package Management
zano init # Creates package.json
zano install lodash # Installs dependencies
zano run start # Runs npm scripts
Multiple Execution Modes
zano script.zn # Run files
zano -e "console.log('Hi')" # Direct evaluation
zano -i # Interactive REPL
Performance Comparison
Aspect | Zano | Node.js |
---|---|---|
Memory Safety | ✅ Compile-time | ❌ Runtime errors possible |
Startup Time | ⚡ Instant | 🐌 ~50ms |
Memory Usage | 📦 Minimal | 📊 Higher baseline |
Concurrency | Tokio-powered | libuv-based |
Real-World Examples
File Processing Pipeline
// file-processor.zn
const fs = require('fs')
console.log("File Processing Pipeline")
try {
let data = "user1,admin\nuser2,member\nuser3,guest"
fs.writeFile('users.csv', data)
let content = fs.readFile('users.csv')
let processed = "Processed: " + content
fs.writeFile('processed.txt', processed)
console.log("✅ Processing complete!")
} catch (error) {
console.error("❌ Processing failed:", error)
}
Data Analysis Script
// analytics.zn
let jan = {month: "Jan", sales: 1000, costs: 800}
let feb = {month: "Feb", sales: 1200, costs: 900}
function calculateProfit(record) {
return {
month: record.month,
profit: record.sales - record.costs
}
}
let results = [calculateProfit(jan), calculateProfit(feb)]
let totalProfit = results[0].profit + results[1].profit
console.log("Total Profit: $" + totalProfit)
// Output: Total Profit: $500
Technical Architecture Deep Dive
Parser Implementation
The heart of Zano is its parser, built as a recursive descent parser with careful attention to JavaScript semantics:
pub enum Expression {
Literal(ZanoValue),
Identifier(String),
Binary { left: Box<Expression>, operator: BinaryOp, right: Box<Expression> },
Call { callee: Box<Expression>, args: Vec<Expression> },
Member { object: Box<Expression>, property: String },
Array(Vec<Expression>),
Object(Vec<(String, Expression)>),
// ... more variants
}
Runtime Execution
The runtime uses Tokio's async capabilities to handle JavaScript's event-driven nature:
async fn evaluate_expression(&self, expression: Expression) -> Result<ZanoValue> {
match expression {
Expression::Call { callee, args } => {
// Handle function calls including member functions like console.log
let function_name = self.resolve_function_name(callee)?;
let func = self.functions.read().await.get(&function_name)?;
func.call(args).await
}
// ... handle other expression types
}
}
Development Lessons Learned
1. Start Simple, Iterate
I began with basic arithmetic and gradually added features. This approach prevented overwhelming complexity and allowed thorough testing at each stage.
2. Embrace Rust's Type System
Initially, I fought against Rust's borrow checker. Eventually, I learned to design with ownership in mind, leading to cleaner, more performant code.
3. Community Feedback is Gold
Testing examples from the README revealed edge cases I hadn't considered. User perspective is invaluable.
4. Documentation-Driven Development
Writing examples for the README helped me understand what the API should look like from a user's perspective.
Performance Benefits in Practice
Here's a simple benchmark comparing Zano to Node.js for a CPU-intensive task:
// fibonacci.zn / fibonacci.js
function fibonacci(n) {
if (n <= 1) return n
return fibonacci(n - 1) + fibonacci(n - 2)
}
console.log("Fibonacci(35):", fibonacci(35))
Results (on my machine):
- Zano: ~1.2s with instant startup
- Node.js: ~1.8s + 50ms startup overhead
Note: This is a synthetic benchmark. Real-world performance varies.
What's Next for Zano?
The v0.1.1 release is just the beginning! Here's what's planned:
Version 1.1.0
- [ ] Full async/await support with proper Promise handling
- [ ] HTTP server implementation with routing
- [ ] Module bundling system
- [ ] Package registry integration
Version 1.2.0
- [ ] Class syntax support
- [ ] Destructuring assignment
- [ ] Template literals with interpolation
- [ ] JSON parsing utilities
- [ ] Comprehensive standard library
Version 2.0.0
- [ ] TypeScript-like static typing (optional)
- [ ] WebAssembly module support
- [ ] Built-in testing framework
- [ ] Advanced debugging tools
Contributing and Community
Zano is open source and welcomes contributions! Whether you're:
- Finding bugs (please report them!)
- Suggesting features (what would make Zano more useful?)
- Improving documentation (clarity is key!)
- Contributing code (PRs welcome!)
Get involved:
- GitHub: https://github.com/sazalo101/zano
- Issues: Share your ideas and bug reports
- Discussions: Join the conversation about Zano's future
Installation and Getting Started
Ready to try Zano? Here's how to get started:
# Install Zano
cargo install zano
# Create your first project
zano init
echo 'console.log("Hello, Zano!")' > hello.zn
zano hello.zn
# Try the REPL
zano -i
# Quick evaluation
zano -e 'let x = 5; let y = 10; console.log("Sum:", x + y)'
Conclusion
Building Zano has been an incredible journey that reinforced my belief that the Rust ecosystem can accommodate diverse programming paradigms while maintaining its core values of safety and performance.
Zano proves that you don't have to choose between familiar syntax and systems programming benefits. You can have both.
The future of backend development is bright, and I believe tools like Zano that bridge different programming communities will play a crucial role in that future.
Try Zano Today!
cargo install zano
Links:
- 📦 Crates.io: https://crates.io/crates/zano
- GitHub: https://github.com/sazalo101/zano
- Documentation: https://docs.rs/zano
What are your thoughts on bringing JavaScript-like syntax to Rust? Have you tried Zano? I'd love to hear your feedback and experiences in the comments!
Tags: #rust #javascript #nodejs #opensource #programming #webdev #performance #memorysafety #async #runtime
Follow me for more updates on Zano's development and other Rust projects!
Top comments (0)