Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

tui

Start the interactive terminal UI.

xrat tui

xrat setup also installs an xratui shortcut next to the xrat binary (run automatically by install.sh/just install, or manually after cargo install/cargo binstall):

xratui

The TUI has no command-specific flags. It uses the same global flags as other commands, including --database, --config, --xray, --v2ray, --sing-box, -v, and -q.

The TUI is an interactive view over xrat’s shared database, subscription, testing, and runtime services. It does not keep a separate copy of business logic: config changes, imports, tests, and runtime operations use the same app services as the CLI commands.

Tabs

The TUI is a single dashboard. The top-left table has two tabs; switching the tab also swaps the detail panel on the right. The Testing strip, the Logs panel, and the Runtime panel stay visible under both tabs.

TabPurpose
ConfigsBrowse, filter, start, test, enable, disable, delete, and share configs
SubscriptionsInspect subscriptions, refresh them, and share subscription/API URLs

Use [ and ] to move to the previous / next tab.

The TUI opens on the Configs tab. The bottom bar shows the version (with an upgrade hint when a newer release is available) and a help shortcut. Test batches are started and monitored from the Configs tab itself; there is no separate Tests view.

Global Keys

KeyAction
[, ]Switch to previous / next table tab
TabCycle card focus (Table → Detail → Log → Runtime)
Shift+TabCycle card focus in reverse
1Focus the table card
2Focus the logs/events card
3Focus the detail card
4Focus the runtime card
j, kMove row / scroll the focused card down/up
arrow keysMove row / scroll the focused card down/up
PgUp, PgDnPage the focused card up / down
Home, EndJump to the top / bottom of the focused card
iImport a config or subscription link
,Open the settings editor
?Open help
EscClose modal, leave search, or go back
q, Ctrl+CQuit

Cards and Scrolling

The dashboard has four cards: the table (Configs/Subscriptions), Logs, the detail panel, and Runtime. Card titles show their direct focus shortcuts (1:, 2:, 3:, 4:). Tab / Shift+Tab move focus between them; the focused card is drawn with an accent border. j/k (or the arrow keys) move the row selection when the table is focused, and scroll the focused card otherwise. PgUp/PgDn step by a screenful and Home/End jump to the first/last row or top/bottom of the card. Cards that overflow their height show a scrollbar.

In the Logs card, long messages wrap inside the message column and continuation lines stay indented under it, so the time, level, source, and kind columns stay aligned and one entry never blends into the next.

Settings Modal

Press , from either tab to edit operational values from the active config.toml, including runtime and inbound settings, rotation, tests, subscription refresh, routing, the API server, and parser mode. Fixed DNS options are editable and take effect on the next managed-runtime restart. Database, binary paths, dynamic [dns.hosts] entries, and Geo/MMDB asset management remain file-only settings. Engine-specific DNS limitations are reported when a runtime configuration is generated.

The modal shows a two-level setting tree on the left and effective values on the right. Deeper groups share their parent page under subheaders such as General, Authentication, Cache, and Remote. Use Left/Right, Enter, or Tab/Shift+Tab to switch panes, then j/k or Up/Down to navigate the active pane. Use / to filter, Enter to edit or toggle, h/l to cycle choices, and r to remove an explicit override and return to its built-in default. List fields use comma-separated values. Secret fields stay masked; enter a literal replacement or env:VARIABLE_NAME. Ctrl+S validates and saves without closing the modal, while Esc cancels the current edit or closes the modal. Closing with unsaved changes asks for confirmation. On compact terminals, only the focused Sections or Values pane is shown; use Left and Right to switch between them.

A contextual Help pane follows the selected field. It explains what the field controls, shows its accepted values or input format, provides a safe TOML assignment example, and states whether the change applies live or needs a proxy runtime or daemon restart. It also shows the built-in default and whether the current value is inherited or explicitly configured. Value rows use · for an inherited default, + for an explicit override, and * for an unsaved change; the Help pane includes the same legend. Secret examples use safe placeholders (and environment-variable references where supported) and never display configured secret contents.

Saving patches only changed keys, preserving comments and unrelated sections. New values apply to subsequent TUI tests and connections immediately. Changes to runtime or routing generation offer to restart an active proxy after saving; daemon-owned rotation, subscription-refresh, and API-server settings report that the daemon must be restarted.

Configs Tab

The Configs tab shows stored configs with latest test summaries and config state. The status marker column uses for active, for soft-deleted, for disabled, and ! for failed configs. Long names are truncated in the table. It supports focused actions, test batches, and managed runtime controls.

