词法分析 → 字节码 VM → 单二进制交付

用 Go 从零实现的
JavaScript 运行时

自研 lexer / parser / compiler / 栈式虚拟机,完整走通一条编译管线。 单二进制、零外部依赖,还能把 JS 脚本打包成独立可执行文件。

goxjs — Gox REPL
$ npm i -g @goxjs/goxjs $ goxjs Gox REPL (ES6 subset, no var) 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] >
108个操作码
3 字节定长指令编码
5 平台npm 预编译二进制
0外部依赖(除 x/image)

为什么是 Gox

不是又一层封装,而是从 Token 到虚拟机的每一层都自己写。

⚙️

完整编译管线

自研 lexer / parser / compiler / 字节码 VM,108 个操作码,定长 3 字节指令 [op 1B][operand 2B],解码即取即用。

ES6+ 语言子集 + JSX

闭包、class、async/await、解构、模板字符串、可选链、空值合并、ES 模块;JSX 在编译期降级为 h() 调用。

📦

丰富的内置对象

Array / String / Map / Set / Symbol / BigInt / RegExp / Proxy / Promise / TypedArray / Temporal 等现代 JS 标准库。

🔌

宿主能力模块

Node 风格的 fs(同步 + 异步)、http 客户端与服务端、全局 fetchpathprocess

🖥️

自研 GUI 渲染层

纯 Go 软件光栅化 + flex 风格布局 + 脏矩形局部重绘,win32 与 X11 后端,产物为无动态库依赖的静态单文件;

🧩

23 个内置组件

按钮 / 勾选 / 单选 / 开关 / 输入框 / 多行编辑 / 下拉框 / 滑块 / 滚动容器 / 图片 / 画布 / 对话框 / 提示 / 菜单栏 / 右键菜单 —— 全部受控语义,配套组件参考手册

🚀

打包成独立可执行文件

jsbuild 把脚本嵌入生成的 Go 工程编译成单文件程序,支持 GUI 应用与纯 Go 交叉编译,目标机无需装任何运行时。

快速开始

两种安装方式,都不需要先懂编译原理。

方式一:npm 安装(推荐)无需 Go 环境
npm i -g @goxjs/goxjs   # 内置 5 平台预编译二进制
goxjs              # 进入 REPL
goxjs app.js       # 运行脚本
npx goxjs app.js   # 不安装直接跑
方式二:从源码构建Go 1.26+
git clone https://github.com/14752222/Gox.git
cd Gox
go build           # Windows 下生成 Gox.exe
./Gox app.js

写起来就是 JavaScript

左边是语言能力,右边是一个 16 行的响应式 GUI 桌面应用 —— 点击按钮计数,只重绘受影响区域。

语言与宿主能力
// ES6+ 子集(let/const,不支持 var)
let [a, b] = [1, 2];
console.log(`${a + b}`);            // 3

// class / async / await
class Point {
  constructor(x, y) { this.x = x; this.y = y }
  norm() { return Math.hypot(this.x, this.y) }
}

async function main() {
  let v = await delay(10, "timer done");
  console.log(v);
}

// fs / http / fetch / process 全局可用
let cfg = fs.readFileSync("app.json", "utf-8");
let res = await fetch("https://example.com/api");
GUI 桌面应用(counter.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>
);

// goxjs counter.js      → 弹出 400x300 窗口
// jsbuild counter.js --gui -o counter.exe
//   → 打包成独立 GUI 程序

架构

一条清晰的编译管线,每一层都可以单独阅读和测试。

.js 源码UTF-8 文本
lexer词法分析 → Token 流
parser语法分析 → AST
compiler符号表 + 字节码生成
vm栈式帧执行 + 事件循环

无 GC 的显式内存管理

对象生命周期由运行时显式控制,循环引用有专门处理,不依赖 Go 的垃圾回收器托管 JS 堆。

单线程 VM + 跨 goroutine 调度

http.createServer 等网络回调跨 goroutine 捕获后调度回 VM 单线程执行,无需锁。

二十三种内置组件,拿来就用

从布局容器到菜单栏,每个组件都有完整的功能说明、参数表与可运行示例。

查看组件参考 →

十分钟跑起来第一个脚本

从安装、REPL、模块、异步到打包独立可执行文件,一步步走。

阅读使用教程 →