The Postgres client landscape has always had a gap in the middle. On one side sits psql, the official command-line client that ships with every PostgreSQL installation. It works, it is fast, and experienced users know its meta-commands by heart. On the other side sit GUI clients like DBeaver, TablePlus, and pgAdmin, which offer point-and-click schema browsers, visual query builders, and connection managers. Between these two poles there is not much, and what exists is fragmented.
pgtui is a new Terminal User Interface client for PostgreSQL that occupies that middle ground deliberately. The introduction post on the author’s blog is concise, which is appropriate for an early project, but the tool’s existence raises a set of design questions worth thinking through: what does a TUI database client need to do well, what does specializing in Postgres make possible, and why does this space keep producing new tools without any of them becoming canonical?
Why TUI Is Architecturally Different from Terminal REPL
The distinction between a TUI and a REPL client is not just cosmetic. pgcli is probably the most widely used alternative to psql, and it is genuinely excellent: it adds autocompletion using schema introspection, syntax highlighting, smart pager integration, and a proper multi-line editor. But pgcli is still a REPL. It reads a line or a block, executes it, prints output, and advances the prompt. The output scrolls. If you run \dt, then \d some_table, then a query, all three outputs live in your terminal buffer, each one pushing the previous up and out of view.
A TUI client owns the screen. It partitions the terminal into panes, manages focus between them, and responds to keyboard input that is not just “submit this query.” The result set stays in a fixed pane that you scroll within. A schema browser can persist in a sidebar across your entire session. Query history becomes a navigable list rather than a readline buffer you arrow through.
This changes exploratory database work in a concrete way. When you are mapping an unfamiliar schema, being able to keep a table list visible while simultaneously editing and running queries against those tables saves constant context switching. The information you need does not disappear as you work.
Framework Choices and What They Signal
Historically, building a TUI in Python meant choosing between curses, which is low-level and tedious, or urwid, which has decent widget support but a learning curve that does not match its apparent simplicity. The situation changed significantly with Textual, the framework from Will McGugan and the team behind Rich. Textual introduces a CSS-like layout system, reactive state management, and a widget model that makes multi-pane terminal apps substantially easier to build and maintain.
pgcli itself uses prompt_toolkit, which is well-suited for sophisticated REPL input handling but was never designed for full-screen multi-pane layouts. For a project aiming at the full TUI design space, Textual is a more natural choice.
The Go and Rust ecosystems have their own answers. Bubble Tea follows the Elm architecture, with immutable state updates and explicit message passing. Ratatui takes a similar approach in Rust, and it’s the foundation for some of the more polished terminal tools shipping today. Both produce responsive, low-overhead apps, but they push more state management complexity onto the developer upfront. Textual’s object-oriented model is more accessible for contributors coming from a Python or web background, which matters for an early open-source project trying to attract help beyond the original author.
The Multi-Database Trap
The closest prior art to pgtui in terms of design is lazysql, a Bubble Tea-based TUI that supports MySQL, PostgreSQL, SQLite, and other databases. lazysql is modeled on lazygit, which has become something of a canonical example of what a keyboard-first TUI developer tool can be. The interface is clean and the keyboard shortcuts are well-considered.
But lazysql’s breadth is also its constraint. Supporting multiple databases means designing for a common denominator. You can browse tables and run queries, but you cannot lean into Postgres-specific features without building separate rendering paths per database or cutting features entirely. Most multi-database tools choose the latter.
A Postgres-specific TUI can afford to be opinionated. EXPLAIN ANALYZE output is notoriously dense as raw text; a dedicated client can parse it and render it as a collapsible tree, surfacing the expensive nodes without burying them in indentation. PostgreSQL’s type system is richer than most databases, and displaying jsonb, array types, composite types, and domain types in ways that respect their structure requires knowing what you’re rendering. Table inheritance and partition hierarchies are Postgres concepts with no direct equivalents elsewhere; they deserve first-class display.
There is also the matter of psql-specific behavior that experienced users carry as muscle memory. The \set ON_ERROR_STOP on pattern, \copy for local file transfers, \timing, and client-side variables are all features a multi-database client has little reason to implement. A Postgres-specific one can build them in properly.
What Makes TUI Database Clients Actually Work
The features that differentiate a usable TUI from one that gets abandoned fall into a few consistent categories.
Result navigation is the first test. Scrolling rows is straightforward; scrolling columns on wide result sets is harder and most tools handle it poorly. The external pager pspg is an instructive comparison: it is not a TUI client but rather a smart pager that psql can pipe output to, and its column navigation and header-freeze behavior set a useful benchmark for what good result browsing looks like in a terminal.
Query history should be searchable, not just navigable. Linear up-arrow navigation works for occasional use; for any sustained query workload you need to search by fragment. pgcli handles this through fzf integration or a built-in fuzzy finder. A TUI client has more room to build this into a dedicated history pane with filtering.
Transaction handling is where design decisions get consequential. Should the client wrap each statement in an implicit transaction and roll back on error? Should it offer an explicit transaction mode? How should it surface PostgreSQL’s error-in-transaction state, where subsequent commands fail until you issue a ROLLBACK? These choices determine whether the tool is safe to use in production contexts or only in development.
Connection management is a quality-of-life concern that becomes critical quickly. Named connection profiles, the ability to switch connections without restarting the client, and a persistent, visible indicator of which database and role you’re connected to are all features that feel minor until they’re missing.
Why This Space Keeps Producing New Tools
The reason new database TUI clients appear regularly without any single one becoming dominant is that the feature set that matters depends entirely on workflow. A developer doing schema migrations cares about different capabilities than someone running analytics queries or debugging a production incident under pressure. A tool optimized for schema exploration will frustrate someone running scripted migrations.
pgtui is new enough that it is still finding its shape. The introduction post is a starting point, not a specification. Where the tool goes depends on which problems its author keeps running into in their own Postgres work, and whether it attracts contributors with complementary use cases. Solo open-source tools guided by the author’s own friction points tend to be the most coherent, even if they are narrower in scope.
The opportunity in this space is real. A Postgres-specific TUI with genuine schema introspection, opinionated rendering of Postgres output, and keyboard-first navigation would fill a gap that psql, pgcli, and multi-database tools all leave open. Whether pgtui is the project that fills it completely is an open question, but it is pointed at the right problem.