Skip to content

FoxNick/jsrt

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚀 JSRT

A lightweight, fast JavaScript runtime built on QuickJS and libuv

Version 0.1.0 • WinterCG Compatible • 90.6% WPT Pass Rate • 73.3% npm Compatible

CI Coverage WPT ![npm Compatibility](https://img.shields.io/badge/npm-73.3%25 Compatible-blue) Tests License: MIT


Important Notice JSRT is an experimental, research-oriented project created to explore AI-assisted development by building a JavaScript runtime from scratch. The codebase is under active development and may change significantly; please evaluate carefully before using it in production environments.

Why JSRT?

JSRT = Minimal footprint + Maximum standards compliance

Perfect for scenarios where size and startup speed matter:

Aspect JSRT Node.js Deno
Binary Size ~2MB ~50MB ~90MB
Memory Baseline ~5MB ~30MB ~20MB
WPT Compliance 90.6% N/A 95%+
Target Use Cases Embedded, Edge, IoT General purpose Modern web apps

🎯 Ideal For

  • Edge Computing: Cloudflare Workers-style serverless functions
  • Embedded Systems: IoT devices, resource-constrained environments
  • CLI Tools: Fast-starting command-line utilities
  • Learning: Understanding JavaScript runtime internals

⚠️ Not Recommended For

  • Production-critical applications - Still in experimental phase
  • Heavy npm ecosystem dependency - Node compatibility is partial
  • Native module intensive projects - FFI is proof-of-concept

✨ Features

  • 🏃‍♂️ Fast & Lightweight: Minimal footprint JavaScript runtime (~2MB binary)
  • 🌐 Web Standards: WinterCG Minimum Common API compliant (29/32 WPT tests pass, 90.6% pass rate)
  • ⚡ Advanced Module System: Unified pipeline with FNV-1a caching, multi-format support (CommonJS/ESM/JSON), and protocol handlers (file://, http://, https://)
  • 🧱 Node Compatibility: 288 tests passing (100%) with compact mode enabled by default, 10+ node: modules including fs, http, crypto, net, path, os, and more
  • 📦 npm Ecosystem: 73.3% npm package compatibility with sophisticated module resolution and loading
  • 🔧 Rich APIs: Console, Fetch, WebCrypto, Streams, Timers, URL, AbortController, WebAssembly (WAMR-based)
  • 🧪 Comprehensive Testing: 288 unit tests + WPT integration with detailed compliance reporting
  • 🔒 Security: Complete WebCrypto API with RSA, AES, HMAC, digest, and random UUID support
  • 🌍 Cross-platform: Builds on Linux, macOS, and Windows with enhanced debugging (AddressSanitizer)
  • 🛠️ Developer Workflow: REPL, bytecode compilation, dev containers, Docker automation, and advanced debugging tools
  • 🧩 Extensible: FFI bridge and custom module hooks for native integration

🚀 Quick Start

Installation

# Clone the repository
git clone https://github.com/leizongmin/jsrt.git
cd jsrt

# Init submodule
git submodule update --init --recursive

# Build the runtime
make

Hello World

# Run from file
echo 'console.log("Hello from JSRT! 🎉");' > hello.js
./bin/jsrt hello.js

# Run from stdin
echo 'console.log("Quick test");' | ./bin/jsrt -

# Interactive REPL
./bin/jsrt repl

# Run from URL
./bin/jsrt https://example.com/script.js

# Compile to standalone binary
./bin/jsrt build hello.js hello-binary
./hello-binary

📖 Usage Examples

Basic JavaScript

// Modern JavaScript features
const result = [1, 2, 3, 4, 5].reduce((sum, n) => sum + n, 0);
console.log('Sum:', result);

// Async/await with Web Standards compliance
async function fetchData() {
  const response = await fetch('https://api.example.com/data');
  return await response.json();
}

// Compact Node mode - require without prefix (enabled by default)
const os = require('os'); // Works: resolves to node:os
const path = require('path'); // Works: resolves to node:path
import fs from 'fs'; // Works: ES modules too

Real-World HTTP Server

// Compact Node mode - works without node: prefix
import http from 'http'; // or: import http from 'node:http';

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(
    JSON.stringify({
      message: 'Hello from JSRT!',
      uptime: process.uptime(),
      memory: process.memoryUsage(),
      platform: process.platform,
    })
  );
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

WebCrypto API

// Generate random values
const randomBytes = new Uint8Array(16);
crypto.getRandomValues(randomBytes);
console.log('Random bytes:', randomBytes);

// Generate UUID
const uuid = crypto.randomUUID();
console.log('UUID:', uuid);

// Hash data
const data = new TextEncoder().encode('Hello, JSRT!');
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
console.log('SHA-256:', hashHex);

WebAssembly Support

// Load and execute WebAssembly modules
const wasmBytes = new Uint8Array([
  0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
  // ... WASM bytecode
]);

const wasmModule = new WebAssembly.Module(wasmBytes);
const wasmInstance = new WebAssembly.Instance(wasmModule);

// Call exported WASM functions
const result = wasmInstance.exports.add(5, 3);
console.log('WASM result:', result);

Native Library Access (FFI)

// Load and call native C library functions (experimental)
const ffi = require('jsrt:ffi');

// Load standard C library
const libc = ffi.Library('libc.so.6', {
  strlen: ['int', ['string']],
  strcmp: ['int', ['string', 'string']],
});

// Note: Function calls are proof-of-concept
console.log('Available functions:', Object.keys(libc));

🧩 Advanced Module System

JSRT features a sophisticated module loading system with unified pipeline architecture and Node.js-compatible resolution:

Features

  • Unified Pipeline: Cache lookup → Node-compatible resolution → Format detection → Protocol handler → Loader compilation
  • Multi-Format Support: CommonJS, ES modules, JSON, built-in jsrt:/node: namespaces, and bytecode preloading
  • Protocol Handlers: First-class file://, http://, and https:// loaders with streaming fetch backed by libuv
  • Adaptive Cache: FNV-1a hash cache with 85-95% hit rates, collision tracking, and explicit invalidation APIs
  • Compact Node Mode: Enable by default - require('fs') and require('node:fs') are equivalent
  • npm Compatibility: 73.3% npm package compatibility with sophisticated module resolution
  • Extensibility Hooks: Register custom protocols, inject loaders, and introspect diagnostics

Module Loading Examples

// Compact Node mode (enabled by default)
const fs = require('fs'); // Works: resolves to node:fs
const path = require('path'); // Works: resolves to node:path
const os = require('os'); // Works: resolves to node:os

// ES Modules with compact mode
import fs from 'fs'; // Works: resolves to node:fs
import http from 'http'; // Works: resolves to node:http

// Traditional explicit prefixes
const fs2 = require('node:fs'); // Explicit prefix
const process = require('jsrt:process'); // jsrt namespace

// Remote modules
import config from 'https://cdn.example.com/config.js';

// Standard npm packages
const lodash = require('lodash');
const axios = require('axios');

Module System Architecture

QuickJS Module System
    │
    │ JS_SetModuleLoaderFunc(normalize_callback, loader_callback)
    ▼
ES Module Bridge → Module Loader Core
    │                 ├─► Cache System (FNV-1a hash)
    │                 ├─► Path Resolver (Node.js-compatible)
    │                 ├─► Format Detector (CJS/ESM/JSON)
    │                 ├─► Protocol Handlers (file/http/https)
    │                 └─► Module Loaders (format-specific)

Performance: 85-95% cache hit rates with minimal overhead Memory Safety: Comprehensive error handling with 60+ error codes Compatibility: Full Node.js resolution algorithm implementation

See docs/module-system-architecture.md and docs/module-system-api.md for complete implementation details.

🧱 Node.js Compatibility

The node: compatibility layer mirrors core Node.js modules while keeping the runtime lightweight:

Implemented Modules (10+ Core Modules - 100% Test Coverage)

Module Support Test Status Notes
assert ✅ Full 100% pass All assertion methods
buffer ✅ Full 100% pass ArrayBuffer-backed buffers
crypto 🟡 Partial 100% pass Common hash/cipher algorithms
dns 🟡 Partial 100% pass Basic lookup functions
events ✅ Full 100% pass EventEmitter implementation
fs 🟡 Partial 100% pass Sync methods + core async methods
http/https ✅ Full 100% pass Server & client (llhttp-based)
net ✅ Full 100% pass TCP sockets
os ✅ Full 100% pass System information
path ✅ Full 100% pass Path manipulation
process 🟡 Partial 100% pass Core properties & methods
querystring ✅ Full 100% pass URL query parsing
stream ✅ Full 100% pass All stream types
timers ✅ Full 100% pass setTimeout/setInterval
url ✅ Full 100% pass URL parsing & formatting
util 🟡 Partial 100% pass Common utilities

🎯 Test Achievement: 288 Node.js compatibility tests passing (100% pass rate)

npm Package Compatibility

🚀 Milestone Achieved: 73.3% npm compatibility success rate (2025-11-07)

✅ Known to Work:

  • Pure JavaScript packages (lodash, dayjs, chalk, etc.)
  • HTTP clients (axios, node-fetch patterns)
  • Simple web frameworks (basic Express routes)
  • JSON processing packages
  • Utility libraries and validation tools

⚠️ Known Limitations:

  • Native addons (.node files) - FFI is experimental
  • Packages requiring full Node.js fs async API
  • Worker threads - not implemented
  • Child processes - not implemented

📊 Compatibility Testing:

# Test a specific package
./bin/jsrt -e "require('package-name')"

# Run comprehensive npm compatibility tests
make test N=node    # Tests all Node.js modules

Compact Node Mode: Enabled by default - allows require('fs') instead of require('node:fs')

# These are equivalent with compact mode (default)
const fs = require('fs');           // Works
const fs2 = require('node:fs');      // Also works

# Disable compact mode if needed
./bin/jsrt --no-compact-node script.js

Refer to docs/nodejs-compatibility-layer.md and docs/compact-node-implementation.md for detailed implementation.

🛠️ API Reference

Web Standard APIs (WinterCG Compatible)

✅ Fully Implemented (100% WPT Pass Rate) - Click to expand
API Global Object Description
Console console log, error, warn, info, debug, assert, time, timeEnd
Performance performance performance.now(), performance.timeOrigin
HR-Time - High-resolution timing APIs
Timers setTimeout, setInterval Timer functions with libuv backend
URL URL, URLSearchParams URL constructor and search params
WebCrypto crypto getRandomValues, randomUUID, subtle.*
Encoding TextEncoder, TextDecoder Text encoding/decoding
Streams ReadableStream, WritableStream Streams API implementation
Base64 btoa, atob Base64 encoding/decoding
AbortController AbortController, AbortSignal Cancelable async operations
🔧 JSRT-Specific Extensions - Click to expand
Module Usage Description
jsrt:process import process from 'jsrt:process' Process info: argv, pid, platform, arch, version, uptime
jsrt:assert const assert = require('jsrt:assert') Testing assertions
jsrt:ffi const ffi = require('jsrt:ffi') Foreign Function Interface (experimental)
WebAssembly WebAssembly.Module, .Instance Full WebAssembly support via WAMR
Build System jsrt build command Bytecode compilation and standalone binary creation
⚠️ Browser-Dependent (Partially Implemented) - Click to expand
API Status Notes
Fetch 🟡 Working fetch, Request, Response, Headers (3 browser-specific WPT tests skipped)
FormData 🟡 Partial Basic FormData API
Blob 🟡 Partial Basic Blob API
DOM ⚠️ Limited Minimal DOM utilities

📊 Web Standards Compliance

JSRT achieves excellent WinterCG Minimum Common API compliance:

Overall Progress: 90.6% WPT Pass Rate (29/32 tests passed, 0 failed, 3 skipped)

API Category Tests Status Pass Rate
Console API 3 ✅ Complete 100%
Performance API 1 ✅ Complete 100%
HR-Time API 1 ✅ Complete 100%
Timer Functions 4 ✅ Complete 100%
URL API 10 ✅ Complete 100%
Encoding API 5 ✅ Complete 100%
WebCrypto API 1 ✅ Complete 100%
Base64 Utilities 1 ✅ Complete 100%
Streams API 2 ✅ Complete 100%
Abort API 1 ✅ Complete 100%
Fetch API 3 ⚠️ Skipped Browser-specific

🎯 Achievement: All WPT tests now pass except for 3 browser-specific Fetch API tests that require DOM/browser environment features not applicable to server-side runtimes.

WPT Test Categories

  • Console: logging, assertions, timing methods
  • Performance: timing measurements, performance.now()
  • HR-Time: high-resolution timestamps
  • Timers: setTimeout, setInterval, clearTimeout, clearInterval
  • URL: URL parsing, URLSearchParams manipulation
  • Encoding: TextEncoder, TextDecoder, btoa, atob
  • WebCrypto: getRandomValues, randomUUID, subtle crypto
  • Base64: base64 encoding/decoding utilities
  • Streams: ReadableStream, WritableStream, TransformStream
  • Abort: AbortController, AbortSignal for cancelable operations

See docs/WPT.md for detailed WPT integration and compliance status.

🗺️ Roadmap

Phase 1: Foundation (✅ Completed)

  • Core runtime with QuickJS + libuv integration
  • Advanced module system (unified pipeline, FNV-1a caching, protocol handlers)
  • Web Standard APIs (90.6% WPT compliance, 29/32 tests passed)
  • WebAssembly support (WAMR-based synchronous APIs)
  • Node.js compatibility layer (10+ modules, 100% test coverage)
  • npm compatibility milestone (73.3% success rate)
  • Compact Node mode (enabled by default)
  • Comprehensive testing (288 tests passing)

Phase 2: Enhancement (🔄 In Progress - Q4 2025)

  • Complete Node.js compatibility (target: 30+ core modules)
    • Full fs async API
    • Child process support
    • Worker threads
  • Improve Fetch API for non-browser environments
  • WebAssembly async APIs (compile(), instantiate())
  • Enhanced FFI - Move from proof-of-concept to production-ready
  • Package manager integration - Improve npm compatibility

Phase 3: Performance & Stability (📅 Q1 2026)

  • Performance optimization
    • JIT compilation exploration
    • Memory usage optimization
    • Startup time improvements
  • Comprehensive test coverage (target: 90%+ code coverage)
  • Benchmark suite - Track performance metrics
  • Memory leak detection - Automated leak checking in CI
  • Fuzzing integration - Security and stability testing

Phase 4: Ecosystem & Tools (📅 Q2 2026)

  • Package manager - Native package installation (jsrt install)
  • Debugger integration - Chrome DevTools protocol
  • TypeScript support - Built-in .ts execution
  • Source maps - Better error stack traces
  • Plugin system - Native extension loading
  • Documentation site - Comprehensive docs and examples

Phase 5: Production Ready (🎯 H2 2026)

  • Stability hardening - Production-grade error handling
  • Security audit - External security review
  • 1.0 Release - API stability guarantees
  • Enterprise features
    • Monitoring & observability hooks
    • Resource limits & sandboxing
    • Multi-isolate support
  • Cloud deployment templates - AWS Lambda, Cloudflare Workers, etc.

Long-term Vision

  • Edge-first runtime - Optimized for serverless and edge computing
  • WebAssembly Component Model - Full component support
  • AI/ML integration - Native tensor operations, model inference
  • Distribution platform - Public registry for JSRT packages

Want to contribute? Check our Contributing Guidelines and open issues.

🏗️ Architecture

JSRT is built on proven technologies:

  • QuickJS - Fast, small JavaScript engine
  • libuv - Cross-platform asynchronous I/O library
  • WAMR - WebAssembly Micro Runtime
  • Custom Standard Library - Web standards compliant APIs
┌─────────────────┐
│   JavaScript    │
│     Code        │
├─────────────────┤
│  JSRT Runtime   │
│   (std lib)     │
├─────────────────┤
│    QuickJS      │
│   (JS engine)   │
├─────────────────┤
│     libuv       │
│   (async I/O)   │
├─────────────────┤
│   OS Platform   │
└─────────────────┘

🏗️ Development

Prerequisites

Tool Version Purpose
GCC 7.0+ C compiler
Make 3.81+ Build system
CMake 3.16+ Build configuration
clang-format Latest Code formatting

Building

# Clone and build
git clone https://github.com/leizongmin/jsrt.git
cd jsrt
git submodule update --init --recursive
make

# Build variants
make jsrt      # Release build (default, optimized)
make jsrt_g    # Debug build with symbols
make jsrt_m    # Debug build with AddressSanitizer
make jsrt_cov  # Coverage instrumentation build

Testing

# Run all tests
make test

# Run specific test directory
make test N=module     # Test module system
make test N=node       # Test Node.js compatibility

# Run Web Platform Tests
make wpt               # Full WPT suite (32 tests, 90.6% pass rate)
make wpt N=console     # Specific WPT category
make wpt-quick         # Essential tests only

# Generate coverage report
make coverage          # Regular test coverage
make coverage-merged   # Combined regular + WPT coverage
# Reports available at: target/coverage/html/index.html

Debugging

# Memory debugging with AddressSanitizer
./bin/jsrt_m script.js
ASAN_OPTIONS=detect_leaks=1 ./bin/jsrt_m script.js

# Single file testing with timeout
timeout 20 ./bin/jsrt test/specific-test.js

# Code formatting (mandatory before commits)
make clang-format

Development Environment

🐳 VS Code Dev Container

  1. Install VS Code and the Dev Containers extension.
  2. Open the repository in VS Code and choose Reopen in Container.
  3. Start hacking—build tools, submodules, and formatting utilities are pre-installed.

🤖 Claude Code Docker Environment

make docker-build    # Build the development image (once)
make claude          # Launch Claude Code with /repo mapped to the project
make claude-shell    # Drop into an interactive container shell

🧪 Testing & Debugging

# Comprehensive testing
make test            # 288 unit tests (100% pass rate)
make wpt             # Web Platform Tests (90.6% pass rate)

# Debug builds and testing
make jsrt_g          # Debug build with JSRT_Debug logging
make jsrt_m          # AddressSanitizer build for memory debugging
ASAN_OPTIONS=detect_leaks=1 ./bin/jsrt_m script.js

# Development workflow (MANDATORY before commits)
make format && make test && make wpt

🚀 Advanced Usage

Cross-Compilation with Zig

Install Zig compiler for cross-platform builds:

# Install Zig (version 0.13.0+)
wget https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz
tar -xf zig-linux-x86_64-0.13.0.tar.xz
sudo mv zig-linux-x86_64-0.13.0 /opt/zig
sudo ln -s /opt/zig/zig /usr/local/bin/zig

Cross-compile for different targets:

# Linux musl (static linking)
CC="zig cc -target x86_64-linux-musl" make clean all

# Windows
CC="zig cc -target x86_64-windows-gnu" make clean all

# macOS
CC="zig cc -target x86_64-macos-none" make clean all

# ARM64 Linux
CC="zig cc -target aarch64-linux-gnu" make clean all

Performance Tuning

# Release build with optimizations
CFLAGS="-O3 -DNDEBUG" make jsrt

# Profile-guided optimization
CFLAGS="-fprofile-generate" make jsrt
./bin/jsrt examples/benchmark.js  # Run representative workload
CFLAGS="-fprofile-use" make clean jsrt

❓ FAQ

Q: Can I use npm packages? A: Pure JavaScript packages work well. Native modules (.node files) are experimental via FFI. Test with: ./bin/jsrt -e "require('package-name')"

Q: How does JSRT compare to QuickJS CLI? A: JSRT adds libuv event loop, Web Standard APIs, Node.js compatibility layer, module system with HTTP(S) loading, and WebAssembly support.

Q: Is it production-ready? A: Not yet. JSRT is experimental and under active development. Use for learning, prototyping, and non-critical projects.

Q: Why not use Bun/Deno instead? A: JSRT targets minimal binary size (~2MB vs 50-90MB) for embedded systems, edge computing, and resource-constrained environments.

Q: What's the relationship with Node.js? A: JSRT implements a Node.js-compatible API surface but is a completely separate runtime built on QuickJS instead of V8.

Q: How can I contribute? A: See our Contributing Guidelines below. We welcome bug reports, feature requests, and pull requests!

🆘 Troubleshooting

Common Issues

"Module not found" error

# Check module resolution
./bin/jsrt -e "console.log(require.resolve('module-name'))"

# For built-in modules, use proper prefix
./bin/jsrt -e "const fs = require('node:fs')"  # Correct
./bin/jsrt -e "const fs = require('fs')"       # May fail

Segmentation fault

# Run with AddressSanitizer to locate issue
make jsrt_m
./bin/jsrt_m your-script.js

Memory leak

# Enable leak detection
ASAN_OPTIONS=detect_leaks=1 ./bin/jsrt_m your-script.js

Test timeout

# Use timeout for hanging scripts
timeout 20 ./bin/jsrt test/problematic-test.js

Build errors

# Ensure submodules are initialized
git submodule update --init --recursive

# Clean and rebuild
make clean
make

More help: GitHub IssuesGitHub Discussions

🤝 Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes and ensure tests pass: make test
  4. Run WPT tests: make wpt to check web standards compliance
  5. Format your code: make clang-format && make prettier
  6. Commit with a clear message: git commit -m "Add amazing feature"
  7. Push to your branch: git push origin feature/amazing-feature
  8. Open a Pull Request

Development Guidelines

  • Follow existing code style and conventions
  • Add tests for new features (prefer WPT-compatible tests)
  • Update documentation as needed
  • Ensure make test, make wpt, and make clang-format pass
  • Check WPT compliance for web standard APIs
  • See AGENTS.md for detailed development setup

Good First Issues

Looking to contribute? Check out issues labeled good first issue for beginner-friendly tasks.

Development Priorities

Current Focus Areas:

  1. Complete Node.js compatibility layer (target: 30+ modules)
  2. Enhance Fetch API for non-browser environments
  3. Improve FFI from proof-of-concept to production-ready
  4. Expand test coverage and documentation
  5. Performance optimization and benchmarking

📄 License

MIT License - see LICENSE file for details

Copyright © 2024-2025 LEI Zongmin


Built with ❤️ using AI-assisted development

⭐ Star this repo🐛 Report Bug💬 Discussions

About

A lightweight, fast JavaScript runtime built on QuickJS and libuv

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 72.0%
  • JavaScript 26.2%
  • CMake 0.7%
  • Python 0.5%
  • Makefile 0.3%
  • Shell 0.2%
  • Batchfile 0.1%