b3tty

command module
v1.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2026 License: MIT Imports: 1 Imported by: 0

README

b3tty

A better, browser-based terminal emulator.

Description

b3tty is a terminal emulator accessible entirely from your web browser. It is built using xterm.js which provides the terminal look and feel using Javascript and CSS. A small web server acts as a proxy between a psuedo terminal and the browser, which communicates over web sockets.

The terminal appearance and server can be configured with a configuration yaml file or command-line flags. Use the following command to display available server and terminal configuration options:

b3tty start --help
Features
  • Customizable themes
  • User defined profiles
  • In-browser menu bar for switching themes and profiles at runtime
  • Mouse support
  • Auto-fit and resizing
  • Background image support
  • Inline image rendering
  • URL links
  • TLS support

Installation

NOTE: b3tty is not compatible with Windows.

Requirements
  • A machine running Linux or MacOS.
  • Your favorite web browser.
  • git and familiarity with using git.
  • Go version 1.25 or higher.
  • bun — used to bundle the frontend TypeScript (src/client/terminal.tssrc/assets/terminal.min.js)
Steps
  1. Open a new terminal window.
  2. b3tty does not ship as a binary. To install b3tty, clone the repo at https://github.com/cmmorrow/b3tty.git.
  3. In the root b3tty directory, run make setup to install the bun dependencies.
  4. After installing the bun dependencies, run make build to build b3tty for your system. This will first bundle the frontend JavaScript with bun, then compile the Go binary.
    • To format frontend source files before building, run make format. To check formatting without modifying files (e.g. in CI), run make format-check.
  5. Make the b3tty binary executable with chmod u+x b3tty.
  6. Either copy the b3tty binary to a directory in your $PATH such as /usr/local/bin, or create a symlink to the betty executable that is in your $PATH.

Usage

To start using b3tty, first make sure the executable works by running b3tty --version. To start the server with default options, run b3tty start. To see the available command-line options when starting the server, run b3tty start --help.

When the b3tty server is started, the output should look something like the output below:

> b3tty start
2024/10/14 00:49:12 [INFO ] http server started on http://localhost:8080/?token=2uzc8uFR7o5yUDy9

Log output uses level prefixes to make it easier to identify the nature of each message:

Level Color Meaning
[INFO ] Cyan Normal operational messages
[WARN ] Yellow Rejected requests, recoverable conditions
[ERROR] Red Handler errors that did not stop the server
[FATAL] Bold red Unrecoverable errors — server exits immediately
[DEBUG] Magenta Verbose diagnostics, only shown with --debug

Colors are shown when output is an interactive terminal and suppressed when piped or redirected.

First-run setup

When b3tty starts and no config file is found, it opens a theme selector in the browser instead of the terminal. The selector presents two built-in themes — Dark and Light — as visual previews, along with a No theme option to skip and configure one manually later.

Selecting a theme and clicking OK writes a conf.yaml file to ~/.config/b3tty/ with the chosen theme and immediately reloads the page to start the terminal. Choosing No theme skips config file creation and starts the terminal with the default xterm.js colors.

Once a config file exists, the setup page is never shown again. To return to the theme selector, delete or move the config file before restarting b3tty.

Configuration

b3tty can be configured via a yaml file specified on startup with the command b3tty start --config <file path>. Themes, profiles, font, font size, cursor blink, and terminal dimensions can only be specified in the config file. The config file is a yaml file and b3tty isn't picky about the file name or path, however, it's recommended to name the file b3tty.yaml and place it in ~/.config/b3tty.

When a config file is provided, b3tty validates it on startup before the server starts. Any unknown keys or fields with the wrong data type are reported with the line number where the problem occurs, and the server will not start until the config file is corrected. An example config yaml file can be seen below:

server:
  tls: true
  cert-file: "/path/to/cert/file"
  key-file: "/path/to/key/file"
  no-auth: false
  no-browser: false
terminal:
  font-family: "MesloLGS Nerd Font Mono"
  font-size: 16
  cursor-blink: false
  rows: 30
profiles:
  projects:
    working-directory: "~/projects"
    title: "Project Development"
    shell: "/bin/fish"
