Skip to content

BlueJS: Compiling JavaScript to 1.2MB Native Binaries Without V8

BlueJS is a groundbreaking new compiler that turns JavaScript into tiny native binaries without bundling V8. We explore how it works, what it's good for, and where it fits in the future of JavaScript deployment.

Author
Devanshu Verma
Published
Reading time
5 min read
On this page10 sections

πŸ’‘ TL;DR: BlueJS is a new JavaScript-to-native compiler that produces standalone executables weighing just 1.2MB β€” without shipping the V8 engine. This could be a game-changer for CLI tools, serverless, and embedded use cases.

Introduction

For most of JavaScript's history, running JS outside a browser has meant shipping a JavaScript engine β€” typically V8 β€” alongside your code. Node.js does this. Deno does this. Bun brings its own engine (JavaScriptCore). Even tools like pkg and nexe that produce "standalone" Node.js binaries still bundle the entire Node runtime, resulting in executables often exceeding 40–80MB.

Enter BlueJS: a compiler that takes your JavaScript source and emits a genuine native binary. Not "native with a hidden runtime tucked inside." A real, lean, machine-code executable at just 1.2MB.

This post explores how BlueJS works, where it fits into the ecosystem, and what it means for the future of JavaScript deployment.

The Problem with Existing Approaches

Bundled Runtime (pkg, nexe, Node SEA)

Tools like pkg, nexe, or Node.js's experimental Single Executable Applications (SEA) all solve the distribution problem by bundling the Node.js runtime with your app. This works but has real costs:

Tool Typical Binary Size V8 Included?
pkg ~40–80 MB βœ… Yes
nexe ~35–70 MB βœ… Yes
Node SEA ~30–60 MB βœ… Yes
Bun compile ~10–15 MB βœ… Yes (JSC)
BlueJS ~1.2 MB ❌ No

The Cold Start Tax

In serverless environments like AWS Lambda or Cloudflare Workers, binary size directly impacts cold start time. A 60MB binary that needs to initialize V8 is orders of magnitude slower to boot than a 1.2MB native binary that starts executing machine instructions immediately.

How Does BlueJS Work?

BlueJS uses Ahead-of-Time (AOT) compilation to convert JavaScript into native machine code. Here's a simplified view of the pipeline:

JavaScript Source (.js)
        β”‚
        β–Ό
   Parsing & AST Generation
        β”‚
        β–Ό
   Type Inference & Analysis
        β”‚
        β–Ό
   IR (Intermediate Representation)
        β”‚
        β–Ό
   Native Code Generation (LLVM)
        β”‚
        β–Ό
   Native Binary (.exe / ELF / Mach-O)

Key Techniques Under the Hood

1. Static Type Inference JavaScript is dynamically typed, but BlueJS analyzes your code statically to infer types where possible. Inferred types allow the compiler to emit more efficient machine code β€” skipping dynamic dispatch and type checks at runtime.

2. Escape Analysis & Stack Allocation BlueJS determines which objects never "escape" their local scope and allocates them on the stack instead of the heap, drastically reducing garbage collection pressure.

3. LLVM Backend The compiler targets LLVM IR, which means it benefits from decades of optimization research built into LLVM β€” including loop unrolling, inlining, vectorization, and dead code elimination.

4. Minimal Runtime Rather than a full JS engine, BlueJS ships with a tiny runtime stub that provides only what's strictly needed: basic memory management, a minimal standard library, and OS interfacing. This is what keeps the binary at 1.2MB.

Getting Started with BlueJS

Installation is straightforward:

bash
npm install -g bluejs-compiler

Compiling your first script:

bash
bluejs compile app.js --output app
./app

For cross-compilation to different targets:

bash
# Compile for Linux x64
bluejs compile app.js --target linux-x64 --output app-linux

# Compile for macOS ARM64
bluejs compile app.js --target darwin-arm64 --output app-macos

# Compile for Windows x64
bluejs compile app.js --target win32-x64 --output app.exe

Real-World Use Cases

1. CLI Tools

Distributing a CLI tool as a native binary means zero install friction. No npm install, no Node.js prerequisite, no PATH issues. Users just download and run:

bash
# Before BlueJS: user needs Node.js installed
npm install -g my-awesome-cli

# After BlueJS: just a binary download
curl -L https://releases.myapp.com/my-awesome-cli-linux && chmod +x my-awesome-cli-linux

2. Serverless Functions

Tiny binaries mean dramatically faster cold starts. A BlueJS-compiled Lambda function could start in under 5ms, compared to 200–500ms for a Node.js Lambda that needs to initialize the runtime and parse your bundle.

3. Embedded & IoT Systems

Running JavaScript logic on resource-constrained hardware has always been challenging. BlueJS opens the door to deploying JS-based business logic on devices with limited RAM and storage where V8 is simply not an option.

4. Edge Computing

Shipping a 1.2MB binary to edge nodes worldwide is trivially fast. This makes BlueJS a compelling option for building edge-native JavaScript services.

Current Limitations

BlueJS is powerful, but it's not a silver bullet. Here are the important limitations to understand before adopting it:

Dynamic Features

JavaScript's most dynamic features are difficult or impossible to AOT-compile:

js
// These patterns may not work in BlueJS:
eval("console.log('hello')");               // ❌ eval
new Function("return 42")();               // ❌ Function constructor
const mod = require(someVariable);         // ❌ Dynamic require
const prop = obj[computedKey];             // ⚠️  Limited support

npm Ecosystem Compatibility

Not all npm packages will work. Packages that rely on Node.js-specific APIs (fs, net, child_process, etc.) will need compatibility shims or may be unsupported. Pure utility libraries (lodash, zod, date-fns) are far more likely to work out of the box.

No JIT Optimization

V8's JIT compiler is extraordinarily good at optimizing hot paths at runtime based on actual usage patterns. BlueJS's AOT compilation produces good static code, but may not match V8's peak throughput for compute-intensive workloads.

BlueJS vs. The Ecosystem

Feature Node.js + pkg Bun compile BlueJS
Binary size 40–80MB 10–15MB 1.2MB
npm compatibility βœ… Full βœ… High ⚠️ Partial
Dynamic JS support βœ… Full βœ… Full ⚠️ Limited
Cold start speed Slow Fast Very Fast
Maturity Stable Stable Experimental

The Bigger Picture

BlueJS represents a fascinating new direction for JavaScript. We're increasingly seeing the language break free from its runtime monoculture (V8 everywhere). Between Bun's JavaScriptCore, Deno's V8 sandbox, WasmGC-based JS engines, and now AOT compilers like BlueJS, the ecosystem is diversifying in exciting ways.

πŸš€ The future of JavaScript isn't one runtime β€” it's the right runtime for each deployment target.

Key Takeaways

  • BlueJS compiles JavaScript to native binaries at just 1.2MB β€” without V8
  • It uses AOT compilation via LLVM, static type inference, and a minimal runtime
  • Best suited for CLI tools, serverless functions, embedded systems, and edge computing
  • Not a drop-in replacement for Node.js β€” dynamic JS features and full npm compatibility are limitations
  • Still experimental, but worth watching closely

Resources

Found this useful? Pass it on.

Devanshu Verma

Frontend engineer building web apps with React, Next.js, Angular and Vue.