From 5ce64844d37df038115b843318a058d01291a2ba Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Nov 2025 04:31:25 +0000 Subject: [PATCH 1/9] chore: update README --- INSTALL.md | 181 -------------------------- README.md | 351 ++++++--------------------------------------------- package.json | 3 +- 3 files changed, 38 insertions(+), 497 deletions(-) delete mode 100644 INSTALL.md diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index a5bd18a..0000000 --- a/INSTALL.md +++ /dev/null @@ -1,181 +0,0 @@ -# Installation & Usage - -## Installation - -```bash -npm install @coder/ghostty-web -# or -bun add @coder/ghostty-web -# or -yarn add @coder/ghostty-web -``` - -### Installing from Git - -You can install directly from GitHub: - -```bash -npm install github:coder/ghostty-web -# or -bun add github:coder/ghostty-web -``` - -**Note:** Git installs require manually building the package first. See [Local Development](#local-development) for build instructions. - -## Basic Usage - -```typescript -import { Terminal } from '@coder/ghostty-web'; - -const term = new Terminal({ - cols: 80, - rows: 24, - cursorBlink: true, - theme: { - background: '#1e1e1e', - foreground: '#d4d4d4', - }, -}); - -// Mount to DOM -await term.open(document.getElementById('terminal')); - -// Write output -term.write('Hello, World!\r\n'); -term.write('\x1b[1;32mGreen text\x1b[0m\r\n'); - -// Handle user input -term.onData((data) => { - console.log('User typed:', data); - // Send to backend, echo, etc. -}); -``` - -## With FitAddon (Responsive Sizing) - -```typescript -import { Terminal, FitAddon } from '@coder/ghostty-web'; - -const term = new Terminal(); -const fitAddon = new FitAddon(); -term.loadAddon(fitAddon); - -await term.open(document.getElementById('terminal')); -fitAddon.fit(); // Resize to container - -// Resize on window resize -window.addEventListener('resize', () => fitAddon.fit()); -``` - -## WebSocket Integration - -```typescript -import { Terminal } from '@coder/ghostty-web'; - -const term = new Terminal(); -await term.open(document.getElementById('terminal')); - -const ws = new WebSocket('ws://localhost:3001/ws'); - -// Send user input to backend -term.onData((data) => { - ws.send(JSON.stringify({ type: 'input', data })); -}); - -// Display backend output -ws.onmessage = (event) => { - const msg = JSON.parse(event.data); - term.write(msg.data); -}; -``` - -## WASM File Handling - -The library requires the `ghostty-vt.wasm` file at runtime. When installing from npm, the WASM is pre-built and included in the package. - -### Local Development - -After cloning: - -```bash -./scripts/build-wasm.sh -``` - -The script will automatically initialize the submodule if needed. The WASM file is generated locally and gitignored. - -### Vite (Recommended) - -Vite handles WASM automatically. No extra config needed: - -```javascript -// vite.config.js -export default { - // WASM works out of the box -}; -``` - -### Webpack - -Configure WASM as an asset: - -```javascript -// webpack.config.js -module.exports = { - module: { - rules: [ - { - test: /\.wasm$/, - type: 'asset/resource', - }, - ], - }, -}; -``` - -### Manual Import (Advanced) - -```typescript -import wasmUrl from '@coder/ghostty-web/ghostty-vt.wasm?url'; -import { Ghostty } from '@coder/ghostty-web'; - -const ghostty = await Ghostty.load(wasmUrl); -``` - -## TypeScript Support - -Full TypeScript definitions are included: - -```typescript -import { Terminal, ITerminalOptions, ITheme } from '@coder/ghostty-web'; - -const options: ITerminalOptions = { - cols: 80, - rows: 24, - cursorBlink: true, -}; - -const theme: ITheme = { - background: '#1e1e1e', - foreground: '#d4d4d4', - cursor: '#ffffff', -}; -``` - -## API Documentation - -See [API.md](https://github.com/coder/ghostty-web/blob/main/packaging/docs/API.md) for complete API reference. - -## Migration from xterm.js - -This library follows xterm.js conventions: - -```typescript -// Before (xterm.js) -import { Terminal } from 'xterm'; -import { FitAddon } from 'xterm-addon-fit'; - -// After (@coder/ghostty-web) -import { Terminal, FitAddon } from '@coder/ghostty-web'; -``` - -Most xterm.js code works with minimal changes. See [API.md](https://github.com/coder/ghostty-web/blob/main/packaging/docs/API.md) for differences. diff --git a/README.md b/README.md index 48b3e92..1463199 100644 --- a/README.md +++ b/README.md @@ -1,331 +1,54 @@ -# Ghostty Web +# ghostty-web -A web-based terminal emulator that integrates [Ghostty's](https://github.com/ghostty-org/ghostty) VT100 parser via WebAssembly. +`ghostty-web` is a fully featured web terminal that aims to bring all the benefits of the excellent [ghostty](https://github.com/ghostty-org/ghostty) +project to the web by leveraging its exported WASM module. Like ghostty, `ghostty-web` intends to be fast, feature-rich, +and native. For many use cases it is a drop-in replacement for xterm.js. -## Installation +## Getting Started -```bash -npm install @coder/ghostty-web -``` - -Or install from GitHub: +Install the module via npm ```bash -npm install github:coder/ghostty-web +npm install ghostty-web ``` +After install, using `ghostty-web` is as simple as -## Quick Start - -```typescript -import { Terminal } from '@coder/ghostty-web'; - -const term = new Terminal({ cols: 80, rows: 24 }); -await term.open(document.getElementById('terminal')); -term.write('Hello, World!\r\n'); +```html + + + +
+ + + ``` -See [INSTALL.md](./INSTALL.md) for complete usage guide. - ## Features -- ✅ Full xterm.js-compatible API -- ✅ Production-tested VT100 parser (via Ghostty) -- ✅ ANSI colors (16, 256, RGB true color) -- ✅ Canvas rendering at 60 FPS -- ✅ Scrollback buffer -- ✅ Text selection & clipboard -- ✅ FitAddon for responsive sizing -- ✅ TypeScript declarations included - -## Development & Demos - -### Shell Terminal Demo - -**Requires server** - -```bash -# Terminal 1: Start PTY shell server -cd demo/server -bun install -bun run start - -# Terminal 2: Start web server (from project root) -bun run dev - -# Open: http://localhost:8000/demo/ -``` - -This provides a **real persistent shell session**! You can: - -- Use `cd` and it persists between commands -- Run interactive programs like `vim`, `nano`, `top`, `htop` -- Use tab completion and command history (↑/↓) -- Use pipes, redirects, and background jobs -- Access all your shell aliases and environment - -**Alternative: Command-by-Command Mode** - -For the original file browser (executes each command separately): - -```bash -cd demo/server -bun run file-browser -``` - -**Remote Access:** If you're accessing via a forwarded hostname (e.g., `mux.coder`), make sure to forward both ports: - -- Port 8000 (web server - Vite) -- Port 3001 (WebSocket server) - -The terminal will automatically connect to the WebSocket using the same hostname you're accessing the page from. - -**Colors Demo** (no server needed) - -```bash -bun run dev -# Open: http://localhost:8000/demo/colors-demo.html -``` - -See all ANSI colors (16, 256, RGB) and text styles in action. - -## Usage - -### Basic Terminal - -```typescript -import { Terminal } from './lib/index.ts'; -import { FitAddon } from './lib/addons/fit.ts'; - -// Create terminal -const term = new Terminal({ - cols: 80, - rows: 24, - cursorBlink: true, - theme: { - background: '#1e1e1e', - foreground: '#d4d4d4', - }, -}); - -// Add FitAddon for responsive sizing -const fitAddon = new FitAddon(); -term.loadAddon(fitAddon); - -// Open in container -await term.open(document.getElementById('terminal')); -fitAddon.fit(); - -// Write output (supports ANSI colors) -term.write('Hello, World!\r\n'); -term.write('\x1b[1;32mGreen bold text\x1b[0m\r\n'); - -// Handle user input -term.onData((data) => { - console.log('User typed:', data); - // Send to backend, echo, etc. -}); -``` - -### WebSocket Integration - -```typescript -const ws = new WebSocket('ws://localhost:3001/ws'); - -// Send user input to backend -term.onData((data) => { - ws.send(JSON.stringify({ type: 'input', data })); -}); - -// Display backend output -ws.onmessage = (event) => { - const msg = JSON.parse(event.data); - term.write(msg.data); -}; -``` - -### URL Detection - -Ghostty-web automatically detects and makes clickable: - -- **OSC 8 hyperlinks** - Explicit terminal escape sequences (e.g., from `ls --hyperlink`) -- **Plain text URLs** - Common protocols detected via regex (https, http, mailto, ssh, git, ftp, tel, magnet) - -URLs are detected on hover and can be opened with Ctrl/Cmd+Click. - -```typescript -// URL detection works automatically after opening terminal -await term.open(container); - -// URLs in output become clickable automatically -term.write('Visit https://github.com for code\r\n'); -term.write('Contact mailto:support@example.com\r\n'); -``` - -**Custom Link Providers** - -Register custom providers to detect additional link types: - -```typescript -import { UrlRegexProvider } from '@coder/ghostty-web'; - -// Create custom provider -const myProvider = { - provideLinks(y, callback) { - // Your detection logic here - const links = detectCustomLinks(y); - callback(links); - }, -}; - -// Register after opening terminal -term.registerLinkProvider(myProvider); -``` - -See [AGENTS.md](AGENTS.md) for development guide and code patterns. - -## Why This Approach? - -**DON'T** re-implement VT100 parsing from scratch (years of work, thousands of edge cases). - -**DO** use Ghostty's proven parser: - -- ✅ Battle-tested by thousands of users -- ✅ Handles all VT100/ANSI quirks correctly -- ✅ Modern features (RGB colors, Kitty keyboard protocol) -- ✅ Get bug fixes and updates for free - -**You build**: Screen buffer, rendering, UI (the "easy" parts in TypeScript) -**Ghostty handles**: VT100 parsing (the hard part via WASM) - -## Architecture - -``` -┌─────────────────────────────────────────┐ -│ Terminal (lib/terminal.ts) │ -│ - Public xterm.js-compatible API │ -│ - Event handling (onData, onResize) │ -└───────────┬─────────────────────────────┘ - │ - ├─► ScreenBuffer (lib/buffer.ts) - │ - 2D grid, cursor, scrollback - │ - ├─► VTParser (lib/vt-parser.ts) - │ - ANSI escape sequence parsing - │ └─► Ghostty WASM (SGR parser) - │ - ├─► CanvasRenderer (lib/renderer.ts) - │ - Canvas-based rendering - │ - 60 FPS, supports all colors - │ - └─► InputHandler (lib/input-handler.ts) - - Keyboard events → escape codes - └─► Ghostty WASM (Key encoder) - -WebSocket Server (server/file-browser-server.ts) -└─► Executes shell commands (ls, cd, cat, etc.) -``` - -## Project Structure - -``` -├── lib/ -│ ├── terminal.ts - Main Terminal class (xterm.js-compatible) -│ ├── buffer.ts - Screen buffer with scrollback -│ ├── vt-parser.ts - VT100/ANSI escape sequence parser -│ ├── renderer.ts - Canvas-based renderer -│ ├── input-handler.ts - Keyboard input handling -│ ├── ghostty.ts - Ghostty WASM wrapper -│ ├── types.ts - TypeScript type definitions -│ ├── interfaces.ts - xterm.js-compatible interfaces -│ └── addons/ -│ └── fit.ts - FitAddon for responsive sizing -│ -├── demo/ -│ ├── index.html - File browser terminal -│ ├── colors-demo.html - ANSI colors showcase -│ └── server/ -│ ├── file-browser-server.ts - WebSocket server -│ ├── package.json -│ └── start.sh - Startup script (auto-kills port conflicts) -│ -├── docs/ -│ └── API.md - Complete API documentation -│ -└── ghostty-vt.wasm - Ghostty VT100 parser (122 KB) -``` - -## Building WASM - -The WASM binary is built from source, not committed to the repo. - -**Requirements:** - -- Zig 0.15.2+ -- Git submodules initialized - -**Build:** - -```bash -# Initialize submodule (first time only) -git submodule update --init --recursive - -# Build WASM -./scripts/build-wasm.sh -# or -bun run build:wasm -``` - -**What it does:** - -1. Initializes `ghostty/` submodule (ghostty-org/ghostty) -2. Applies patches from `patches/ghostty-wasm-api.patch` -3. Builds WASM with Zig (takes ~20 seconds) -4. Outputs `ghostty-vt.wasm` (404 KB) -5. Reverts patch to keep submodule clean - -**Updating Ghostty:** - -```bash -cd ghostty -git fetch origin -git checkout -cd .. -./scripts/build-wasm.sh -# Test, then commit the updated submodule pointer -``` - -**CI:** The WASM is built as part of the `test` and `build` jobs. - -## Testing - -Run the test suite: - -```bash -bun test # Run all tests -bun test --watch # Watch mode -bun run typecheck # Type checking -bun run build # Build distribution -``` - -**Test Coverage:** - -- ✅ ScreenBuffer (63 tests, 163 assertions) -- ✅ VTParser (45 tests) -- ✅ CanvasRenderer (11 tests) -- ✅ InputHandler (35 tests) -- ✅ Terminal integration (25 tests) -- ✅ FitAddon (12 tests) +Because `ghostty-web` hooks into Ghotty's WASM module it benefits from the meticulous care put into the project. +Among others, ghostty-web has: -## Documentation +- An xterm.js-compatible API +- Zero runtime dependencies: just ghostty-web and its bundled Ghostty WASM engine. +- Canvas-based rendering (60 FPS) +- Responsive resizing +- Full VT100/ANSI emulation +- Screen + scrollback buffer +- Cursor state + modes +- Robust parser/state machine -- **[AGENTS.md](AGENTS.md)** - Development guide for AI agents and developers +## Development -## Links +In order to begin development you'll need: -- [Ghostty Terminal](https://github.com/ghostty-org/ghostty) -- [libghostty-vt API](https://github.com/ghostty-org/ghostty/tree/main/include/ghostty/vt) -- [VT100 Reference](https://vt100.net/docs/vt100-ug/) +- [bun](https://bun.com/docs/installation) +- [zig](https://ziglang.org/download/) -## License +### Building WASM -See cmux LICENSE (AGPL-3.0) +The library relies on a patch applied on top of Ghostty in order to expose additional functionality not yet implemented in the upstream repo. Building it is as simple as running `bun run build`. \ No newline at end of file diff --git a/package.json b/package.json index 0a686d8..827bb6f 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,7 @@ "files": [ "dist", "ghostty-vt.wasm", - "README.md", - "INSTALL.md" + "README.md" ], "keywords": [ "terminal", From d6af950a3c18628a17b86dfc0c2ce3351ba5aaf4 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Tue, 18 Nov 2025 23:54:44 -0500 Subject: [PATCH 2/9] add gif Added logo image to README and improved description. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1463199..ed09f8b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # ghostty-web +![ghostty](https://github.com/user-attachments/assets/6154beda-9b51-4a04-843d-a7f144803ecf) + `ghostty-web` is a fully featured web terminal that aims to bring all the benefits of the excellent [ghostty](https://github.com/ghostty-org/ghostty) project to the web by leveraging its exported WASM module. Like ghostty, `ghostty-web` intends to be fast, feature-rich, and native. For many use cases it is a drop-in replacement for xterm.js. @@ -51,4 +53,4 @@ In order to begin development you'll need: ### Building WASM -The library relies on a patch applied on top of Ghostty in order to expose additional functionality not yet implemented in the upstream repo. Building it is as simple as running `bun run build`. \ No newline at end of file +The library relies on a patch applied on top of Ghostty in order to expose additional functionality not yet implemented in the upstream repo. Building it is as simple as running `bun run build`. From a4cd5e8bb779311bb2596fa0cb6b376f39c83756 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Nov 2025 05:20:28 +0000 Subject: [PATCH 3/9] refinements --- README.md | 102 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ed09f8b..14cb45e 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,30 @@ ![ghostty](https://github.com/user-attachments/assets/6154beda-9b51-4a04-843d-a7f144803ecf) -`ghostty-web` is a fully featured web terminal that aims to bring all the benefits of the excellent [ghostty](https://github.com/ghostty-org/ghostty) -project to the web by leveraging its exported WASM module. Like ghostty, `ghostty-web` intends to be fast, feature-rich, -and native. For many use cases it is a drop-in replacement for xterm.js. +`ghostty-web` is a fully-featured web terminal built on [Ghostty's](https://github.com/ghostty-org/ghostty) +terminal emulation core compiled to WebAssembly. By leveraging Ghostty's production-tested VT100 parser +and state machine, `ghostty-web` delivers fast, robust terminal emulation in the browser. For many use +cases it is a drop-in replacement for xterm.js. + +## Live Demo + +You can try ghostty-web yourself: +> [!NOTE] +> Requires Zig and Bun see [Development](#development) + +```bash +git clone https://github.com/coder/ghostty-web +cd ghostty-web +bun install +bun run build +cd ./demo +bun run dev # Starts on localhost:8000 + +# In a separate terminal +cd ./demo/server +bun run start +``` +>>>>>>> Stashed changes ## Getting Started @@ -32,17 +53,63 @@ After install, using `ghostty-web` is as simple as ## Features -Because `ghostty-web` hooks into Ghotty's WASM module it benefits from the meticulous care put into the project. -Among others, ghostty-web has: +`ghostty-web` compiles Ghostty's core terminal emulation engine (parser, state +machine, and screen buffer) to WebAssembly, providing: + +**Core Terminal:** +- Full VT100/ANSI escape sequence support +- True color (24-bit RGB) + 256 color + 16 ANSI colors +- Text styles: bold, italic, underline, strikethrough, dim, reverse +- Alternate screen buffer (for vim, htop, less, etc.) +- Scrollback buffer with mouse wheel support + +**Input & Interaction:** +- Text selection and clipboard integration +- Mouse tracking modes +- Kitty keyboard protocol support +- Custom key/wheel event handlers + +**API & Integration:** +- xterm.js-compatible API (drop-in replacement for many use cases) +- FitAddon for responsive terminal sizing +- Event system (onData, onResize, onBell, onScroll, etc.) -- An xterm.js-compatible API -- Zero runtime dependencies: just ghostty-web and its bundled Ghostty WASM engine. -- Canvas-based rendering (60 FPS) -- Responsive resizing -- Full VT100/ANSI emulation -- Screen + scrollback buffer -- Cursor state + modes -- Robust parser/state machine +**Performance:** +- Canvas-based rendering at 60 FPS +- Zero runtime dependencies (just ghostty-web + bundled WASM) +- Parser/state machine from Ghostty + +## Why ghostty-web? + +**Don't reimplement VT100 parsing** – it's thousands of edge cases refined over years. Instead, leverage Ghostty's battle-tested terminal emulator that's proven by thousands of daily users. +**Drop-in xterm.js replacement** – for many use cases, ghostty-web can replace xterm.js with minimal code changes +**Modern & maintained** – Built on Ghostty, an actively developed modern terminal emulator, ensuring continued improvements and bug fixes. + +## Usage Example + +### Basic Terminal + +```typescript +import { Terminal } from 'ghostty-web'; +import { FitAddon } from 'ghostty-web/addons/fit'; +const term = new Terminal({ + cursorBlink: true, + fontSize: 14, + theme: { + background: '#1e1e1e', + foreground: '#d4d4d4', + }, +}); +const fitAddon = new FitAddon(); +term.loadAddon(fitAddon); +await term.open(document.getElementById('terminal')); +fitAddon.fit(); +// Handle user input +term.onData(data => { + // Send to backend/PTY + console.log('User typed:', data); +}); +``` ## Development @@ -53,4 +120,13 @@ In order to begin development you'll need: ### Building WASM +<<<<<<< Updated upstream The library relies on a patch applied on top of Ghostty in order to expose additional functionality not yet implemented in the upstream repo. Building it is as simple as running `bun run build`. +======= +`ghostty-web` builds a custom WASM binary from Ghostty's source with patches to expose additional +browser-specific functionality + +```bash +bun run build +``` +>>>>>>> Stashed changes From 6838be4667566cef4bc627d5d387b1616ff9300f Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Nov 2025 05:21:35 +0000 Subject: [PATCH 4/9] rm conflicts --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 14cb45e..542cc29 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,6 @@ bun run dev # Starts on localhost:8000 cd ./demo/server bun run start ``` ->>>>>>> Stashed changes ## Getting Started @@ -120,13 +119,9 @@ In order to begin development you'll need: ### Building WASM -<<<<<<< Updated upstream -The library relies on a patch applied on top of Ghostty in order to expose additional functionality not yet implemented in the upstream repo. Building it is as simple as running `bun run build`. -======= `ghostty-web` builds a custom WASM binary from Ghostty's source with patches to expose additional browser-specific functionality ```bash bun run build ``` ->>>>>>> Stashed changes From 99e7cc2634e7e045fc8f65e1c85e627c1dfe0da9 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Nov 2025 05:23:54 +0000 Subject: [PATCH 5/9] formatting --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 542cc29..d11d3c3 100644 --- a/README.md +++ b/README.md @@ -80,9 +80,9 @@ machine, and screen buffer) to WebAssembly, providing: ## Why ghostty-web? -**Don't reimplement VT100 parsing** – it's thousands of edge cases refined over years. Instead, leverage Ghostty's battle-tested terminal emulator that's proven by thousands of daily users. -**Drop-in xterm.js replacement** – for many use cases, ghostty-web can replace xterm.js with minimal code changes -**Modern & maintained** – Built on Ghostty, an actively developed modern terminal emulator, ensuring continued improvements and bug fixes. +- **Don't reimplement VT100 parsing** – it's thousands of edge cases refined over years. Instead, leverage Ghostty's battle-tested terminal emulator that's proven by thousands of daily users. +- **Drop-in xterm.js replacement** – for many use cases, ghostty-web can replace xterm.js with minimal code changes +- **Modern & maintained** – Built on Ghostty, an actively developed modern terminal emulator, ensuring continued improvements and bug fixes. ## Usage Example From 7c978d3afdcd1d6d6f9cb12f18dcc8034e05ded4 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Nov 2025 05:27:06 +0000 Subject: [PATCH 6/9] wording --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d11d3c3..bc76102 100644 --- a/README.md +++ b/README.md @@ -89,8 +89,8 @@ machine, and screen buffer) to WebAssembly, providing: ### Basic Terminal ```typescript -import { Terminal } from 'ghostty-web'; -import { FitAddon } from 'ghostty-web/addons/fit'; +import { Terminal, FitAddon } from "ghostty-web"; + const term = new Terminal({ cursorBlink: true, fontSize: 14, @@ -99,10 +99,13 @@ const term = new Terminal({ foreground: '#d4d4d4', }, }); + const fitAddon = new FitAddon(); term.loadAddon(fitAddon); + await term.open(document.getElementById('terminal')); fitAddon.fit(); + // Handle user input term.onData(data => { // Send to backend/PTY From 3f8922429145ea96643184ef5393ad88f0a7e1a8 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Nov 2025 00:30:30 -0500 Subject: [PATCH 7/9] Add MIT License to the project --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bd8d593 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Coder + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 3f6c79549967492c68bdef58877dcaf5a8e5013c Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Nov 2025 00:37:20 -0500 Subject: [PATCH 8/9] Update image link in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bc76102..8323db1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ghostty-web -![ghostty](https://github.com/user-attachments/assets/6154beda-9b51-4a04-843d-a7f144803ecf) +![ghostty](https://github.com/user-attachments/assets/8ef9161e-135d-4189-a6f6-0a644a82a5de) `ghostty-web` is a fully-featured web terminal built on [Ghostty's](https://github.com/ghostty-org/ghostty) terminal emulation core compiled to WebAssembly. By leveraging Ghostty's production-tested VT100 parser From b27e26c70c860846e74c9943aadbf60b6ada43c6 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Nov 2025 05:46:44 +0000 Subject: [PATCH 9/9] fmt --- README.md | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 8323db1..24f52f7 100644 --- a/README.md +++ b/README.md @@ -3,27 +3,30 @@ ![ghostty](https://github.com/user-attachments/assets/8ef9161e-135d-4189-a6f6-0a644a82a5de) `ghostty-web` is a fully-featured web terminal built on [Ghostty's](https://github.com/ghostty-org/ghostty) -terminal emulation core compiled to WebAssembly. By leveraging Ghostty's production-tested VT100 parser -and state machine, `ghostty-web` delivers fast, robust terminal emulation in the browser. For many use +terminal emulation core compiled to WebAssembly. By leveraging Ghostty's production-tested VT100 parser +and state machine, `ghostty-web` delivers fast, robust terminal emulation in the browser. For many use cases it is a drop-in replacement for xterm.js. ## Live Demo You can try ghostty-web yourself: + > [!NOTE] -> Requires Zig and Bun see [Development](#development) +> Requires Zig and Bun, see [Development](#development) ```bash git clone https://github.com/coder/ghostty-web cd ghostty-web bun install -bun run build -cd ./demo -bun run dev # Starts on localhost:8000 +bun run build # Builds the WASM module and library -# In a separate terminal -cd ./demo/server +# Terminal 1: Start PTY Server +cd demo/server +bun install bun run start + +# Terminal 2: Start web server +bun run start # http://localhost:8000 ``` ## Getting Started @@ -33,6 +36,7 @@ Install the module via npm ```bash npm install ghostty-web ``` + After install, using `ghostty-web` is as simple as ```html @@ -52,10 +56,11 @@ After install, using `ghostty-web` is as simple as ## Features -`ghostty-web` compiles Ghostty's core terminal emulation engine (parser, state +`ghostty-web` compiles Ghostty's core terminal emulation engine (parser, state machine, and screen buffer) to WebAssembly, providing: **Core Terminal:** + - Full VT100/ANSI escape sequence support - True color (24-bit RGB) + 256 color + 16 ANSI colors - Text styles: bold, italic, underline, strikethrough, dim, reverse @@ -63,17 +68,20 @@ machine, and screen buffer) to WebAssembly, providing: - Scrollback buffer with mouse wheel support **Input & Interaction:** + - Text selection and clipboard integration - Mouse tracking modes - Kitty keyboard protocol support - Custom key/wheel event handlers **API & Integration:** + - xterm.js-compatible API (drop-in replacement for many use cases) - FitAddon for responsive terminal sizing - Event system (onData, onResize, onBell, onScroll, etc.) **Performance:** + - Canvas-based rendering at 60 FPS - Zero runtime dependencies (just ghostty-web + bundled WASM) - Parser/state machine from Ghostty @@ -81,15 +89,15 @@ machine, and screen buffer) to WebAssembly, providing: ## Why ghostty-web? - **Don't reimplement VT100 parsing** – it's thousands of edge cases refined over years. Instead, leverage Ghostty's battle-tested terminal emulator that's proven by thousands of daily users. -- **Drop-in xterm.js replacement** – for many use cases, ghostty-web can replace xterm.js with minimal code changes +- **Drop-in xterm.js replacement** – for many use cases, ghostty-web can replace xterm.js with minimal code changes - **Modern & maintained** – Built on Ghostty, an actively developed modern terminal emulator, ensuring continued improvements and bug fixes. -## Usage Example +## Usage Examples ### Basic Terminal ```typescript -import { Terminal, FitAddon } from "ghostty-web"; +import { Terminal, FitAddon } from 'ghostty-web'; const term = new Terminal({ cursorBlink: true, @@ -107,22 +115,22 @@ await term.open(document.getElementById('terminal')); fitAddon.fit(); // Handle user input -term.onData(data => { +term.onData((data) => { // Send to backend/PTY console.log('User typed:', data); }); ``` -## Development +## Development -In order to begin development you'll need: +### Prerequisites -- [bun](https://bun.com/docs/installation) +- [bun](https://bun.com/docs/installation) - [zig](https://ziglang.org/download/) ### Building WASM -`ghostty-web` builds a custom WASM binary from Ghostty's source with patches to expose additional +`ghostty-web` builds a custom WASM binary from Ghostty's source with patches to expose additional browser-specific functionality ```bash