Open-source terminal infrastructure for product teams.
Embed a real terminal into your product with a PTY-backed Go backend, a headless web terminal wrapper, and a runnable reference app.
Why floeterm · Packages · Quick Start · Development
floeterm is built for teams that want terminal workflows inside their own product, not inside someone else's UI shell.
Product-first: ship your own terminal experience while floeterm handles PTY lifecycle, history replay, resize coordination, and browser-facing terminal plumbing.Composable: useterminal-goas the backend engine,terminal-webas the headless browser layer, or start from the end-to-end reference app inapp/. FloeTerm also owns the versionedbeamterm-rendererWebGL2 distribution used by the web package.User-ready: mobile-friendly input bridging, IME support, reconnect-friendly history replay, configurable clipboard behavior, and first-class shell bell/title plus link-provider extension points are already in the stack.Operationally sane: onemake checkpath matches CI for Go race tests,govulncheck, web lint/test/build, andnpm audit.
Typical use cases:
- AI coding workspaces and browser IDEs
- Cloud admin consoles and internal ops tools
- Remote development environments
- Embedded terminals inside dashboards, drawers, tabs, or dedicated terminal pages
| Tag | What it means in practice |
|---|---|
🧩 HEADLESS UI |
terminal-web exposes TerminalCore, createTerminalInstance, and TerminalSessionsCoordinator without forcing a component library or design system. |
🌱 DORMANT-FIRST |
Sessions can be created before the PTY starts, then activated with the real viewport size on first attach. |
📚 HISTORY REPLAY |
Scrollback is buffered, filtered, and replayed safely after reconnects or remounts. |
⌨️ IME READY |
The web layer bridges the hidden textarea used by ghostty-web, keeping soft keyboard and composition input usable on touch devices. |
📐 MULTI-VIEW |
Responsive resize controls help keep one remote session usable across panes, tabs, and focused terminal views. |
🔗 ACTIONABLE OUTPUT |
Custom link providers and bell/title forwarding let products turn terminal output into file navigation, alerts, and richer UX without patching internals. |
🧪 REFERENCE APP |
A runnable HTTP + WebSocket app shows the full integration path end to end. |
| Package | Best for | What you get |
|---|---|---|
terminal-go |
Go backends that need PTY sessions | Session lifecycle, history buffering/filtering, explicit workdir and foreground-command signals, low-frequency output activity metadata, resize coordination, and event callbacks |
terminal-web |
Web clients that want terminal plumbing without UI lock-in | TerminalCore, createTerminalInstance, TerminalSessionsCoordinator, strict Agent CLI classification, config helpers, and a headless ghostty-web wrapper |
beamterm-renderer |
FloeTerm's WebGL2 rendering release | A versioned, reproducible Beamterm fork with upstream provenance and browser warning/performance gates |
app/ |
Teams that want a working reference before integrating | HTTP APIs, WebSocket streaming, and a Solid.js demo UI that wires the stack together |
Install the building blocks you need:
go get github.com/floegence/floeterm/terminal-go
npm i @floegence/floeterm-terminal-web| You need to... | floeterm gives you... |
|---|---|
| Start a session before layout is stable | Dormant-first session creation via CreateSession, then shared PTY activation with real cols/rows via ActivateSession, ActivateSessionContext, or first attach |
| Restore terminal output after reconnect or remount | History chunks, replay windows, and filtering that removes problematic terminal auto-responses |
| Support touch devices and IME input | A browser input bridge that keeps composition and soft keyboard flows working with ghostty-web |
| Reuse one session across multiple surfaces | Per-connection sizing on the backend plus focus-aware responsive resize options in the web layer |
| Distinguish a running command from active terminal output | Independent foreground-command and unknown / streaming / settled output metadata, without subscribing every session to its PTY byte stream |
| Turn terminal output into product interactions | Custom link providers, bell events, and title updates surfaced through TerminalCore |
| Evaluate quickly before integrating | A reference app you can run locally in minutes |
make runThen open http://localhost:8280.
make runserves the bundled app and is also reachable from other devices on your LAN viahttp://<your-ip>:8280.make devstarts the Go backend on0.0.0.0:8080and the Vite dev server on0.0.0.0:5173for HMR and cross-device debugging.
package main
import (
"log"
terminal "github.com/floegence/floeterm/terminal-go"
)
func main() {
manager := terminal.NewManager(terminal.ManagerConfig{})
session, err := manager.CreateSession("", "")
if err != nil {
log.Fatal(err)
}
if err := manager.ActivateSession(session.ID, 120, 40); err != nil {
log.Fatal(err)
}
if err := session.WriteDataWithSource([]byte("ls\n"), ""); err != nil {
log.Fatal(err)
}
}import { createTerminalInstance } from '@floegence/floeterm-terminal-web';
const controller = createTerminalInstance({
sessionId: 'session-1',
isActive: true,
transport: myTransport,
eventSource: myEventSource,
});
await controller.mount(container);| Topic | Notes |
|---|---|
| Platform | terminal-go relies on a POSIX PTY and is tested on macOS/Linux. |
| Lifecycle | CreateSession creates a dormant logical session. The first attach or an explicit activation should provide the real terminal viewport size. ActivateSessionContext lets a request stop waiting without cancelling another caller's shared activation; delete and cleanup cancel the session-owned activation. |
| Multi-view sizing | Every live connection reports its own viewport cols/rows. Because one PTY has one real window size, the shared PTY uses the minimum live column count and minimum live row count. terminal/live_v1 publishes that effective geometry to every renderer, so differently sized pages keep one terminal grid and identical screen state; detaching the limiting view expands the PTY and all remaining renderers together. |
| Working directory tracking | terminal-go follows explicit local cwd OSC markers and buffers incomplete frames across PTY reads. Remote OSC 7 authority/path hints remain display-only execution context and never overwrite local session resource metadata. |
| Context, command, and output awareness | Shell integration exposes atomic location/application context, revision-fenced semantic work, a bounded foreground executable basename, and independent output activity. Long-lived SSH/Agent processes do not imply loading; settled only means visible output is quiet. |
| UI ownership | terminal-web is intentionally headless. You own the surrounding layout, session list, controls, and product experience. |
| Input model | Every TerminalCore owns an isolated ghostty-web WASM runtime and supports explicit-copy-only clipboard behavior when you disable copy-on-select. |
| Extension points | TerminalCore exposes link providers, shell bell/title callbacks, buffer line reads, touch-scroll helpers, and explicit runtime font updates so downstream apps do not need any-based terminal mutations. |
| Reference transport | The sample app uses HTTP APIs for control operations and one bidirectional binary WebSocket for live terminal input, resize, and output. |
| Command | What it does |
|---|---|
make check |
Runs the same hard gates as CI: Go race tests, govulncheck, renderer Rust/WASM/package checks, web lint/test/build, real-process E2E, and npm audit |
make run |
Builds and serves the reference app from the Go backend |
make dev |
Runs backend + Vite dev server separately for local iteration |
make app-web-build |
Builds the reference web app only |
cd e2e && npm run perf:standalone -- --url=http://127.0.0.1:8280 |
Runs the headed hardware WebGL2 performance gate, including two differently-sized views on one session |
Renderer and web releases are coupled: terminal-web pins one exact
@floegence/beamterm-renderer version. The release workflow validates that pin, builds
the Rust/WASM package with the repository's fixed toolchain, publishes the renderer
first, and only then validates and publishes terminal-web.
| Path | Purpose |
|---|---|
terminal-go/ |
Go PTY session manager |
terminal-web/ |
Framework-neutral web terminal package |
beamterm-renderer/ |
FloeTerm-maintained Beamterm WebGL2 renderer fork and npm package |
app/backend/ |
HTTP + WebSocket backend reference implementation |
app/web/ |
Solid.js reference UI |
e2e/ |
Real-process unit, Playwright functional, and hardware performance gates |
- Third-party notices: THIRD_PARTY_NOTICES.md
- License: MIT