phosphor
Phosphor
For the Rails developer who misses the terminal
A Crystal terminal UI framework that maps Rails conventions onto the Elm Architecture (MVU). If you've written a Rails app, you can read this framework's code on day one.
Why Crystal?
Crystal reads almost exactly like Ruby but compiles to native binaries — no JIT, no GC pauses at the wrong moment, no runtime to ship. A Rails developer can read Crystal code on day one. The differences that matter for a TUI framework are type safety (no NoMethodError at runtime) and fibers (lightweight green threads, like Go's goroutines, built in).
# This is valid Crystal. It looks like Ruby.
class TodoItem
getter text : String
getter done : Bool
def initialize(@text, @done = false)
end
def render
done ? "[✓] #{text}" : "[ ] #{text}"
end
end
The core mental model: Rails MVC → MVU
Rails developers think in Model–View–Controller. This framework maps most naturally to Model–View–Update — Elm's architecture, the same pattern Bubbletea uses — but with Rails naming conventions so nothing feels alien.
| Rails concept | TUI equivalent | What it does |
|---|---|---|
ActiveRecord model |
AppState struct |
Holds all app data — immutable snapshot |
| Controller action | handle(event) method |
Returns a new AppState, never mutates |
| Shared concern / base model | MockWidget |
Reusable, stateful UI primitive — lives in a shard |
| View component / ERB partial | Widget |
App-specific wrapper: translates events → Msg |
ActionView layout |
View |
Owns mounted widgets, focus stack, event routing |
before_action |
Middleware chain |
Intercepts events before your handler |
ApplicationController |
Screen base class |
Shared behaviour across all screens |
config/routes.rb |
Router |
Maps key bindings to handler methods |
rails server |
App.run |
Starts the explicit, readable event loop |
For the full architectural rationale, see DESIGN.md.
Project structure
Familiar to any Rails developer:
my_tui_app/
├── src/
│ ├── app.cr # Entry point — like config/application.rb
│ ├── state/
│ │ └── app_state.cr # Like your AR models, but an immutable struct
│ ├── screens/
│ │ ├── dashboard_screen.cr # Like a controller — owns a View
│ │ └── detail_screen.cr
│ ├── widgets/
│ │ ├── mock/
│ │ │ ├── list_mock.cr # Reusable primitive — could be its own shard
│ │ │ ├── input_mock.cr
│ │ │ └── spinner_mock.cr
│ │ ├── todo_list_widget.cr # App-specific wrapper around ListMock
│ │ ├── search_input_widget.cr
│ │ └── status_bar_widget.cr
│ ├── ports/
│ │ ├── stdin_port.cr # Continuous event source — keyboard
│ │ └── live_feed_port.cr # Continuous event source — e.g. live data feed
│ ├── handlers/
│ │ └── key_handler.cr # Like controller actions
│ └── router.cr # Like config/routes.rb
├── spec/
└── shard.yml # Like Gemfile
The key addition is widgets/mock/ — a home for reusable primitives that could be extracted into their own published shard, like a gem for UI components. The ports/ directory holds anything that emits events continuously, as opposed to one-shot async work.
What you get for free vs. Rails
| Rails gives you | This framework gives you |
|---|---|
| Database persistence | In-memory state (you bring your own DB layer) |
| HTTP request/response cycle | Terminal event/render cycle |
| Asset pipeline | Shard ecosystem (termbox-cr, etc.) |
| ActionCable | Port — continuous async event streams |
| ActiveJob / Sidekiq | Cmd — one-shot async work in fibers |
| Devise / Pundit | Not applicable — it's a local TUI |
| Puma thread pool | Crystal's fiber scheduler |
| ViewComponent gem | MockWidget shard (extractable) |
rails generate scaffolding |
Could be added — conventions are all here |
Platform support
phosphor supports Unix-like systems only: macOS, Linux, BSD, and WSL2 on Windows.
Native Windows console support is not on the roadmap. Windows users should run phosphor through WSL2, where it works the same as on any other Linux. See TASKS.md's Explicitly out of scope section for the full rationale.
Documentation
- DESIGN.md — Architecture: every layer explained with code samples and Rails analogies
- TASKS.md — Implementation roadmap, in build order
- CHANGELOG.md — Release notes
- CONTRIBUTING.md — How to contribute, report bugs, suggest features
- STABILITY.md — API stability tiers
- RELEASING.md — Versioning and release process
License
TBD
phosphor
- 0
- 0
- 0
- 0
- 1
- about 3 hours ago
- May 26, 2026
MIT License
Sun, 28 Jun 2026 16:36:14 GMT