Skip to content

Commit dbff74d

Browse files
committed
feat: Build WASM from ghostty-org/ghostty submodule with patches
Major architectural change to build WASM from source instead of committing the binary to the repository. Changes: - Add ghostty-org/ghostty as root-level submodule (pinned to 0f64b9a8e) - Add patches/ghostty-wasm-api.patch (33KB, 1006 lines) - Exposes 16 C API functions for terminal integration - Based on coder/ghostty fork commit bfd067d - Rewrite scripts/build-wasm.sh: - Initialize submodule if needed - Apply patch, build WASM with Zig, revert patch - Keeps submodule clean for easy updates - Update CI workflow: - Add Zig 0.15.2 installation to test and build jobs - Build WASM before running tests/build - Add WASM size check (512KB limit) - Update package.json: - Add build:wasm script - Integrate WASM build into main build process - Update .gitignore: - Ignore ghostty-vt.wasm (built locally and in CI) - Ignore ghostty/zig-out/ and ghostty/zig-cache/ - Remove committed ghostty-vt.wasm binary (404KB) - Update README.md and INSTALL.md with new build instructions Benefits: - Transparent build process (exact Ghostty version + patches visible) - Easier to update upstream Ghostty - Smaller git history (no binary commits) - WASM still included in npm package (built during prepublishOnly) Build time: ~20 seconds for WASM, adds ~30 seconds to CI test/build jobs
1 parent 4cdb614 commit dbff74d

10 files changed

Lines changed: 1123 additions & 34 deletions

File tree

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,23 @@ jobs:
6060
runs-on: ubuntu-latest
6161
steps:
6262
- uses: actions/checkout@v4
63+
with:
64+
submodules: recursive
6365

6466
- uses: oven-sh/setup-bun@v1
6567
with:
6668
bun-version: latest
6769

70+
- name: Install Zig 0.15.2
71+
run: |
72+
curl -L -o zig.tar.xz https://ziglang.org/download/0.15.2/zig-linux-x86_64-0.15.2.tar.xz
73+
tar xf zig.tar.xz
74+
sudo mv zig-linux-x86_64-0.15.2 /usr/local/zig-0.15.2
75+
sudo ln -s /usr/local/zig-0.15.2/zig /usr/local/bin/zig
76+
77+
- name: Build WASM
78+
run: ./scripts/build-wasm.sh
79+
6880
- name: Install dependencies
6981
run: bun install
7082

@@ -76,11 +88,32 @@ jobs:
7688
runs-on: ubuntu-latest
7789
steps:
7890
- uses: actions/checkout@v4
91+
with:
92+
submodules: recursive
7993

8094
- uses: oven-sh/setup-bun@v1
8195
with:
8296
bun-version: latest
8397

98+
- name: Install Zig 0.15.2
99+
run: |
100+
curl -L -o zig.tar.xz https://ziglang.org/download/0.15.2/zig-linux-x86_64-0.15.2.tar.xz
101+
tar xf zig.tar.xz
102+
sudo mv zig-linux-x86_64-0.15.2 /usr/local/zig-0.15.2
103+
sudo ln -s /usr/local/zig-0.15.2/zig /usr/local/bin/zig
104+
105+
- name: Build WASM
106+
run: ./scripts/build-wasm.sh
107+
108+
- name: Check WASM size
109+
run: |
110+
SIZE=$(stat -c%s ghostty-vt.wasm)
111+
echo "WASM size: $SIZE bytes"
112+
if [ "$SIZE" -gt 524288 ]; then
113+
echo "❌ Error: WASM exceeds 512 KB limit"
114+
exit 1
115+
fi
116+
84117
- name: Install dependencies
85118
run: bun install
86119

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@ dist/
33
.DS_Store
44
*.log
55
.vite/
6+
7+
# WASM build output (built locally and in CI)
8+
ghostty-vt.wasm
9+
10+
# Ghostty submodule build artifacts
11+
ghostty/zig-out/
12+
ghostty/zig-cache/

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "ghostty"]
2+
path = ghostty
3+
url = https://github.com/ghostty-org/ghostty.git

