Skip to content

Run in a worker

You will open a terminal whose emulator, frame building and GPU rendering run in a dedicated worker. Start with a bundler that supports worker URLs, OffscreenCanvas and a supported GPU backend.

worker.ts
import { Terminal } from 'ghostty-webgpu/worker'
export async function mountWorker(host: HTMLElement, fontUrl: string) {
const terminal = await Terminal.create({
backend: 'auto',
fonts: [{ family: 'Terminal Mono', source: { url: fontUrl } }],
appearance: { font: { family: 'Terminal Mono', size: 14 } },
})
await terminal.open(host)
await terminal.writeln('The terminal core and GPU renderer run in a worker.')
terminal.onData((bytes) => {
void terminal.write(bytes)
})
terminal.focus()
return () => terminal.dispose()
}

Call mountWorker(host, fontUrl) with an absolute font URL reachable by the worker. Fonts loaded through the page’s document.fonts belong to the page. Supply the worker’s font faces through fonts, using a URL or Uint8Array bytes.

Keep ghostty-vt.wasm, bridge.wasm and the built worker alongside the package output. Defaults resolve them relative to the package module. For a custom deployment, set assets: { wasm, bridge } and workerUrl to the hosted URLs.

Your CSP must allow the worker URL in worker-src, WebAssembly compilation, and asset/font requests. Keep cross-origin assets under your CORS policy. This worker uses messages; shared memory and cross-origin isolation are unnecessary for this path.

The main entry updates native state synchronously. Worker writes, reads, appearance changes and disposal return promises. Await a write before a read that depends on it. Host operations such as focus keep their synchronous shape.

The worker’s backend accepts auto, webgpu and webgl. Its current API has capability limits for Canvas modes, link providers, keyboard link discovery and finite synchronous input connections. attachTerminalHotkeys belongs to the main entry. Keep those boundaries in mind when migrating an interactive host.

Inspect the deployed asset URLs. A nested site base path changes document-relative URLs. Prefer URLs resolved by the bundler or absolute URLs you supply explicitly.

Read the error’s why and fix. Use the main entry when your integration needs a synchronous original-input handler or a currently unsupported worker capability.

Next, connect a producer or inspect the worker reference under API.