theme: "my-theme"
themes:
  my-theme:
    black: "#14181d"
    bright-black: "#404040"
    red: "#eb5a4b"
    bright-red: "#ee837b"
    green: "#c6d173"
    bright-green: "#dff06c"
    yellow: "#e6ce6c"
    bright-yellow: "#fdf699"
    blue: "#5998db"
    bright-blue: "#8ccdfa"
    magenta: "#e68c8c"
    bright-magenta: "#f3b7b9"
    cyan: "#b2e7d4"
    bright-cyan: "#b2e7d4"
    white: "#fefefe"
    bright-white: "#feffff"
    foreground: "#dbdbdb"
    background: "#15191e"
    cursor: "#dbdbdb"
    cursor-accent: "#15191e"
    selection-foreground: "#000000"
    selection-background: "#bad5fb"
Config file schema

The config file is a YAML document with five top-level keys. All keys are optional; omitting a section leaves those settings at their defaults.

server

Controls how the HTTP/WebSocket server is started.

Key Type Default Description
tls bool false Enable HTTPS/WSS. Requires cert-file and key-file. Changes the default port from 8080 to 8443 when true.
cert-file string "" Path to the TLS certificate file. Required when tls: true.
key-file string "" Path to the TLS private key file. Required when tls: true.
no-auth bool false Disable the access-token requirement. Reduces security posture — use only in trusted environments.
no-browser bool false Suppress automatically opening b3tty in the default browser on startup.
port int 8080 (8443 with TLS) The TCP port the server listens on.
terminal

Controls the appearance and dimensions of the terminal.

Key Type Default Description
font-family string "monospace" The font used in the terminal. Multi-word names (e.g. "Fira Code") are supported. Note: the font must be available in the browser.
font-size int 14 Terminal font size in pixels.
cursor-blink bool true Whether the terminal cursor blinks. May not work in all browsers.
rows int 24 Number of terminal rows.
columns int 0 Number of terminal columns. 0 means auto-fit to the browser window width.
theme

A string naming which entry under themes to activate, e.g. theme: "my-theme". Omit this key (or leave it empty) to use the default xterm.js colors.

themes

A map of named theme objects. Each key is an arbitrary theme name; the value is an object whose fields set terminal colors. All fields are optional strings; omitting a field keeps the xterm.js default for that color.