INSTALL.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,18 @@ ws.onmessage = (event) => {
9191

9292
## WASM File Handling
9393

94-
The library requires the `ghostty-vt.wasm` file at runtime. Most bundlers handle this automatically.
94+
The library requires the `ghostty-vt.wasm` file at runtime. When installing from npm, the WASM is pre-built and included. When installing from git, it's built during `postinstall`.
95+
96+
### Local Development
97+
98+
After cloning:
99+
100+
```bash
101+
git submodule update --init --recursive
102+
./scripts/build-wasm.sh
103+
```
104+
105+
The WASM file is generated locally and gitignored.
95106

96107
### Vite (Recommended)
97108

README.md

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -218,30 +218,48 @@ WebSocket Server (server/file-browser-server.ts)
218218
└── ghostty-vt.wasm - Ghostty VT100 parser (122 KB)
219219
```
220220

221-
## Building
221+
## Building WASM
222222

223-
Requires:
223+
The WASM binary is built from source, not committed to the repo.
224224

225-
- **Zig 0.15.2+** (to build WASM)
226-
- **Ghostty source** (from GitHub)
225+
**Requirements:**
226+
227+
- Zig 0.15.2+
228+
- Git submodules initialized
229+
230+
**Build:**
227231

228232
```bash
229-
# Install Zig 0.15.2
230-
curl -L -o zig-0.15.2.tar.xz \
231-
https://ziglang.org/download/0.15.2/zig-x86_64-linux-0.15.2.tar.xz
232-
tar xf zig-0.15.2.tar.xz
233-
sudo cp -r zig-x86_64-linux-0.15.2 /usr/local/zig-0.15.2
234-
sudo ln -sf /usr/local/zig-0.15.2/zig /usr/local/bin/zig
235-
236-
# Clone Ghostty
237-
git clone https://github.com/ghostty-org/ghostty.git
238-
cd ghostty
233+
# Initialize submodule (first time only)
234+
git submodule update --init --recursive
239235

240-
# Build WASM (~20 seconds)
241-
zig build lib-vt -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall
242-
# Output: zig-out/bin/ghostty-vt.wasm (122 KB)
236+
# Build WASM
237+
./scripts/build-wasm.sh
238+
# or
239+
bun run build:wasm
243240
```
244241

242+
**What it does:**
243+
244+
1. Initializes `ghostty/` submodule (ghostty-org/ghostty)
245+
2. Applies patches from `patches/ghostty-wasm-api.patch`
246+
3. Builds WASM with Zig (takes ~20 seconds)
247+
4. Outputs `ghostty-vt.wasm` (404 KB)
248+
5. Reverts patch to keep submodule clean
249+
250+
**Updating Ghostty:**
251+
252+
```bash
253+
cd ghostty
254+
git fetch origin
255+
git checkout <commit-or-tag>
256+
cd ..
257+
./scripts/build-wasm.sh
258+
# Test, then commit the updated submodule pointer
259+
```
260+
261+
**CI:** The WASM is built as part of the `test` and `build` jobs.
262+
245263
## Testing
246264

247265
Run the test suite:

ghostty

Submodule ghostty added at 0f64b9a

ghostty-vt.wasm

-403 KB
Binary file not shown.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
},
4747
"scripts": {
4848
"dev": "vite --port 8000",
49-
"build": "bun run clean && bun run build:lib && bun run build:wasm-copy",
49+
"build": "bun run clean && bun run build:wasm && bun run build:lib && bun run build:wasm-copy",
50+
"build:wasm": "./scripts/build-wasm.sh",
5051
"build:lib": "vite build",
5152
"build:wasm-copy": "cp ghostty-vt.wasm dist/",
5253
"clean": "rm -rf dist",

0 commit comments

Comments
 (0)