KeyAction
/Edit config search
Ctrl+UClear search while editing
SCycle sort field
FCycle filter: all, enabled, failed, has-delay
PCycle protocol filter
TShow or hide soft-deleted configs
EnterStart the focused config
e, xEnable or disable the focused config
dSoft-delete chord (see below)
DPurge chord (see below)
rRestore chord (see below)
tTest chord (see Testing Strip)
KStop/disconnect the managed runtime
RRestart the managed runtime
yShow a QR code for the focused config URI
cCopy the focused config URI

Chord keys

On the Configs tab, t, d, D, and r are chord leaders: press the leader, then a second key to pick the scope. The key bar shows the available second keys while a chord is armed; Esc (or any unbound key) cancels it. Every destructive action — single-row (d d, D D, r r) and multi-config alike — asks for an inline y/n confirmation in the key bar; there are no confirmation modals. Multi-config chords run as a single bulk database operation.

ChordAction
d dSoft-delete the focused config (confirm)
d fSoft-delete all failed configs
d vSoft-delete all visible (filtered) configs
d xSoft-delete all disabled configs
D DPurge the focused config (confirm)
D fPurge all failed configs
D vPurge visible configs that are already soft-deleted
D aEmpty trash — purge every soft-deleted config
r rRestore the focused soft-deleted config
r vRestore visible configs that are soft-deleted
r aRestore every soft-deleted config

Search matches the displayed config fields. Sorting can cycle through latency, ID, name, protocol, subscription, last-tested time, and imported time. Deleted configs are hidden by default; press T to include them.

