github.com/webmatze/anvil
0.1.0 / published Sep 2, 2026 / repository
Terminal UI library for Crystal with two modes of operation: fullscreen (alternate screen, 30/60 fps) and inline (the scrollback stays; only a live region at the bottom is redrawn).
anvil
Terminal-UI-Library für Crystal, mit zwei Betriebsarten:
- Inline — der Scrollback bleibt erhalten, nur eine Live-Region am unteren Rand wird neu gezeichnet. Fertige Inhalte wandern einmal in die History und bleiben dort kopier- und durchsuchbar. Das Modell von smith und Claude Code.
- Fullscreen — Alternate Screen, die App besitzt das Raster. Für Animation und Vollbild-Werkzeuge, gemessen flickerfrei bei 60 fps.
Beide teilen sich alles oberhalb der Zeichenfläche: Text, Blöcke, Eingabe, Schleife.
Unterbau ist termisu — ausgewählt nach einem Vergleich gegen crysterm, skuznetsov/crystal_tui und handgeschriebenen Code, siehe BENCHMARK.md.
Beispiel
require "anvil"
include Anvil
backend = Backend.new(alternate_screen: false)
surface = Surface::Inline.new(backend, height: 1)
app = App.new(surface, Loop.for(backend, target_fps: 20))
app.status = ->(width : Int32) { Text.line("bereit", Text::Style.new(fg: Text::Palette::ACCENT)) }
app.run do |input|
app.add_block(View::TextBlock.new("❯ #{input}"))
app.idle!
end
Eine vollständige App mit streamenden Blöcken, Werkzeug-Zuständen und einer modalen
Rückfrage mitten im Vorgang: crystal run examples/agent_demo.cr.
Aufbau
Backend Terminal · Raw-Mode · Eingabe · Ereignisse · Signal-Aufräumen
Surface Fullscreen │ Inline │ Memory (für Tests)
Text Style · Span · StyledLine · wrap · truncate · Palette
View Block · Segment · Region.compose (Drop-Priorität)
Widgets InputEditor · ListPopup
Loop Takt · Drift-Korrektur · Resize-Entprellung
App Blöcke · Live-Region · Modals · Zustandsmaschine
Bewusst nicht enthalten: CSS, Layout-Engine, Widget-Zoo. Layout bleibt beim Aufrufer —
eine Liste von StyledLine und die Regel, was auf kleinem Schirm zuerst weicht.
Was es kostet
| Binary (gestrippt, gleiche App) | 0,97 MB — gegenüber 0,60 MB handgeschrieben, 35,4 MB crysterm |
| Bytes pro Redraw (Region 15 Zeilen, 2 bewegt) | 118 |
| Bytes pro Vollbild-Frame (200×50, Dashboard) | 6 836 — identisch mit direktem termisu |
| Build | Sekunden |
Entwicklung
mise install && shards install
crystal spec # 68 Specs, kein Terminal nötig
python3 examples/check_demo.py # vollständige Sitzung durch ein PTY
python3 bench/restore_check.py anvil # Aufräumen bei Signal
FRAMES=600 bench/run.sh && bench/report.py # Leistungs-Regression
Der Benchmark ist Regressionstest: bin/anvil muss die Zahlen von bin/baseline
(handgeschrieben, ohne Library) halten.
Entwurf und Begründungen: DESIGN.md · Anforderungen aus smith: SMITH-REQUIREMENTS.md