What is nstd?

A small, standalone JavaScript runtime that runs Node.js programs without Node.js installed.

nstd runs a JavaScript file much like node script.js does, but it is a single small executable with no Node.js installation behind it:

nstd script.js

It pairs the QuickJS-NG JavaScript engine with nstdlib, a portable copy of Node's own standard library. You can build it as a native executable (about 5 MB) or as a WebAssembly module for WASI (about 4.6 MB). A browser build is planned.

#Why use it?

  • Nothing else to install. The executable is the whole runtime, engine and standard library included. Ship one file and you're done.
  • It starts fast. The standard library is compiled into the binary as bytecode, so nothing has to be parsed before your first line of code runs.
  • It's small. About 5 MB for the native executable and about 4.6 MB for the WebAssembly module.
  • It runs where a JIT can't. QuickJS-NG is an interpreter and never generates machine code at run time, so nstd also fits restricted platforms such as iOS.

nstd is a good fit for small command-line tools, for adding a scripting layer to another program, or simply for seeing how far a Node-compatible runtime built from scratch can go.

#How it works

nstd is built from four parts:

  • QuickJS-NG runs your JavaScript. It trades raw speed for low memory use and fast startup.
  • A host written in Zig talks to the operating system: files, sockets, file watching, TLS connections and child processes. This is what turns a library that could run anywhere into a runtime that runs here.
  • nstdlib provides fs, http, path, events and the rest of Node's standard library, compiled in as bytecode.
  • A handful of bundled libraries fill in the rest: Undici for fetch and other web APIs, ada for URL parsing, merve for CommonJS analysis, llhttp for HTTP parsing, Mbed TLS for secure connections, zlib and Brotli's decoder for compression, and wasm3 for WebAssembly.

#How it differs from Node.js

nstd is not Node with a different launcher. Almost nothing underneath is shared:

Node.jsnstd
JavaScript engineV8QuickJS-NG (no JIT)
Event loop and I/Olibuva small Zig host on poll(2)
TLSOpenSSLMbed TLS

Two pieces are the same: the URL parser and the CommonJS lexer are the exact C/C++ libraries Node itself ships, compiled straight into the binary, so those behave exactly like Node.

Because so little is shared, compatibility is measured rather than assumed. Much of the standard library works as you'd expect, and some things don't yet. For example, there is no TLS server, and a few command-line options Node accepts are rejected. Node.js Compatibility has the details.

#Status

nstd is experimental. It is not yet a general-purpose replacement for Node. A large and growing share of Node's behavior works correctly, and every known gap is tracked and documented rather than hidden.

#Next steps

  • Installation shows how to build nstd from source, which is currently the only way to get it.
  • If you want the standard library itself, to use in a browser, a worker, a bundler or Node, rather than a standalone executable, read What is nstdlib?