This is my first CLI project, and I wanted to go in a direction I hadn’t tried before — no canvas, no browser, no UI framework at all in the traditional sense. Just a terminal. That became TRIX, a terminal-native IDE: a file tree, an editor, and a real embedded shell, all living in one TUI window with zero Electron and zero browser underneath it.
You can install it right now with pip install trix-ide if you want to poke around while reading.
Why a TUI, and why Textual
The pitch for TRIX to myself was simple: I spend most of my day in a terminal anyway, so why alt-tab between editor, file explorer, and shell when they could just live in the same window, keyboard-driven, with no mouse required?
I built it on Textual, a Python framework for building rich terminal UIs. It gives you widgets, layout, and event handling that feel closer to a real GUI framework than the curses-era TUIs most people picture. The three-panel layout — file tree, editor, terminal — maps almost directly onto Textual’s widget composition model, which made the initial skeleton come together fast:
from textual.app import App
from textual.containers import Horizontal
class TrixApp(App):
def compose(self):
yield Horizontal(
FileTreeWidget(),
EditorWidget(),
TerminalWidget(),
)
The hard part was never the layout. It was making each panel behave the way you’d expect from a real editor.
Embedding a real shell, not a fake one
The single trickiest piece of TRIX was the terminal panel. A lot of “embedded terminal” implementations in TUI apps fake it — they capture a subprocess’s stdout and print it into a text widget, which falls apart the moment you run something interactive like git commit without -m, or anything that expects a real pseudo-terminal.
I wanted cd, git, npm — everything — to just work, exactly like a normal PowerShell window. That meant reaching for winpty to get a genuine PTY-backed PowerShell process running underneath the widget, rather than shelling out and scraping text. The terminal widget reads from the PTY and renders raw output, so command history, interactive prompts, and colored output all behave correctly instead of needing to be specially handled.
The tradeoff: this ties the current build to Windows, since winpty’s native PowerShell embedding doesn’t have a direct equivalent path on Linux/macOS without swapping the whole approach. Cross-platform support is on the roadmap, but I’d rather ship something that works properly on one platform than something flaky everywhere.
Theming as data, not code
TRIX ships with Ayu Dark, Ayu Light, and Ayu Mirage themes (based on dempfi’s Ayu palette), cyclable with Ctrl+T. Rather than hardcoding colors into widgets, each theme is a plain JSON file describing every UI surface — borders, backgrounds, selection states, muted text, and so on:
{
"name": "Ayu Dark",
"appearance": "dark",
"style": {
"border": "#3f4043ff",
"border.focused": "#1b4a6eff",
"background": "#313337ff",
"element.hover": "#2d2f34ff",
"text": "#bfbdb6ff",
"text.muted": "#8a8986ff"
}
}
Once your visual state is just data, adding new themes is a matter of writing a new JSON file, not touching rendering code. Cycling themes at runtime just means swapping which style dictionary gets applied to the app’s CSS-like styling system — Textual supports this well since its styling is already declarative.
Keeping it keyboard-first
Every feature in TRIX has a shortcut — Ctrl+B to toggle the file tree, Ctrl+Shift+Z for zen mode, Ctrl+Shift+H to flip the layout direction, and a full shortcut reference available anytime with ?. Building this in from day one, rather than bolting it on, meant designing every widget to expose its actions as callable methods first and mouse/click handling second — the opposite order from most GUI tutorials, but the right one for a tool meant to be driven entirely from the keyboard.
What’s next
The roadmap is honest about what’s missing: no LSP support yet (so no autocomplete or go-to-definition), no git integration beyond what the embedded shell gives you for free, and no Linux/macOS support. All of that is next. There’s also an item on the roadmap for Claude AI integration, which I’m looking forward to getting into.
If you want to try it, pip install trix-ide or pipx install trix-ide gets you running in under a minute, and the source has the full setup for building from scratch.