Color values must be a 3- or 6-digit CSS hex color (e.g. #fff or #14181d) or a letters-only CSS named color (e.g. red or cornflowerblue). Invalid values are rejected at startup.

Key Description
foreground Default text color
background Terminal background color
cursor Cursor color
cursor-accent Color of the character beneath the cursor
selection-foreground Text color inside a selection
selection-background Background color of a selection
black ANSI color 0
bright-black ANSI color 8 (bright black / dark grey)
red ANSI color 1
bright-red ANSI color 9
green ANSI color 2
bright-green ANSI color 10
yellow ANSI color 3
bright-yellow ANSI color 11
blue ANSI color 4
bright-blue ANSI color 12
magenta ANSI color 5
bright-magenta ANSI color 13
cyan ANSI color 6
bright-cyan ANSI color 14
white ANSI color 7
bright-white ANSI color 15
background-image Absolute path to a background image file on the server. When set, the container, terminal, and profile label backgrounds become 50% transparent so the image is visible behind the terminal text.
profiles

A map of named profile objects. Each key is an arbitrary profile name used in the ?profile= query parameter. All fields are optional strings unless noted.

Key Type Default Description
shell string $SHELL Path to the shell binary to launch (e.g. /bin/fish). Must not contain spaces.
working-directory string $HOME The working directory for the shell. Supports ~ and ~/… expansion.
title string "b3tty" Browser tab title shown when this profile is active.
commands list of strings [] Commands to run in the pseudo terminal immediately after it opens. Each entry is a shell command string.
root string "/" The HTTP root path the server is mounted under.

Themes

b3tty allows the look and feel of the browser-based terminal to be customized in the b3tty config file. Themes set the colors used by the terminal representation in the browser. Multiple themes can be defined in the config file. One theme is active at startup (set by the theme key), and additional themes can be switched to at runtime using the Themes menu in the menu bar without reloading the page. Selecting the already-active theme from the menu is a no-op and does not make a network request.

Each color value in a theme must be either a 3- or 6-digit CSS hex color (e.g. #fff or #14181d) or a letters-only CSS named color (e.g. red or cornflowerblue). Invalid color values are reported at startup and the server will not start until they are corrected.

In addition to the standard terminal palette colors, themes support two cursor-specific keys:

Key Description
cursor Color of the terminal cursor
cursor-accent Color of the character beneath the cursor

Profiles

Profiles are used to set the default terminal behavior when navigating to the b3tty url. Profiles allow the working directory and shell to be used to be set when the pseudo terminal is started by the server. The title of the browser tab can also be set to make different profiles easier to distinguish from one another.

Unlike server, terminal, and theme settings, different profiles can be used by different browser tabs (or browser windows) when connecting to the b3tty server. To use a profile defined in the b3tty config file, add the profile= query parameter to the end of the b3tty url where the value is the name of the profile to use. When more than one profile is configured, a Profiles menu also appears in the menu bar; selecting a profile from it opens that profile in a new browser tab.

When a non-default profile is active, the profile's name (its key in the config file) is displayed in a small label below the terminal in the browser. The label uses the configured font family, font size, and theme foreground and background colors. The label is hidden when using the default profile.

When more than one profile is configured, the server lists them on startup with their URL, shell, and working directory:

2024/10/14 00:49:12 [INFO ] Configured profiles:
2024/10/14 00:49:12 [INFO ]   projects    http://localhost:8080/?token=2uzc8uFR7o5yUDy9&profile=projects    (shell: /bin/fish | dir: ~/projects)
2024/10/14 00:49:12 [INFO ]   work        http://localhost:8080/?token=2uzc8uFR7o5yUDy9&profile=work        (shell: /bin/zsh  | dir: ~/work)

Profile names are sorted alphabetically and aligned for readability.

Menu bar

The menu bar is a browser-side control strip that appears at the top of the terminal page when at least one theme or one non-default profile is configured. It is always present in the DOM but completely hidden when there is nothing to show.

Appearance and interaction:

  • When collapsed, only a thin trigger strip is visible at the top of the viewport.
  • Hovering over the trigger slides the full menu bar into view.
  • The menu bar automatically hides after 5 seconds of inactivity, or immediately when you click outside it.
  • When the menu bar opens or closes, the terminal resizes to fill the available space.

Themes menu — The first item is always Select Theme…, which opens the Theme Selector overlay (see below). When themes are defined in the config file, a separator is shown followed by one item per theme; selecting a theme applies it immediately without reloading the page.

Profiles menu — visible when more than one profile is configured. Selecting a profile opens that profile in a new browser tab.

Colors — the menu bar uses the terminal's foreground color as its background and the terminal's background color as its text color, so it contrasts naturally with the active theme. When the theme is changed via the Themes menu, the menu bar colors update automatically to match.

Theme Selector

The Theme Selector is a full-page overlay that lets you browse and apply any built-in or user-defined theme from directly inside the terminal page, without editing the config file.

Opening the Theme Selector

Click Select Theme… at the top of the Themes menu in the menu bar. The overlay opens in front of the terminal — the PTY session continues running in the background and is never interrupted.

Browsing themes

The overlay displays a card for each available theme. Each card shows the theme name and a row of color swatches drawn from the theme's palette, so you can preview the color scheme before applying it.

Click a card to select it. The OK button becomes active once a card is selected.

Applying a theme

Click OK to apply the selected theme. The following happens immediately, without a page reload:

  1. The theme colors are applied to the terminal and the page background.
  2. If the selected theme is a built-in theme that was not previously in your config file, it is added to the themes section of your config file and the theme key is updated — so the selection persists across restarts.

Click Cancel at any time to close the overlay without making any changes.

Built-in themes

b3tty ships with the following built-in themes, all available in the Theme Selector without any config file changes:

Theme Style
b3tty-dark Dark (default dark theme)
b3tty-light Light (default light theme)
Catppuccin Mocha Dark
Catppuccin Latte Light
Dracula Dark
Tokyo Night Dark
Solarized Dark Dark
Solarized Light Light
One Light Light
Gruvbox Light Light

User-defined themes from the themes section of the config file also appear in the Theme Selector alongside the built-in ones.

Debug mode

Passing --debug to b3tty start enables verbose diagnostic output:

b3tty start --debug

On the server side, additional [DEBUG] log lines are printed covering startup configuration, incoming request metadata, PTY dimensions, resize events, and WebSocket lifecycle events.

On the browser side, debug mode activates keypress round-trip timing. After each keypress, the time from when the input is sent to the server until xterm.js has finished rendering the PTY response is printed to the browser console:

[b3tty] keypress round-trip: 4.23ms

Debug mode has no effect on normal terminal operation and is intended for development and performance investigation only.

Architecture

b3tty uses a client/server model to enable the connection from a web browser to a pseudo terminal. When the server is started, a url where b3tty can be accessed from a web browser is displayed. When the url is visited through a web browser, the server renders an HTML page containing a JSON configuration object (window.B3TTY) with the terminal settings, then loads the frontend JavaScript bundle. The frontend determines the width of the browser window to know how many columns to use, then sends that size to the server and waits for confirmation before opening a WebSocket connection. The server then forks a new pseudo terminal process sized to those dimensions. All keyboard input is forwarded over the WebSocket to the pseudo terminal, and any output from the pseudo terminal is sent back and displayed on the page.

When the WebSocket connection closes unexpectedly (e.g. a network drop), a modal dialog is displayed in the browser informing the user that the connection has been closed. The terminal cursor is also hidden at this point. Dismissing the modal by clicking OK restores the page to its normal state. Clean closes — such as the shell process exiting normally — write [exited] to the terminal but suppress the dialog.

A word on security

Because b3tty is opening a connection from a web browser to a new psuedo terminal proccess as the user of b3tty's parent process, it's important to ensure the connection and access to the server are secure. For this reason, b3tty features several security features.

Origin check

The server will only allow connections from localhost or 127.0.0.1 as part of an origin check. This is to prevent opening a remote connection to a b3tty server. If access to remote machine is needed, run betty locally then SSH into the remove machine from b3tty.

Access token

By default, when the server starts, the url with a token of 24 randomly generated characters is provided and must be provided to access the b3tty client in the browser. This is to prevent a user without access to the terminal session where b3tty was started from guessing the url. This behavior can be disabled by passing the --no-auth flag at start up or setting the server.no-auth: true property in the b3tty config.

Each failed token validation incurs an exponential backoff delay before the 403 response is sent: 1s after the first failure, doubling on each subsequent attempt up to a maximum of 30s. The counter resets when a valid token is presented. Backoff is skipped entirely when --no-auth is set.

Content Security Policy

The server sets a Content-Security-Policy header on every page response. Scripts are restricted to same-origin files and a single per-request nonce used for the inline configuration block. 'wasm-unsafe-eval' is also permitted to support xterm.js's internal use of WebAssembly. Framing by other pages is blocked via frame-ancestors 'none'.

CSRF protection

The POST /size endpoint (used by the frontend to communicate terminal dimensions before opening the WebSocket) is protected against cross-site request forgery. Requests that carry a Sec-Fetch-Site header with a value other than same-origin are rejected. This header is set automatically by browsers and cannot be overridden by page scripts.

TLS

The connection between the client and server can be secured over TLS. Using TLS will change the protocol from http and ws to https and wss as well as change the default port from 8080 to 8443. TLS can be enabled by passing the --tls, --cert-file, and --key-file flags on start up or by setting the server.tls: true, server.cert-file: <file path>, and server.key-file: <file path> properties in the b3tty config.

Contributing

Pull requests are welcome. The following checks run automatically on every PR and must pass before merging:

  • Testmake test runs the full Go and bun test suites.
  • Formatmake format-check verifies that all frontend TypeScript source files are formatted with prettier. Run make format locally to fix any formatting issues before pushing.

When a PR that updates the VERSION file is merged into main, a git tag matching the new version number is created automatically.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL