A terminal UI for Azure Cosmos DB (NoSQL API). It browses accounts, containers and documents in three panes, like the Data Explorer in the Azure portal.
- Rust 1.88 or later, when installing with
cargo - The Azure CLI, logged in with
az login
curl -fsSL https://christianhelle.com/termos/install | bashThis installs the latest release to ~/.local/bin. To install somewhere else, or to pin a release:
curl -fsSL https://christianhelle.com/termos/install | INSTALL_DIR="$HOME/bin" bash
curl -fsSL https://christianhelle.com/termos/install | VERSION="<tag>" bashirm https://christianhelle.com/termos/install.ps1 | iexThis installs the latest release to %LOCALAPPDATA%\Programs\termos, or to ~\.local\bin or ~\bin if one of those already exists, and adds it to your user PATH. To install somewhere else, or to pin a release:
$install = irm https://christianhelle.com/termos/install.ps1
& ([scriptblock]::Create($install)) -InstallDir "$env:USERPROFILE\bin"
& ([scriptblock]::Create($install)) -Version "<tag>"cargo install termosTo build from a clone of this repository, run cargo install --path ..
Download a build from Releases. Archives are available for Linux, macOS and Windows, on x64 and ARM64.
termos [--subscription <ID>] [--auth auto|entra|key] [--key <KEY>]
termos --emulator [<ENDPOINT>] [--key <KEY>]-
Accounts (left): a tree of accounts, databases and containers. Open an account with Enter or → to load its containers. Selecting a container lists its first 100 documents, and Enter moves to them. termos starts where the last run left off, showing the same accounts, containers, documents, search and query at once while they refresh in the background. Settings and the query editor's results are not restored. The session, with the documents it showed, is saved on quit in
%LOCALAPPDATA%\termoson Windows,~/Library/Caches/termoson macOS and~/.cache/termoson Linux. Delete thesession*.jsonfiles there to start afresh. -
Results (middle): the id and partition key of each document found, 100 at a time. When the title says
more ↓, press ↓ on the last result to load the next 100. Pressdhere or in the Document pane to delete the selected document, thenyor Enter in the dialog to confirm. Any other key cancels. To delete several at once, press Space on each result to mark it (or Ctrl-A to mark them all, Esc to clear the marks), thenddeletes every marked document. -
Document (right): the selected document as JSON. Drag the mouse over it to pick text, then press
yto copy it to the clipboard. With nothing picked,ycopies the whole document. Esc drops the picked text. -
Search (top): press
/and type a query, then Enter. ASELECTstatement runs as typed. Clauses likeWHERE c.status = 'open'orORDER BY c._ts DESCfollowSELECT * FROM c. A bare condition likec.total > 10becomes aWHEREclause. -
Query editor: press
nto write SQL for the selected container, like the Data Explorer's New SQL Query. The editor replaces the search bar, results and document. It starts with the latest query, colours the SQL and numbers its lines. Enter starts a new line, and F5, Ctrl-R or Shift-Enter run the query as written. Shift-Enter only works in terminals that report it, such as kitty, WezTerm, foot, Ghostty and Warp. Ctrl-Enter and Alt-Enter run it too. Below the editor, the output shows the results as one JSON array, 100 at a time, and ↓ at the end loads more.sswitches to the query stats: the request charge, round trips and the metrics Cosmos DB reports for the query.ycopies the results,wsaves them to a JSON file and Ctrl-S saves the query. The editor keeps its results apart from the results and document, so a query that picks a few fields leaves them as they were. Selecting another container in the tree runs the next query there, and its documents are listed when you go back to browsing. Esc leaves the editor for the output, and Esc ornthere goes back to browsing, keeping the query for next time. A query that fails shows why in a dialog. The Azure Cosmos DB SDK for Rust cannot run aggregates such asCOUNTorGROUP BYacross partitions yet, so those queries fail in termos while they work in the Azure portal. -
Settings: press
sto edit the selected container's settings, like the Data Explorer's Settings. They replace the other panes, with three tabs that Tab and Shift-Tab move between:- Settings: time to live (Off, On with no default, or On after a number of seconds), whether spatial data is geography or geometry, and the partition key, which cannot change. ↑ and ↓ move between the settings, ← → or Space pick another choice, and digits type the seconds.
- Indexing Policy and Computed Properties: edited as JSON, with numbered, coloured lines.
A tab with unsaved changes shows a
*. Ctrl-S saves them all. If something cannot be saved, such as JSON that does not parse, a dialog says why and where, on the tab it is on. Esc orsgoes back, and asks first whether to discard any changes. Selecting another container in the tree shows its settings unless there are unsaved changes.
Tab and Shift-Tab move between the accounts, results and document (the search bar is reached with /), Ctrl-B hides or shows the accounts to give the other panes more room, z zooms the focused pane to fill the screen and shows every pane again, r runs the query again, ? shows every key and q quits.
The mouse works too. Click a pane to focus it, or a node or document to select it. Click a selected node again to open or close it, the same as Enter. The wheel scrolls the pane under the mouse. A pane with more than fits shows a scrollbar on its right border. Because termos captures the mouse, drag in the document to pick text there, or hold Shift to select text anywhere in most terminals.
Accounts, databases and containers are found through Azure Resource Manager, using your az login identity. Accounts come from every subscription you can access; add --subscription <ID> to list just one.
Documents are read through the Cosmos DB data plane. --auth picks how to authenticate:
--auth |
Behaviour |
|---|---|
auto (default) |
Try Entra ID first. If you have no Cosmos DB data plane role, fall back to the account key fetched from Resource Manager. |
entra |
Only use Entra ID. |
key |
Only use the account key fetched from Resource Manager. |
Pass --key <KEY> to supply an account key yourself.
--emulator browses the local Cosmos DB emulator instead of Azure, with no az login. It connects to https://localhost:8081/ with the emulator's well-known key and accepts its self-signed certificate. Give another endpoint as --emulator <ENDPOINT>, and pass --key <KEY> if the emulator was started with its own key.
termos --emulator
termos --emulator http://cosmos:8081/The emulator in Docker tells clients to use its address inside the container, which can't be reached from the host. Start it with that address set to 127.0.0.1, and publish port 8081 as itself:
docker run -d -p 8081:8081 -p 10250-10255:10250-10255 \
-e AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE=127.0.0.1 \
mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latestcargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --check- Azure access: the
Connectorlists accounts and opens container connections. The adapters inarm.rs,emulator.rsandcosmos.rsare kept thin, andtesting.rshas in-memory fakes of the control and data planes for tests. - The terminal UI: keys and finished background work go through
state::update, which returns the work to start next, so it is tested without a terminal.




