Skip to content

GoxA JavaScript Runtime Built from Scratch in Go

A complete lexer → parser → bytecode VM pipeline built from the ground up. Single binary, zero cgo, zero external dependencies, with a built-in software-rasterized GUI rendering layer — and your finished JS can be packaged into a standalone executable for direct distribution.

Gox — a JavaScript runtime built from scratch in Go

Up and Running in 30 Seconds ​

gox — REPL / run scripts / create projects
$ npm i -g @goxjs/goxjs
$ gox
Gox REPL (ES6 subset)
Type :exit to quit, :help for help
 
> let x = 10
> let y = 20
> x + y
  30
> [1, 2, 3].map(v => v * 2)
  [2, 4, 6]
>

You can also skip the install: npx goxjs app.js; or build from source with go build. See Installation and Creating a Project for details.

What It Actually Is ​

What it is

A JavaScript runtime written in Go with everything implemented from scratch, from lexical analysis to the bytecode virtual machine. Not a binding for V8, and not JS translated into Go.

What you can do with it

Run ES6+ scripts, write CLI tools, build desktop apps with windows, package scripts into a single executable to share with others, and use it to learn how compilers and VMs are built.

What it is not

It does not aim to replace the Node ecosystem in production: no npm compatibility, no require, no JIT, and no DOM. Treat it as an independent small language with a built-in UI framework.

The Compilation Pipeline ​

One clear pipeline, where every layer can be read and tested on its own.

.js sourceUTF-8 text
→
lexerTokenization → token stream
→
parserParsing → AST
→
compilerSymbol table + bytecode generation
→
vmStack-frame execution + event loop

Key design decisions: GC-free explicit memory management (with dedicated handling for circular references), a single-threaded VM with cross-goroutine scheduling (network callbacks are re-posted, so JS is always single-threaded and lock-free), and fixed-length instruction encoding (decoding is a simple fetch).

A Desktop GUI App in 16 Lines ​

js
import { createSignal } from "gx/solid";
import { h, render } from "gx/gfx";

const [count, setCount] = createSignal(0);

render(
  <window title="Counter" width={400} height={300}>
    <column gap={8} padding={16}>
      <text font={20}>{() => `count: ${count()}`}</text>
      <button onClick={() => setCount(c => c + 1)}>加一</button>
    </column>
  </window>
);
bash
gox counter.js          # Run directly — opens a 400x300 window
go run ./packager counter.js --gui -o counter.exe   # Package into a standalone GUI app

Passing a function as a prop or text makes it a reactive binding: signal update → dependent nodes marked dirty → dirty rectangles merged so only affected regions are redrawn. See the GUI desktop app tutorial for more.

Capability Overview ​

AreaWhat's coveredWhere to look
LanguageES6+ subset: let/const, arrow functions, class, async/await, destructuring, template literals, optional chaining, ES modules, JSXTutorial · Language Basics
Standard libraryObject / Array / String / Map / Set / Proxy / Promise / TypedArray / Temporal …API · Standard Built-ins
Host modules (no import)console / fs / path / process / http / fetchAPI · Host Modules
ReactivityGetX-style obs / computed, SolidJS-style gx/solid signalsTutorial · Reactivity
GUI44 built-in elements + JSX + dirty-rectangle partial redraw, routing, multi-windowComponent Reference
PlatformsDesktop Windows / Linux / macOS (win32 / X11 / cocoa) and mobile Android / iOS / HarmonyOS — platform shell projects driving the same rendering core, with one JS UI across all of themTutorial · GUI Apps
Built-in modules (import required)gx/solid · gx/gfx · gx/view · gx/router · gx/screen · gx/dialog · gx/storage · gx/dev plus the six native-capability modulesAPI · Built-in Modules
ToolchainREPL, gox create scaffolding, gox dev hot reload, jsbuild packaging, prebuilt npm binaries for five platformsTutorial · Installation

Versions and Current Status ​

Current version v0.9.0; see GitHub Releases for the full changelog.

VersionHighlights
0.9.0table / tree / list-item data-display components, tabs, and tooltip; design tokens and a theme system (32 colour tokens, dark preset, runtime switching); gx/update v1.1 auto-update (streaming download / resume / progress callbacks / pre channel); gox create --ts TypeScript / TSX template; var declarations and class expressions; runtime errors carry source-frame locations
0.8.0Test262 compliance pipeline (scheduled language suite runs, badge auto-writeback); gox vs node performance benchmark harness; stress and frame-budget tests (10k-timer storm / concurrent fetch / 489-node render budget); 3 sample apps (TODO / dashboard / Snake); computed property names; draggable scrollbars and horizontal scrolling
0.7.0gox cert to generate signing certificates for all platforms in one step, gox build android auto-wires signing, gox create generates a certs/ directory; gox build macos --arch universal (merged amd64+arm64); ordered multi-select photo picking on iOS and multi-file preview in media.preview
0.6.0macOS window backend cocoa (desktop GUI now covers all three platforms); gox dev hot reload, gox.json project config, unified gox build entry point
0.5.0Six built-in native-capability modules (gx/device · gx/app · gx/geo · gx/media · gx/permission · gx/viewport)
0.4.0gox create scaffolding; routing gx/router and screen gx/screen become built-in modules

Known Gaps

Rich text (inline mixed styling) is not yet wrapped (virtualized long lists landed as <scroll vlist>) — the table / tree / tooltip / icon / spinner / tabs data-display and feedback widgets all landed in 0.9.0; parts of the native-capability layer that depend on real devices (camera / location / photo library / permissions) honestly report unsupported on desktop; on mobile they are provided by the platform shell projects (Android verified on emulator, iOS pending, HarmonyOS still stubbed). See Limitations and Common Pitfalls for the itemized list.