The config detail panel shows the subscription a config belongs to (#id name) or none for configs added directly. The Configs table title shows the active subscription filter (· sub:<name> or · sub:orphans) when one is set from the Subscriptions tab.

Soft delete hides a config from normal views and workflows. Purge permanently deletes it. Both destructive actions require confirmation.

The Runtime panel shows the current managed runtime state, active config, current task, proxy endpoint, available proxy engines (xray / sing-box), daemon status and rotation schedule, config counts, and failure message when present. The API subscription URL is shown only when the HTTP API is enabled; when the API binds to 0.0.0.0/:: the panel shows the host’s LAN IP instead of the wildcard address. Runtime actions use the same runtime service as xrat connect, xrat disconnect, and xrat status. The same runtime prerequisites apply: the configured Xray/V2Ray binary must be available, runtime paths must be writable, and daemon/runtime configuration must be valid.

Focus a config on the Configs tab and press Enter to start or switch the runtime. Runtime operations run in the background and reload TUI data after completion.

Subscriptions Tab

The Subscriptions tab replaces the Configs table with the subscription list; the right Detail panel then shows the focused subscription’s metadata. The local HTTP API base64 subscription URL is shown in the Runtime panel.

The table starts with two synthetic rows that act as filters for the Configs tab:

  • All configs — clear the subscription filter; the Configs tab shows every config.
  • Orphans — show only configs that do not belong to any subscription (for example, configs added with xrat add).

Below them is one row per subscription. Focusing any row applies its filter to the Configs tab live, with no confirmation step; switch back to the Configs tab to browse the filtered set.

KeyAction
rRefresh the focused subscription
RRefresh all subscriptions with stored values
nRename the focused subscription
dDelete the focused subscription and its configs
yShow a QR code for the focused subscription URL
cCopy the focused subscription URL
uShow a QR code for the HTTP API /b64 subscription URL
UCopy the HTTP API /b64 subscription URL

Subscription actions apply to the focused subscription row; they are no-ops on the All configs and Orphans rows.

Press i from either tab to open the import modal, then paste one supported config share link or one HTTP(S) subscription URL. Config links are saved immediately. Subscription URLs open a second, compact name prompt; leaving it blank uses the displayed random name. File paths, raw base64 payloads, JSON, and multi-link text remain available through xrat import <input>.

Subscription refresh runs as a background task. While it runs, the Runtime card shows live activity and the bottom bar shows completion summaries that auto-hide. When refresh finishes, the TUI reloads database-backed data so both tabs reflect the new state, including any configs removed by subscription reconciliation.

Testing Strip

A full-width Testing strip sits below the filter bar under both tabs. Its left side summarizes the test scope and count, mode, and concurrency. Its right side shows a live progress gauge while a batch is running, then summarizes nonzero completed result counts as done, ok, and failed.

Test batches run the stages listed in [runtime.rotation].test_stages (typically icmp and real_delay) with concurrency 4, restricted to enabled, non-deleted configs. TCP and upload stages are always skipped from the TUI; the URLs, timeouts, and other stage settings come from config.toml. This mirrors rotation’s stage selection rather than the full xrat test pipeline — for a CLI bulk test with identical semantics, run xrat test --enabled-only and align [testing] stages with [runtime.rotation].test_stages. Tests use the t chord leader: t t (focused), t a (all enabled), t v (visible), t r (failed), t s (stale), and t c cancels a running batch.

While a batch is running, the gauge updates without blocking navigation. Cancelling requests cooperative cancellation; the active operation reports cancelled once the shared test executor observes the cancellation request.

Runtime, Logs, and Help

The merged runtime panel summarizes runtime, database, subscription, API, and config-count state alongside the active config. Both the runtime and logs cards stay visible under both tabs.

The Logs card is tabbed. Focus it with 2, Tab, or Shift+Tab, then switch tabs:

KeyAction
[ / ]Cycle to the previous / next log tab
C lClear the active log view (view-only)
C sClear the traffic view / counters (view-only)
C pClear all persisted events from the database
TabShows
EventsStructured app/runtime events (same data as xrat logs)
EngineParsed xray / sing-box engine logs for the latest session
TrafficLive throughput + probe dashboard (charts, see below)
APIHTTP API requests recorded by the server (source = api)

The Engine and Traffic tab titles show the active engine and version.

The engine tab parses recognized xray and sing-box log lines into time, level, source/component, and message columns; the active engine and version are shown once in the card title instead of repeating per row. Generated sing-box configs enable log.timestamp so its lines carry a timestamp. xray access logs get an inferred Info level and their [inbound >> outbound] routing path in the source column. stderr is styled as a warning, and unrecognized lines are kept as raw messages with severity inferred from keywords. Access logs from xrat’s own stats polling ([api -> api]) are hidden as instrumentation noise, the same as xrat logs.

The API tab splits each recorded request into TIME, LEVEL, METHOD, PATH, CODE, and MESSAGE columns. The server records requests as the synthetic line <METHOD> <path> -> <code>, which is not a real handler message, so MESSAGE shows -; any recorded line that is not a request line is shown verbatim.

Severity colors are shared across the Events, API, and Engine tabs: critical/fatal/panic/error are red, warn/warning are yellow, and info/debug/trace are neutral/accent.

The Traffic tab samples the active engine once per second — the xray gRPC StatsService or the sing-box Clash API /connections endpoint — and resets its history on each new runtime session. It is enabled by [runtime.stats] (see config reference). The top row shows a throughput summary (total ↓/↑ and current rate) next to a probe table (Name | Value | mean ± std | n | last update) built from the active config’s recent connection_tests. The lower row pairs a bidirectional traffic chart (upload bars up, download bars down, with independent scales and failure markers) with a probe-latency graph plotting each activated latency test as its own colored series.

Clears come in two kinds. C l and C s are view-only: they hide the current log/traffic buffer in the TUI without deleting anything, and a periodic reload does not resurrect the cleared rows. C p is a database clear — it removes the persisted events rows, the same data cleared by xrat logs clear. Engine log files are not touched by any of them.

Press ? from either tab to open the help modal. Press Esc to close it.

QR and Clipboard Behavior

QR modals are available for focused config URIs, subscription URLs, and the HTTP API subscription URL. Press Esc or q to close a QR modal.

Clipboard actions use the host clipboard. They can fail in SSH, tmux, Wayland, X11, or headless sessions depending on environment support. When clipboard access fails, the TUI reports the error in the status area.

QR generation can fail if a URI is too long for the QR renderer. When that happens, the QR modal reports the failure instead of crashing.

WorkflowCLI equivalent
Manage config stateconfig management
Start or stop runtimeruntime
Run teststest
Inspect subscriptionslist subscriptions
Import subscriptionsimport
Refresh subscriptionsupdate
Serve API URLserve

Troubleshooting

If the TUI cannot start, check that the terminal supports alternate-screen raw mode and run with a higher log level:

xrat -vv tui

If runtime actions fail, verify the equivalent CLI flow first:

xrat daemon start
xrat connect <id>
xrat status

If subscription/API QR or copy actions report that a URL is unavailable, ensure the subscription has a stored value and that the HTTP API subscription URL can be built from the current app configuration.