import SwiftTUI
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack(spacing: 1) {
TextFigure("\(count)", font: .future)
.frame(minWidth: 14, alignment: .center)
Button("Increment") { count += 1 }
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
@main
struct CounterApp: App {
var body: some Scene {
WindowGroup("Counter") { CounterView() }
}
}
Build Swift Terminal User Interfaces
Views, State, Observation, Gestures, Animations—
SwiftUI semantics, drawn in terminal cells. One native binary for macOS, Linux, and Windows.
A real SwiftTUI app, running live in your browser.
Starting the WASI runtime
The source and static site remain available.
The same counter in your own terminal: one clone, one command.
Run it locallyGet started
A terminal and a toolchain. That's it.
SwiftTUI apps are plain SwiftPM packages. Any Swift 6.3+ toolchain builds and runs them from the command line on macOS, Linux, or Windows: no Xcode project, no simulator, no app store.
# macOS, Linux, or Windows — any Swift 6.3+ toolchain
git clone https://github.com/SwiftTUI/swift-tui-counter-demo.git
cd swift-tui-counter-demo
swift run --package-path counter counterThe counter from the demo above, drawn in your own terminal. Space or a click increments; Ctrl-C quits and restores your shell.
Pick a toolchain
swiftly on macOS and Linux, a current Xcode on a Mac, or the swift.org installer on Windows.
Start your own app
// Package.swift
.package(
url: "https://github.com/SwiftTUI/swift-tui",
.upToNextMinor(from: "0.9.11")
),
// in your executable target:
.product(name: "SwiftTUI", package: "swift-tui")Paste the counter above into main.swift and swift run. Then the first-hour guides.
Why SwiftTUI
A proven UI model, pointed at the terminal.
Most TUI toolkits offer a low-level draw loop or a widget set with its own state story. SwiftTUI takes the declarative model SwiftUI has proven at platform scale and aims it at terminal cells: you declare views; the framework owns layout, focus, redraw, and the terminal.
- 01
State in, screen out
Change a value and the runtime recomputes layout and rewrites exactly the cells that changed. No draw loop, no buffer diffing, no repaint bookkeeping.
View · @State · @Observable · body - 02
Real components, real focus
Buttons, text fields, pickers, sliders, lists, tables, and scroll views, with focus traversal, keyboard chords, tap · drag · hover gestures, and animation built in.
@FocusState · TapGesture · withAnimation · List - 03
The terminal, negotiated for you
Truecolor, Kitty and Sixel images, OSC 8 links, and mouse reporting are probed per session and degrade gracefully, so one binary is right in kitty, over SSH, or in CI. --accessible, --reduce-motion, --no-color, and --ascii come free.
TerminalCapabilityProfile · Kitty · Sixel · OSC 8 - 04
One binary, testable without a TTY
Swift 6 compiles your interface into a single executable with checked concurrency. A frame is a pure function of the view tree and a size, so tests compare integer-cell frames with no terminal attached.
SwiftPM · Swift 6 · RenderOnce
How it compares
The first five columns are the day-one terminal experience; the last two are where the same source can go later.
Verified August 2026 against current releases: Bubble Tea 2.0 · Textual 8.2 · Ratatui 0.30 · Ink 7.1. ✓ first-party · ~ partial, separate package, or raw mouse events · — none · local only the app runs as a process you host and streams a terminal to the browser; there is no static build to deploy. SwiftTUI's browser paths render to the DOM with a real accessibility tree, not through a terminal emulator.
Coming from SwiftUI? The shape is the same; the terminal-native differences are deliberate and recorded in the open. Read the primer.
Showcase
Built with SwiftTUI.
The counter above fits on one screen. These do not. All four are maintained examples in swift-tui-examples: clone the repo and each one builds and runs with one command.




Further reading
Beyond the terminal
Terminal first, not terminal only. The same App runs in a browser: --web serves it on localhost, or build it with SwiftTUIWASI and ship a static bundle with @swifttui/web, as the demo above is. It also embeds in native apps through swift-tui-swiftui (macOS, iOS) and swift-tui-android (arm64 preview). No terminal emulators. Start from Hosts and Platforms.
Community
Build with us.
Development happens in public on GitHub, and the people building SwiftTUI are on Discord. Come ask questions, show what you are building, or talk through a contribution.