Configure datui
datui reads one TOML config file; every key is in Settings.
datui config init
That writes the file with every key commented out at its default. Uncomment what you want, then restart datui.
| OS | Config file |
|---|---|
| Linux | ~/.config/datui/config.toml |
| macOS | ~/Library/Application Support/datui/config.toml |
| Windows | %APPDATA%\datui\config.toml |
| Command | Does |
|---|---|
datui config init | Write the file; --force replaces one that is there |
datui config path | Print the files read, imports first |
datui config keys | List every key: its type, default, the value in effect and what set it |
DATUI_CONFIG_DIR moves the directory; Environment variables
lists the rest.
Set common defaults
[display]
row_numbers = true
number_format = "thousands"
[theme]
mode = "light"
This shows row numbers, groups digits, and starts from the light palette.
Datasets and directories to list on the home screen are not here: they are in
your catalog, catalog.toml, which
datui config init writes empty beside the config file.
Find a setting
| Change | Reference |
|---|---|
| Type inference, decompression, following | Read |
| CSV comments, nulls and inference rows | CSV |
| Number formatting, columns and row numbers | Display |
| Row buffers and the streaming engine | Performance |
| Analysis sample size or chart rows | Analysis |
| The home screen and its search | Home · Home search |
| Named datasets and directories, local or remote, and the example datasets | Catalogs |
| Cloud accounts and connections | Cloud connections |
| Clipboard over SSH | Clipboard |
| Colors and symbols | Colors · Glyph overrides |
| A theme from your desktop | Theme from your system |
Override a setting
-c KEY=VALUE sets any key for one run; it is repeatable, and the last of one
key wins. A flag of the key’s own, such as --sample-rows, beats -c:
printf 'a,b\n1,2\n' > data.csv
datui -c display.row_numbers=true data.csv
datui -c csv.comment='#' -c performance.streaming=false data.csv
datui --sample-rows 0 data.csv
The last one makes every analysis tool, Data Quality included, read every row. An unknown key is refused with the nearest ones.
| Precedence, lowest first | |
|---|---|
| Built-in defaults | |
| Imported files | In the order listed |
| Your config file | A key you write wins over an import, even when it equals the default |
| Environment | DATUI_LOG over log.level; cloud variables over [cloud] |
-c KEY=VALUE | |
| A flag of the key’s own |
Import other config files
import names TOML files to merge in before this file’s own settings: a theme
generated by something else, a team’s shared file. Replace <FILE> with the
file’s path:
import = ["<FILE>"]
[display]
row_numbers = true
- Imports apply in the order listed, each over the last; this file’s own values apply after all of them.
- A file changes only the keys it writes. One written as the built-in default
still overrides an import:
notes_accent = trueundoes an importedfalse. Tables such as[theme.colors]or[display.number_format]merge key by key. - These lists add up across files:
catalogs,[home] hide,[cloud] hide,[cloud] env_filesand[formats] path. A[[cloud.connections]]entry replaces the earlier one of its name; two of one name in one file are an error. - TOML cannot unset a key, so a key with no default, such as
sidebar_width, stays set once an import sets it; set it to the value you want. - An imported file may itself
import. Chains stop at 8 files; a cycle is an error. - Paths may be absolute, relative to the importing file, or use
~and$VAR. - A missing import is skipped with a warning on stderr. An import that cannot be read or parsed stops datui with its path, as your own file does. No config file means the defaults.
Glyphs or ASCII
display.unicode = "auto" (the default) draws Unicode glyphs when the terminal
is doing UTF-8, and the ASCII set otherwise. "always" or "never" skips
detection.
| Environment | Set |
|---|---|
LC_ALL, LC_CTYPE or LANG set (first non-empty wins) | Unicode if it names UTF-8 (en_US.UTF-8), else ASCII (C) |
| None set, Windows | Unicode, whatever the code page |
| None set, anything else | ASCII |
A font without a glyph draws a box in its place. If the classic Windows
console shows boxes, pick a font such as Cascadia Mono, or set
unicode = "never".
Number formatting
display.number_format groups digits, so 248956422 reads 248,956,422.
, toggles it for the session.
| Preset | 1234567.89 becomes |
|---|---|
none (default) | 1234567.89 |
thousands | 1,234,567.89 |
european | 1.234.567,89 |
si | 1 234 567.89 (narrow no-break space) |
swiss | 1'234'567.89 |
indian | 12,34,567.89 |
underscore | 1_234_567.89 |
system | What LC_ALL, LC_NUMERIC or LANG says, else thousands |
For finer control, a table:
[display.number_format]
grouping = "thousands"
group_separator = ","
decimal_separator = "."
floats = true
float_precision = 2
exclude_columns = ["year", "*_id", "zip"]
floats groups float columns too; float_precision rounds them (leave it out
to keep the file’s own decimals); exclude_columns takes globs of columns never
grouped, for numbers that are labels. Every value of a grouped column is
grouped. Formatting is display only: exports, queries, filters and views use
the raw values.
Themes
[theme]
dark = "night-market"
light = "day-market"
A theme is a named set of colors, one per slot.
theme.dark is used when the terminal is dark and theme.light when it is
light. Two are built in, and those are the defaults:
| Theme | For |
|---|---|
night-market | Dark terminals: Tokyo Night with one cyan accent |
day-market | Light terminals: Tokyo Night’s day variant |
Every *.toml in themes/ in the config directory (datui config path
shows where that is) is a theme too, named by its file. This one is
themes/my-dusk.toml:
extends = "night-market"
description = "Night Market with a warm accent"
accent = "#e0af68"
chip_key = "#e0af68"
| Key | Means |
|---|---|
extends | The theme the unset slots come from. Without it, they come from night-market when the theme is used as theme.dark and from day-market when it is used as theme.light |
description | Shown by datui theme list |
| Any slot | The same slots and color forms as [theme.colors] |
The repository’s
contrib/themes/
has more, each crediting its palette: gruvbox-dark and high-contrast. Copy
one into themes/ to use it.

