A JavaScript engine (e.g. V8, JavaScriptCore) executes JavaScript code. It doesn't know about things like files, HTTP requests, or timers.On the other hand, a JavaScript runtime (e.g. Node.js, Bun) is a more complete environment where JavaScript runs. It contains a JavaScript engine, extra APIs, an event loop and task queues, and platform-specific features.That's what I'm hacking on today: a tiny runtime with console.log, process.uptime(), setTimeout and clearTimeout, fs.readFileSync and fs.readFile, as well as an event loop and worker pool for file I/O. Built on top of QuickJS.Here's an example program it can run:const startedAt = process.uptime();console.log("runtime booted"); setTimeout(async () => { // Timers console.log("uptime:", process.uptime() - startedAt); // Sync I/O console.log("sync bytes:", fs.readFileSync("Makefile", "utf8").length); // Async I/O console.log("async bytes:", (await fs.readFile("Makefile", "utf8")).length);}, 100);Booting QuickJS from a Custom ExecutableQuickJS actually ships with a small shell/runtime built around qjs.c and a basic standard library, but I'm not going to re-use any of it. We'll start from scratch.So, to begin with, we need to boot QuickJS from a custom executable. The smallest useful embedder involves creating an instance of the engine (JSRuntime), an execution environment (JSContext), and a way to read a code file, evaluate it, and print any exceptions.int main(int argc, char **argv){ JSRuntime *rt = JS_NewRuntime(); JSContext *ctx = JS_NewContext(rt); int exit_code; // ... install globals later exit_code = run_file(ctx, argv[1]); // ... then run the event loop until timers / async work complete JS_FreeContext(ctx); JS_FreeRuntime(rt); return exit_code;}QuickJS runs JavaScript but we, the host, decide what the global environment looks like; what the input is, and how the outputs are returned to the user.static int run_file(JSContext *ctx, const char *path){ SourceFile source = {0}; JSValue result; int exit_code = 1; if...
First seen: 2026-03-26 18:14
Last seen: 2026-03-27 14:27