Code Mode Unified supports multiple JavaScript/TypeScript runtimes, each with unique characteristics, strengths, and limitations.
| Feature | QuickJS | Bun | Deno | isolated-vm | E2B |
|---|---|---|---|---|---|
| Status | ✅ Production | ✅ Production | 🚧 In Progress | 🚧 In Progress | 🚧 In Progress |
| Async/Await | ❌ | ✅ | ✅ | ✅ | ✅ |
| TypeScript | ❌ | ✅ | ✅ | ❌ | ✅ |
| Startup Time | ~5ms | ~10ms | ~15ms | ~3ms | ~200ms |
| Memory | ~3MB | ~90MB | ~50MB | ~10MB | ~512MB |
| Isolation | WASM | Process | Process | V8 Isolate | Cloud VM |
| In-Process | ✅ | ❌ | ❌ | ✅ | ❌ |
| Cloud-Based | ❌ | ❌ | ❌ | ❌ | ✅ |
| Cost | Free | Free | Free | Free | Paid |
Best For: Lightweight execution, embedded scenarios, untrusted code
- Tiny footprint: ~3MB memory, ~600KB binary
- Fast startup: 5-10ms initialization
- True isolation: WASM-based sandboxing
- Cross-platform: Runs anywhere with WASM support
- Deterministic: Predictable execution behavior
- No dependencies: Self-contained runtime
- No async/await: Synchronous execution only
- ES2020 only: Limited modern JavaScript features
- No TypeScript: Requires pre-compilation
- Performance: Slower execution vs V8/JSC
- Limited stdlib: Minimal built-in APIs
// ❌ NOT SUPPORTED
async function fetchData() {
await fetch('...');
}
const result = await somePromise;
// ✅ WORKAROUND: Two-pass execution
var result = mcp.fetch.getData(); // Returns placeholder first pass
console.log(result); // Actual data on second pass- Embedding in applications
- Untrusted user scripts
- Resource-constrained environments
- Simple synchronous workflows
- Maximum security isolation
Best For: Modern JavaScript/TypeScript, high performance, full ES2024+ support
- Full async/await: Native Promise support
- TypeScript native: No compilation needed
- Fast: JavaScriptCore engine (Safari)
- Modern ES: ES2024+ features
- npm compatible: Use existing packages
- Built-in tooling: Bundler, test runner, package manager
- Large runtime: ~90MB overhead
- Subprocess: Slower startup than in-process
- Limited permissions: No fine-grained controls
- Newer ecosystem: Less mature than Node/Deno
- Process isolation only: No V8 isolate-level control
// ✅ FULLY SUPPORTED
async function processData() {
const data = await fetch('https://api.example.com');
return await data.json();
}
// TypeScript works out of the box
interface User {
name: string;
email: string;
}
const user: User = { name: 'Alice', email: 'alice@example.com' };- Modern JavaScript workflows
- TypeScript-first projects
- Async-heavy operations
- npm package integration
- Development environments
Best For: Secure by default, TypeScript, fine-grained permissions
- Security first: Explicit permissions required
- TypeScript native: Built-in support
- Modern standards: Web APIs, ES modules
- Fine-grained permissions: Control file/network/env access
- V8 engine: Fast execution
- Standard library: Comprehensive built-in modules
- Permission complexity: Requires careful configuration
- --allow-run escape: Subprocess can bypass sandbox
- Module ecosystem: Different from npm
- Subprocess overhead: Not in-process
- Configuration verbosity: Many permission flags
// ✅ SUPPORTED WITH PERMISSIONS
await Deno.readTextFile('./data.txt'); // Requires --allow-read
await fetch('https://api.com'); // Requires --allow-net
// ⚠️ SECURITY RISK
Deno.run({ cmd: ['bash', '-c', 'rm -rf /'] }); // --allow-run bypasses everything
// ✅ RECOMMENDED: Use OS-level sandboxing (chroot, cgroups)- Security-sensitive applications
- TypeScript projects
- Web-standard APIs
- Controlled environment execution
- Compliance requirements
Best For: Enterprise production, deterministic execution, high throughput
- In-process: Millisecond startup
- V8 isolates: True isolation without processes
- Deterministic: Reproducible execution
- Production-proven: Used by Temporal, Algolia
- High throughput: Concurrent isolate execution
- Memory efficient: Shared V8 heap
- Maintenance mode: No new features (v6.0.1)
- Node 16+ required: Specific runtime dependencies
- No TypeScript: Requires pre-compilation
- Complex API: Steeper learning curve
- V8 dependency: Tied to V8 engine versions
// ✅ FULLY SUPPORTED
async function compute() {
const result = await heavyComputation();
return result;
}
// ❌ NOT SUPPORTED
// TypeScript requires pre-compilation with tsc
// ✅ DETERMINISTIC EXECUTION
// Same input always produces same output
// Useful for workflow engines, testing, reproducibility- Enterprise workflow engines
- High-throughput APIs
- Deterministic computations
- In-process sandboxing
- Temporal/workflow systems
Best For: Complete isolation, untrusted code, multi-language support
- Complete isolation: Full VM per execution
- Multi-language: JavaScript, Python, Go, etc.
- Cloud-managed: No infrastructure management
- Secure by design: Network-isolated VMs
- Scalable: Auto-scaling infrastructure
- File system access: Full Linux environment
- Paid service: Costs per execution
- Network latency: Cloud API calls
- Slow startup: ~200ms VM initialization
- API dependency: Requires internet connectivity
- Cost at scale: Can be expensive for high volume
// ✅ FULL LINUX ENVIRONMENT
await fs.writeFile('/tmp/data.txt', 'content');
await execSync('bash script.sh');
// ⚠️ LATENCY CONSIDERATION
// Cold start: ~200ms
// Warm execution: ~50ms
// ✅ USE FOR: Untrusted user code, multi-language, complex operations
// ❌ AVOID FOR: High-frequency simple operations, latency-sensitive- User-generated code execution
- Multi-language support needs
- Complete environment isolation
- Complex dependency requirements
- Low-frequency high-value operations
┌─ Need TypeScript? ─────────────────────┐
│ YES: Bun, Deno, E2B │
│ NO: QuickJS, isolated-vm │
└───────────────────────────────────────┘
┌─ Need async/await? ────────────────────┐
│ YES: Bun, Deno, isolated-vm, E2B │
│ NO: QuickJS (two-pass pattern) │
└───────────────────────────────────────┘
┌─ Priority: Startup time? ──────────────┐
│ <5ms: isolated-vm (3ms) │
│ <10ms: QuickJS (5ms) │
│ <20ms: Bun (10ms), Deno (15ms) │
│ OK with 200ms: E2B │
└───────────────────────────────────────┘
┌─ Priority: Memory usage? ──────────────┐
│ Minimal: QuickJS (3MB) │
│ Low: isolated-vm (10MB) │
│ Medium: Deno (50MB) │
│ High: Bun (90MB), E2B (512MB) │
└───────────────────────────────────────┘
┌─ Priority: Security isolation? ────────┐
│ Maximum: E2B (Cloud VM) │
│ High: QuickJS (WASM), Deno (perms) │
│ Good: isolated-vm (V8), Bun (proc) │
└───────────────────────────────────────┘
┌─ Cost tolerance? ──────────────────────┐
│ Free only: QuickJS, Bun, Deno, │
│ isolated-vm │
│ Paid OK: E2B │
└───────────────────────────────────────┘
import { RuntimeFactory, RuntimeType } from './runtime/base-runtime.js';
const runtime = await RuntimeFactory.create({
type: RuntimeType.QUICKJS,
maxWorkers: 4,
idleTimeout: 30000,
defaultTimeout: 30000,
memoryLimit: 134217728 // 128MB
});
const result = await runtime.execute(`
var result = mcp.memory.getData();
console.log(result);
`);const runtime = await RuntimeFactory.create({
type: RuntimeType.BUN,
maxWorkers: 2,
defaultTimeout: 30000,
bun: {
bunPath: '/usr/local/bin/bun'
}
});
const result = await runtime.execute(`
async function fetchData() {
const response = await fetch('https://api.example.com');
return await response.json();
}
await fetchData();
`);const runtime = await RuntimeFactory.create({
type: RuntimeType.DENO,
maxWorkers: 2,
defaultTimeout: 30000,
deno: {
denoPath: '/usr/local/bin/deno',
permissions: [
'--allow-net=api.example.com',
'--allow-read=/tmp'
]
}
});const runtime = await RuntimeFactory.create({
type: RuntimeType.ISOLATED_VM,
maxWorkers: 10,
defaultTimeout: 30000,
isolatedVm: {
memoryLimit: 128, // MB
inspector: false
}
});const runtime = await RuntimeFactory.create({
type: RuntimeType.E2B,
maxWorkers: 1,
defaultTimeout: 60000,
e2b: {
apiKey: process.env.E2B_API_KEY,
templateId: 'nodejs-20'
}
});isolated-vm: █░░░░░░░░░ 3ms
QuickJS: ██░░░░░░░░ 5ms
Bun: ████░░░░░░ 10ms
Deno: ██████░░░░ 15ms
E2B: ████████████████████ 200ms
isolated-vm: █░░░░░░░░░ 1ms
Bun: ██░░░░░░░░ 2ms
QuickJS: ███░░░░░░░ 3ms
Deno: ███░░░░░░░ 3ms
E2B: ████████░░ 8ms (+ network)
QuickJS: █░░░░░░░░░ 3MB
isolated-vm: ███░░░░░░░ 10MB
Deno: ████████████████░░░░ 50MB
Bun: ████████████████████████████ 90MB
E2B: [Cloud managed] 512MB+
isolated-vm: 10,000+
QuickJS: 5,000+
Bun: 3,000+
Deno: 2,500+
E2B: 500+ (network dependent)
Reasons: Need async/await, TypeScript, modern JS features
Changes Required:
- Convert two-pass MCP pattern to native async
- Can use TypeScript directly
- Update configuration to Bun runtime
// QuickJS (before)
var data = mcp.api.getData(); // Two-pass execution
console.log(data);
// Bun (after)
const data = await mcp.api.getData(); // Native async
console.log(data);Reasons: Need higher throughput, deterministic execution, production hardening
Changes Required:
- Minimal code changes (both support similar JS subset)
- Better async support in isolated-vm
- Update configuration
Reasons: Need complete isolation, multi-language, complex dependencies
Changes Required:
- Full environment available
- Can use filesystem, subprocesses
- Budget for API costs
Best Choice: Bun or Deno
- Fast iteration with TypeScript
- Modern language features
- Good debugging experience
Best Choice: isolated-vm
- In-process execution
- V8 performance
- Proven at scale (Temporal, Algolia)
Best Choice: QuickJS
- Minimal footprint
- Cross-platform WASM
- No external dependencies
Best Choice: E2B (if budget allows) or QuickJS
- Complete isolation (E2B: VM, QuickJS: WASM)
- No escape vectors
- Controlled environment
Best Choice: isolated-vm
- Deterministic execution
- Production-proven
- High reliability
Best Choice: E2B
- JavaScript, Python, Go, etc.
- Full Linux environment
- Complex dependency trees
Each runtime has a comprehensive test suite:
# Test all runtimes
npm run test:runtimes
# Test specific runtime
npm run test:runtime:quickjs
npm run test:runtime:bun
npm run test:runtime:deno
npm run test:runtime:isolated-vm
npm run test:runtime:e2b
# Test runtime-specific constraints
npm run test:constraints- QuickJS - Production ready
- Bun - Production ready
- Deno - In progress (80% complete)
- isolated-vm - Planned (Q1 2025)
- E2B - Planned (Q1 2025)
When implementing a new runtime:
- Extend
BaseRuntimeclass - Implement all required methods
- Add runtime-specific configuration
- Create comprehensive test suite
- Document capabilities and constraints
- Add benchmarks
- Update this comparison guide
- QuickJS: https://bellard.org/quickjs/
- Bun: https://bun.sh
- Deno: https://deno.land
- isolated-vm: https://github.com/laverdet/isolated-vm
- E2B: https://e2b.dev