One table in each theme: night-market and day-market (top), gruvbox-dark
and high-contrast (bottom), sorted with ] on dep_delay.
datui -c theme.mode=light uses day-market for one run.
datui theme list lists the themes; datui theme show NAME prints one with
every slot, to save into themes/ and edit. A theme file with a mistake is
left out with a warning. A theme name that cannot be used falls back to its
mode’s built-in, with a warning when that mode is in use: always under auto,
otherwise only for the pinned mode.
The colors are worked out in this order, each step over the one before:
| Step | Gives |
|---|---|
theme.mode, or the terminal under auto | Dark or light |
theme.dark or theme.light | The theme for that mode |
extends, theme by theme | Slots the theme leaves unset |
[theme.colors] | Your own slots, over the theme in either mode |
Light and dark
[theme]
mode = "light"
theme.mode picks the theme: auto (the default) follows the terminal,
dark always uses theme.dark, light always uses theme.light. The
header fill, row stripes, borders and dim text sit a few shades off the
terminal’s background, so a dark theme’s shades are unreadable on a light
background.
auto asks the terminal for its background color (OSC 11) at startup and
does not wait for the answer. The first frame uses, in this order:
| Source | When |
|---|---|
| The terminal’s answer | It is in before the first frame; light when black text reads better on it than white |
| The last answer from this terminal | One was given before; remembered in the cache by TERM_PROGRAM, else TERM |
COLORFGBG | The terminal sets it |
dark | None of these |
An answer that arrives after the first frame switches the theme if it differs. On a light terminal seen for the first time, that is one dark frame before the light theme.
Under auto the theme follows the terminal: when its window comes back into
focus, datui asks again and switches between theme.dark and theme.light if
the scheme changed. That takes a
terminal that reports focus; in tmux, turn on set -g focus-events on.
The question is not asked on Windows, on the Linux console (TERM=linux), or
when standard output is not a terminal. A terminal that does not answer
costs nothing at startup and is left at COLORFGBG or dark: set mode
there.
Colors
[theme.colors] changes a few slots over the theme in use, in both modes;
for more than a few, write a theme file. Every color is a slot
(the slots), written one of three ways:
| Form | Example | Shown |
|---|---|---|
| Hex | "#ff9e64" | Exactly on a true-color terminal; the nearest of 256 on xterm-256color; basic ANSI below that |
| Name | "bright_red" | black red green yellow blue magenta cyan white, bright_*, gray dark_gray light_gray, default (the terminal’s own) |
| Indexed | "indexed(236)" | An entry of the xterm 256-color palette |
NO_COLOR set to anything turns color off. A Dracula theme, saved as
themes/dracula.toml and picked with theme.dark = "dracula":
description = "Dracula"
accent = "#bd93f9"
accent_bright = "#ff79c6"
gradient_start = "#8be9fd"
gradient_end = "#ff79c6"
chip_key = "#bd93f9"
chip_label = "#ff79c6"
background = "#282a36"
surface = "#44475a"
controls_bg = "#44475a"
text_primary = "#f8f8f2"
text_secondary = "#6272a4"
text_inverse = "#282a36"
table_header = "#f8f8f2"
table_header_bg = "#44475a"
table_selected = "#44475a"
table_alternate_row = "default"
table_column_separator = "#bd93f9"
type_str = "#50fa7b"
type_int = "#8be9fd"
type_float = "#bd93f9"
type_bool = "#f1fa8c"
type_temporal = "#ff79c6"
success = "#50fa7b"
warning = "#ffb86c"
error = "#ff5555"
dimmed = "#6272a4"
chart_1 = "#8be9fd"
chart_2 = "#ff79c6"
chart_3 = "#50fa7b"
chart_4 = "#f1fa8c"
chart_5 = "#bd93f9"
chart_6 = "#ff5555"
chart_7 = "#ffb86c"
Glyph overrides
[glyphs] replaces single symbols when your font has better ones than the
set every common terminal font carries. Keys are the slot names in
glyphs.rs;
spinner, score_marks, mini_bars and bar_eighths take lists:
[glyphs]
in_object_store = "☁"
spinner = ["◐", "◓", "◑", "◒"]
- An override keeps the display width of the glyph it replaces; a wrong width is refused at startup, naming the slot. Nerd Font icons work where the font has them.
- Overrides apply only to the Unicode set: under
display.unicode = "never", or when detection finds no UTF-8, the ASCII set draws. spinnertakes any number of frames;score_marksexactly 5,mini_barsandbar_eighthsexactly 8. The wordmark cannot be overridden.
Mouse and text selection
datui takes the mouse by default: the wheel scrolls, a click selects, and a drag moves or sizes a column (The mouse). To select text with the terminal meanwhile, hold its bypass modifier as you drag:
| Terminal | Select text |
|---|---|
| Most (GNOME Terminal, Konsole, kitty, Alacritty, WezTerm, Windows Terminal, xterm) | Shift+drag |
| iTerm2 | Option+drag |
tmux with set -g mouse on | Shift+drag, or tmux’s own copy mode |
To leave the mouse to the terminal, --mouse=false for one run, or:
[display]
mouse = false
Theme from your system
To follow a theme something else generates (a desktop theme manager, chezmoi,
home-manager, a dotfiles repository), import the
file it writes. Your own settings still win. Replace <FILE> with the
generated file:
import = ["<FILE>"]
The imported file may set any section, not only [theme.colors].
Omarchy
Omarchy renders per-app theme files from templates when you switch themes. Datui ships one. These steps need an Omarchy system.
-
Install the template from the repository:
mkdir -p ~/.config/omarchy/themed curl -fsSL https://raw.githubusercontent.com/derekwisong/datui/main/contrib/omarchy/datui.toml.tpl \ -o ~/.config/omarchy/themed/datui.toml.tpl -
Import the file Omarchy generates, in
~/.config/datui/config.toml:import = ["~/.local/state/omarchy/current/theme/datui.toml"] -
Switch themes as usual, here to Tokyo Night:
omarchy theme set tokyo-night
The template sets theme.mode from the theme’s polarity and maps its accent
onto datui’s accent, gradient and selection tint. A running datui keeps the
theme it started with; the next launch takes the new one.
A color in your own config.toml wins over the import, even when it equals
the built-in default:
import = ["~/.local/state/omarchy/current/theme/datui.toml"]
[theme.colors]
type_int = "#ff8800"
To override one theme only, import a second file that only that theme
provides. In ~/.config/datui/config.toml:
import = [
"~/.local/state/omarchy/current/theme/datui.toml",
"~/.local/state/omarchy/current/theme/datui.override.toml",
]
and in ~/.config/omarchy/themes/osaka-jade/datui.override.toml:
[theme.colors]
type_int = "#ff8800"
type_float = "#ff00ff"
Omarchy copies your theme directory into place before rendering templates, so
the override arrives untouched. Themes without the file are skipped with a
warning on stderr. Name it datui.override.toml: a file named datui.toml
replaces the generated file and drops every color it does not restate.
Troubleshooting
| Problem | What to do |
|---|---|
| The file is ignored | Check the path for your OS above, or datui config path. A file that does not parse stops datui with its path, line and reason |
| A key seems to do nothing | Warnings go to stderr, which the UI hides: run datui data.csv 2> /tmp/datui.log and read it after quitting. An unknown key is named there with the nearest ones; datui config keys lists them all |
| An import does not apply | Check the file exists at the resolved path, and that nothing later in the chain, a -c or a flag, overrides it |
Invalid color value for 'accent': Unknown color name | A typo in a name. Names ignore case; hex needs six digits; indexed is indexed(0) to indexed(255) |
| Colors look wrong | The terminal may not take true color, so hex is approximated; try names or indexed(...). Everything monochrome: NO_COLOR is set |
Header or chip text cut off or garbled in VS Code’s terminal or on xterm-256color | Some terminals mishandle a background color on those rows; set them to the terminal’s own, below |
| The config file does not parse | The error names the file, line and reason, then the way out: fix that line, or move the file aside to start from the defaults, after which datui config init writes a fresh one. A broken import is named by its own path; moved aside, it is skipped |
| Start over | datui config init --force rewrites the file with the defaults; with no file, datui runs on them |
| Odd home-screen state: recents, folded sections, a hidden source | datui cache clear resets the cache: recents, folds, remembered places, hidden sources and Example datasets, measurements and histories; never your data or config, and not the log. A cache line that cannot be read is skipped and logged in datui.log (The log) |
[theme.colors]
controls_bg = "default"
table_header_bg = "default"
The log
datui.log in the cache directory (~/.cache/datui on Linux,
~/Library/Caches/datui on macOS, %LOCALAPPDATA%\datui on Windows) holds
Polars warnings, the errors datui showed, internal errors with their
backtraces, cache and history failures, and anything else written to stderr
while the UI was up, with credentials masked. It is capped at 1 MB, the
previous file kept as datui.log.1; datui cache clear leaves both. On
Windows it receives Polars warnings and datui’s own messages, not other stderr
output.
| Set | How |
|---|---|
| Another file | --log-file PATH, or log.file |
| Level | --log-level, DATUI_LOG or log.level: error, warn (default), info, debug, trace or off |