{"id":45029161,"url":"https://github.com/phranck/tuikit","last_synced_at":"2026-02-27T10:01:16.889Z","repository":{"id":335173826,"uuid":"1144520116","full_name":"phranck/TUIkit","owner":"phranck","description":"A declarative, SwiftUI-like framework for building Terminal User Interfaces in Swift.","archived":false,"fork":false,"pushed_at":"2026-02-16T00:34:40.000Z","size":178015,"stargazers_count":76,"open_issues_count":1,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-19T07:55:04.112Z","etag":null,"topics":["linux","linux-app","macos","swift","swiftui","terminal","terminal-app","tui","vt220"],"latest_commit_sha":null,"homepage":"https://tuikit.dev","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phranck.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-28T19:01:57.000Z","updated_at":"2026-02-18T09:48:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/phranck/TUIkit","commit_stats":null,"previous_names":["phranck/tuikit"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/phranck/TUIkit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phranck%2FTUIkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phranck%2FTUIkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phranck%2FTUIkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phranck%2FTUIkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phranck","download_url":"https://codeload.github.com/phranck/TUIkit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phranck%2FTUIkit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29890653,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T09:48:51.284Z","status":"ssl_error","status_checked_at":"2026-02-27T09:48:43.992Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linux","linux-app","macos","swift","swiftui","terminal","terminal-app","tui","vt220"],"created_at":"2026-02-19T04:33:10.071Z","updated_at":"2026-02-27T10:01:16.880Z","avatar_url":"https://github.com/phranck.png","language":"Swift","readme":"[![CI](https://github.com/phranck/TUIkit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/phranck/TUIkit/actions/workflows/ci.yml)\n![Tests](https://img.shields.io/badge/Tests-1170%2B_passing-brightgreen)\n[![Release](https://img.shields.io/github/v/release/phranck/TUIkit?label=Release)](https://github.com/phranck/TUIkit/releases/latest)\n![Swift 6.0](https://img.shields.io/badge/Swift-6.0-F05138?logo=swift\u0026logoColor=white)\n![Platforms](https://img.shields.io/badge/Platforms-macOS%20%7C%20Linux-blue)\n![License](https://img.shields.io/badge/License-MIT-lightgrey?style=flat)\n![i18n](https://img.shields.io/badge/i18n-5%20Languages-orange)\n\n![TUIkit Banner](.github/assets/github-banner.png)\n\n# TUIkit\n\n\u003e [!TIP]\n\u003e **☕ Support TUIkit Development**\n\u003e\n\u003e If you enjoy TUIkit and find it useful, consider supporting its development! Your donations help cover ongoing costs like hosting, tooling, and the countless cups of coffee that fuel late-night coding sessions. Every contribution, big or small, is greatly appreciated and keeps this project alive. Thank you! 💙\n\u003e\n\u003e [![Donate via PayPal](https://img.shields.io/badge/Donate-PayPal-blue?logo=paypal\u0026logoColor=white)](https://paypal.me/LAYEREDwork)\n\u003e [![Support on Ko-fi](https://img.shields.io/badge/Support-Ko--fi-FF5E5B?logo=ko-fi\u0026logoColor=white)](https://ko-fi.com/layeredwork)\n\n\u003e [!IMPORTANT]\n\u003e **This project is currently a WORK IN PROGRESS! I strongly advise against using it in a production environment because APIs are subject to change at any time.**\n\nA SwiftUI-like framework for building Terminal User Interfaces in Swift: no ncurses, no C dependencies, just pure Swift.\n\n## What is this?\n\nTUIkit lets you build TUI apps using the same declarative syntax you already know from SwiftUI. Define your UI with `View`, compose views with `VStack`, `HStack`, and `ZStack`, style text with modifiers like `.bold()` and `.foregroundColor(.red)`, and run it all in your terminal.\n\n```swift\nimport TUIkit\n\n@main\nstruct MyApp: App {\n    var body: some Scene {\n        WindowGroup {\n            ContentView()\n        }\n    }\n}\n\nstruct ContentView: View {\n    @State var count = 0\n    \n    var body: some View {\n        VStack(spacing: 1) {\n            Text(\"Hello, TUIkit!\")\n                .bold()\n                .foregroundColor(.cyan)\n            \n            Text(\"Count: \\(count)\")\n            \n            Button(\"Increment\") {\n                count += 1\n            }\n        }\n        .statusBarItems {\n            StatusBarItem(shortcut: \"q\", label: \"quit\")\n        }\n    }\n}\n```\n\n## Features\n\n### Core\n\n- **`View` protocol**: the core building block, mirroring SwiftUI's `View`\n- **`@ViewBuilder`**: result builder for declarative view composition\n- **`@State`**: reactive state management with automatic re-rendering\n- **`@Environment`**: dependency injection for theme, focus manager, status bar\n- **`App` protocol**: app lifecycle with signal handling and run loop\n\n### Views \u0026 Components\n\n- **Primitive views**: `Text`, `EmptyView`, `Spacer`, `Divider`, `Image` (ASCII art rendering, multiple color modes, async loading)\n- **Layout containers**: `VStack`, `HStack`, `ZStack`, `LazyVStack`, `LazyHStack` with alignment and spacing\n- **Interactive**: `Button`, `Toggle`, `Menu`, `TextField`, `SecureField`, `Slider`, `Stepper`, `RadioButtonGroup` with keyboard navigation\n- **Data views**: `List`, `Table`, `Section`, `ForEach`, `NavigationSplitView`\n- **Containers**: `Alert`, `Dialog`, `Panel`, `Box`, `Card`\n- **Feedback**: `ProgressView` (5 bar styles), `Spinner` (animated)\n- **`StatusBar`**: context-sensitive keyboard shortcuts\n\n### Styling\n\n- **Text styling**: bold, italic, underline, strikethrough, dim, blink, inverted\n- **Full color support**: ANSI colors, 256-color palette, 24-bit RGB, hex values, HSL\n- **Theming**: 6 predefined palettes (Green, Amber, Red, Violet, Blue, White)\n- **Border styles**: rounded, line, double, thick, ASCII, and more\n- **List styles**: `PlainListStyle`, `InsetGroupedListStyle` with alternating rows\n- **Badges**: `.badge()` modifier for counts and labels on list rows\n\n### Notifications\n\n- **Toast-style notifications**: transient alerts via `.notificationHost()` modifier\n\n### Internationalization (i18n)\n\n- **5 languages built-in**: English, German, French, Italian, Spanish\n- **Type-safe string constants**: Compile-time verified `LocalizationKey` enum\n- **Persistent language selection**: Automatic storage with XDG paths\n- **Fallback chain**: Current language → English → key itself\n- **Thread-safe operations**: Safe language switching at runtime\n\n### Advanced\n\n- **Lifecycle modifiers**: `.onAppear()`, `.onDisappear()`, `.task()`\n- **Key handling**: `.onKeyPress()` modifier for custom keyboard shortcuts\n- **Storage**: `@AppStorage`, `@SceneStorage` with JSON backend\n- **Preferences**: bottom-up data flow with `PreferenceKey`\n- **Focus system**: Tab/Shift+Tab navigation, `.focusSection()` for grouped areas\n- **Render caching**: `.equatable()` for subtree memoization\n\n## Run the Example App\n\n```bash\nswift run TUIkitExample\n```\n\nPress `q` or `ESC` to exit.\n\n## Installation\n\n### Quick Start with CLI\n\nInstall the `tuikit` command and create a new project:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/phranck/TUIkit/main/project-template/install.sh | bash\ntuikit init MyApp\ncd MyApp \u0026\u0026 swift run\n```\n\nSee [project-template/README.md](project-template/README.md) for more options (SQLite, Swift Testing).\n\n### Manual Setup\n\nAdd TUIkit to your `Package.swift`:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/phranck/TUIkit.git\", branch: \"main\")\n]\n```\n\nThen add it to your target:\n\n```swift\n.target(\n    name: \"YourApp\",\n    dependencies: [\"TUIkit\"]\n)\n```\n\n\u003e **Tip:** `import TUIkit` re-exports all sub-modules. For finer control you can import individual modules: `TUIkitCore`, `TUIkitStyling`, `TUIkitView`, or `TUIkitImage`.\n\n## Theming\n\nTUIkit includes predefined palettes inspired by classic terminals:\n\n```swift\n@main\nstruct MyApp: App {\n    var body: some Scene {\n        WindowGroup {\n            ContentView()\n        }\n        .palette(SystemPalette(.green))  // Classic green terminal\n    }\n}\n```\n\nAvailable palettes (all via `SystemPalette`):\n- `.green`: Classic P1 phosphor CRT (default)\n- `.amber`: P3 phosphor monochrome\n- `.red`: IBM 3279 plasma\n- `.violet`: Retro sci-fi terminal\n- `.blue`: VFD/LCD displays\n- `.white`: DEC VT100/VT220 (P4 phosphor)\n\n## Internationalization\n\nTUIkit includes comprehensive i18n support with 5 languages and type-safe string constants:\n\n```swift\nimport TUIkit\n\nstruct MyView: View {\n    var body: some View {\n        VStack {\n            // Type-safe localized strings\n            Text(localized: LocalizationKey.Button.ok)\n            LocalizedString(LocalizationKey.Error.notFound)\n\n            // Switch language at runtime\n            Button(\"Deutsch\") {\n                AppState.shared.setLanguage(.german)\n            }\n        }\n    }\n}\n```\n\n**Supported languages**: English, Deutsch, Français, Italiano, Español\n\nFor complete documentation, see [Localization Guide](https://github.com/phranck/TUIkit/blob/main/Sources/TUIkit/TUIkit.docc/Articles/Localization.md) in the DocC documentation.\n\n## Architecture\n\n- **Modular package**: 5 Swift modules + 1 C target (see Project Structure below)\n- **No singletons for state**: All state flows through the Environment system\n- **Pure ANSI rendering**: No ncurses or other C dependencies\n- **Linux compatible**: Works on macOS and Linux (XDG paths supported)\n- **Value types**: Views are structs, just like SwiftUI\n\n## Project Structure\n\n```\nSources/\n├── CSTBImage/            C bindings for stb_image (PNG/JPEG decoding)\n├── TUIkitCore/           Primitives, key events, frame buffer, concurrency helpers\n├── TUIkitStyling/        Color, theme palettes, border styles\n├── TUIkitView/           View protocol, ViewBuilder, State, Environment, Renderable\n├── TUIkitImage/          ASCII art converter, image loading (depends on CSTBImage)\n├── TUIkit/               Main module: App, Views, Modifiers, Focus, StatusBar, Notification\n│   ├── App/              App, Scene, WindowGroup\n│   ├── Environment/      Environment keys, service configuration\n│   ├── Focus/            Focus system and keyboard navigation\n│   ├── Localization/     i18n service, type-safe keys, translation files (5 languages)\n│   ├── Modifiers/        Border, Frame, Padding, Overlay, Lifecycle, KeyPress\n│   ├── Notification/     Toast-style notification system\n│   ├── Rendering/        Terminal, ANSIRenderer, ViewRenderer\n│   ├── StatusBar/        Context-sensitive keyboard shortcuts\n│   └── Views/            Text, Stacks, Button, TextField, Slider, List, Image, ...\n└── TUIkitExample/        Example app (executable target)\n\nTests/\n└── TUIkitTests/          1100+ tests across 150+ test suites (including i18n consistency \u0026 localization tests)\n```\n\n## Requirements\n\n- Swift 6.0+\n- macOS 14+ or Linux\n\n## Developer Notes\n\n- Tests use Swift Testing (`@Test`, `#expect`): run with `swift test`\n- All 1170 tests run in parallel\n- The `Terminal` class handles raw mode and cursor control via POSIX `termios`\n\n## Contribution\n\n## License\n\nThis repository has been published under the [MIT](https://mit-license.org) license.\n","funding_links":["https://paypal.me/LAYEREDwork","https://ko-fi.com/layeredwork"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphranck%2Ftuikit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphranck%2Ftuikit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphranck%2Ftuikit/lists"}