A terminal that
runs at idle.

A GPU-accelerated terminal emulator written in Rust on wgpu and winit. The event loop rests. The PTY blocks. The cursor blinks in 423 nanoseconds.

  • macOS
  • Linux
  • Windows
[01 / 04]

Six primitives, one
quiet terminal.

Fasty is small on purpose. No plugin runtime, no daemon, no telemetry. The whole binary is one Rust crate plus the bits you can see in src/. Every feature earned its keep.

01

Cell rendering in WGSL

Every glyph, every cursor blink, every scroll update passes through a single wgpu pipeline. WGSL shaders handle the cell grid across Vulkan, Metal, DX12 and GLES with one shader set.

// renderer/pipeline.wgsl
@vertex
fn vs_cell(
  @location(0) pos: vec2<f32>,
  @location(1) cell: vec4<u32>,
) -> VSOut {
  var out: VSOut;
  out.clip = cell;
  out.pos  = vec4<f32>(pos, 0.0, 1.0);
  return out;
}

@fragment
fn fs_cell(in: VSOut) -> @location(0) vec4<f32> {
  return sample_atlas(in.clip);
}
02

Sub-1% CPU at idle

The event loop rests in Wait. The PTY reader blocks at the kernel. The cursor blinks through a 48-byte fast-path that skips cell iteration, atlas dirty checks, and font rasterization.

# stock M3 Pro · single tab · idle shell prompt
$ ps -p $(pgrep fasty) -o %cpu,rss,etime,thcount
  %CPU    RSS       ELAPSED   TH
  0.7     52416    02:14:08   4

$ powermetrics --samplers cpu_power -i 1000 -n 1 | grep fasty
  fasty: idle   wakeups/s: 0.0   pkg_energy: 12 mJ
03

Tab tear-out, sub-millisecond

Drag a tab outside the window. The GPU atlases are shared via Arc, so the new window spawns without recompiling glyph caches. The OS drag gesture takes it from there.

shared atlas via Arc · spawn: 0.8 ms

04

Bottombar widgets

A 20px strip above the scrollback for what you actually want to see. Git status, clock, kubectl context, AWS profile, or anything you can run as a shell command. Click actions: copy, run, open.

kubectl get pods -n prod
NAME READY STATUS RESTARTS AGE
api-7d4b9c-xjp2 1/1 Running 0 14m
api-7d4b9c-kw7r 1/1 Running 0 14m
worker-9f3a-mn1 2/2 Running 1 3h
main ↑2 ●3 14:32:08 kube: prod click → cycle aws: dev
widgets.toml → poll interval · click action · align
[+]

Snippets, TUI-safe.

Type gst, press Tab, get git status. Bundled defaults cover git, docker, rust, filesystem, search, system. VSCode-style placeholders, live reload. TUI apps take precedence and Tab passes through to vim, fzf, htop.

# snippets.toml
[snippet]

"gst" = "git status"
"gcm" = "git commit -m \"${1:message}\""
"cb"  = "cargo build"
"dps" = "docker ps"
"ll"  = "ls -lah"
"ports" = "ss -tlnp"
[02 / 04]

The numbers are
boring on purpose.

Measurements on an Acer Aspire 3 with a Ryzen 5 and 8 GB of RAM, running CachyOS. Single tab, idle shell prompt, JetBrains Mono 14pt. Methodology and benchmark sources live in the repo under benches/.

fasty % cargo bench --release cachyos · ryzen 5 · 8gb
   Compiling fasty 0.4.1 (38 crates)
    Finished `release` profile [optimized] in 4.21s

   Running benches/parser_bench
   parser_plain_text   time:   [374.70 µs 413.21 µs 451.07 µs]
   parser_sgr_ansi     time:   [675.72 µs 692.18 µs 710.08 µs]
   parser_complex      time:   [380.68 µs 389.77 µs 399.65 µs]

Found 3 benchmarks; finish in 4.21s
profile: release · LTO fat · codegen-units=1 · strip · panic=unwind
parser_plain_text
Feeds VtParser::feed_str() a 10 KB buffer of plain text (no escapes). Throughput floor: how fast bytes from the PTY move through the parser when nothing fancy is happening — cargo build output, cat a log file, git log.
parser_sgr_ansi
10 KB of SGR escape sequences (\x1b[31mred\x1b[0m…) — the colour codes every ls --color, git diff, and test runner emits. The slower path: each byte can be part of a multi-byte escape or trigger a state transition in the parser state machine.
parser_complex
Mixed cursor moves, SGR, text, and carriage returns — what a real TUI like htop or btop emits at 60 Hz to redraw its dashboard. Tracks whether the parser keeps up with a full-screen redraw cycle.

Every byte the shell writes passes through feed_str() before it reaches the cell grid. The median parser cost per 10 KB chunk is under 0.7 ms — fast enough to parse the output of a heavy cargo test --release run in real time without ever stalling the renderer. Run the bench yourself with cargo bench --bench parser_bench or read the source at benches/parser_bench.rs.

E2E BENCHMARKS · startup + throughput scripts/benchmark_e2e.py · 3 runs · Acer Aspire 3 · CachyOS · run the script to reproduce
Terminal Startup
sh -c true
Plain text
100k lines
ANSI/SGR
50k lines
Fasty 0.4.1 1.05s ± 0.28s 1.99s ± 0.08s 1.94s ± 0.13s
Ghostty 1.77s ± 0.30s 2.41s ± 0.28s 1.99s ± 0.25s
Konsole 0.68s ± 0.25s 2.26s ± 0.49s 1.20s ± 0.32s

Startup = sh -c true round-trip · Plain text = cat 100k lines · ANSI/SGR = cat 50k lines of styled output · Source: scripts/benchmark_e2e.py · Fasty compiled with cargo build --release.

[03 / 04]

Five built-ins,
infinite drop-ins.

Fasty ships with five tuned palettes and reads custom JSON themes from ~/.config/fasty/themes/. Drop a file in, name it after the theme, switch from the command palette. Theme changes re-render every surface live: scrollback, topbar, tabs, settings, context menu.

REGISTRY · 5 bundled + custom ~/.config/fasty/themes/
  • Fasty DEFAULT Tomorrow Night palette · bundled
    default
  • Catppuccin github.com/catppuccin · bundled
    catppuccin
  • One Dark Atom One Dark · bundled
    one-dark
  • Solarized Dark Ethan Schoonover · bundled
    solarized-dark
  • High Contrast A11Y WCAG AAA · bundled
    high-contrast

Custom themes are JSON files. All 18 ANSI fields are optional except background and foreground; missing colors fall back to the foreground.

[04 / 04]

One curl.
You're in.

The installer scripts detect your OS and architecture, pull the matching release, and drop the binary where it belongs. No daemon. No background service. No telemetry phone-home.

$ curl -fsSL https://raw.githubusercontent.com/diegoleteliers10/fasty/main/instalar.sh | bash

Apple Silicon & Intel · installs to /Applications · CLI symlink to /usr/local/bin/fasty

Manual builds and per-arch archives on the releases page. First-run config lives at ~/.config/fasty/fasty.toml.