docs / ambry

Documentation

Ambry is an open-source desktop database client for PostgreSQL, MySQL, and SQLite. It puts an editable data grid, a fast SQL editor, and schema tools behind one quick, keyboard-friendly app.

This guide covers everything from your first connection to the file formats Ambry writes. If you just want to install it, jump to Install.

PLATFORM The current build targets macOS on Apple Silicon (arm64). Linux and Windows are not distributed yet.

Install

Homebrew (recommended)

Homebrew strips the macOS quarantine attribute on install, so the app launches without a “damaged” prompt.

# first time — tap the cask repository
brew tap wess/packages
brew install --cask ambry

# or in one line
brew install --cask wess/packages/ambry

Direct download

Grab Ambry.dmg from the latest release, mount it, and drag Ambry into Applications. If macOS reports the app is “damaged,” that build wasn’t notarized — clear the quarantine flag once:

xattr -dr com.apple.quarantine /Applications/Ambry.app

Notarized builds skip this step entirely.

First connection

Ambry opens to a connection list. Click New Connection (or press ⌘N) to open the connection form.

  1. Give the connection a name and pick a type — PostgreSQL, MySQL / MariaDB, or SQLite.
  2. For Postgres and MySQL, fill in host, port, database, username, and password. For SQLite, give a file path instead.
  3. Click Test to verify the connection — Ambry connects, reads the server version, and reports back.
  4. Click Create to save it. Back on the list, click Connect to open the workspace.

Connections are saved to ~/.ambry/connections.json — plain JSON you can read, back up, or edit by hand.

Connections

Every connection carries more than a host and password. The form’s General tab covers the essentials; the connection format also supports transport security and tunneling.

FieldApplies toWhat it does
nameallDisplay name in the connection list.
typeallpostgres, mysql, or sqlite.
host / portpg, mysqlServer address. Defaults: 5432 (pg), 3306 (mysql).
databasepg, mysqlDatabase to open on connect.
filepathsqlitePath to the .db / .sqlite file.
colorallAccent color for the connection card.
group / tagsallOrganize the connection list into labeled groups.
safeModealloff, confirm, or readonly — guards against accidental writes.
startupCommandsallSQL run automatically on connect, one statement per line.
sslpg, mysqlTLS mode plus optional CA / client cert / key paths.
sshpg, mysqlSSH tunnel — host, port, user, and password or key auth.

When a connection defines an SSH tunnel, Ambry opens it before connecting and routes traffic through 127.0.0.1 on a local port, closing it again on disconnect. A background health check probes each live connection every 30 seconds.

NOTE The General fields have full form controls today. SSL and SSH settings round-trip when you edit an existing connection; dedicated editors for them are on the roadmap. In the meantime you can set the ssl / ssh objects in connections.json directly — see Storage & files.

The data grid

Select a table in the sidebar and its rows load into the grid on the Data tab. The grid is the heart of Ambry — it is not a read-only preview.

Reading

  • Sort by clicking a column header; click again to flip direction. An arrow marks the sorted column.
  • Resize a column by dragging its right edge. Widths are per-column.
  • Scroll horizontally when a table is wider than the window — every column stays at its own width.
  • Page through large tables with the pager at the bottom; page size follows your settings.
  • NULL values render distinctly, and foreign-key columns are marked so you can tell references from plain values.

Selecting

ActionResult
Click a rowSelect just that row.
⌘ + clickToggle a row in or out of the selection.
⇧ + clickSelect a contiguous range.

Editing & commits

Ambry batches every change and shows you the SQL before anything touches the database. Nothing is written until you commit.

Making changes

  • Edit a cell: double-click it, type, and press Enter to stage the change (or Esc to cancel). The cell highlights amber to show it is pending.
  • Insert a row: click Insert, fill in the fields you want, and submit. Empty fields fall through to the column’s database default.
  • Delete rows: select one or more rows and click Delete — they are staged for deletion and struck through.
  • Generate data: click Generate to insert mock rows shaped by each column’s type — handy for filling a fresh table.

Reviewing & committing

A bar appears with a count of pending changes. Click Review to see every change as the exact UPDATE, INSERT, or DELETE statement it will run, grouped by kind. From there:

  • Commit applies every change in order, then refreshes the grid.
  • Discard throws the whole batch away — nothing was written.
WHY IT WORKS THIS WAY Staging changes and previewing them as SQL means you never issue a write you didn’t read first. The amber highlight in the grid is the same signal used across this site: amber always means “pending / live.”

The SQL editor

The Query tab is a syntax-highlighted SQL editor bound to the active connection.

  • Run the buffer with ⌘↵ or the Run button.
  • Multiple statements separated by semicolons run in sequence.
  • Results come back into the same grid used on the Data tab — same reading, sorting, and column behavior.
  • A statement that returns no rows reports how many rows it affected and how long it took.
  • Every executed statement is recorded in query history under ~/.ambry/history.json (newest first, capped at 500).
-- runs against the active connection
SELECT customer, sum(total) AS revenue
FROM orders
WHERE status = 'paid'
GROUP BY customer
ORDER BY revenue DESC;

Structure

The Structure tab reads a table’s shape directly from the live schema — never a cached guess:

  • Columns — name, type, nullability, default, and whether each is part of the primary key.
  • Indexes — name, the columns covered, type, and uniqueness.
  • Foreign keys — name, the local columns, and the table and columns they reference.

Switching databases

When a Postgres or MySQL connection exposes more than one database, a selector appears in the sidebar above the table list. Choosing a different database reconnects to it in place and reloads the table list — no need to define a separate connection per database. SQLite connections, which are a single file, don’t show the selector.

Keyboard shortcuts

ShortcutAction
⌘NNew connection
⌘↵Run the query buffer
Double-clickEdit the cell under the cursor
EnterCommit the cell edit (while editing)
EscCancel the cell edit
⌘ / ⇧ + clickToggle / range-select rows
⌘HHide Ambry
⌘QQuit

Engines

The grid, editor, and schema tools work the same across every engine; only the introspection underneath differs.

PostgreSQL

Full schema introspection, foreign-key discovery, TLS modes, and SSH tunnels. Result columns are read from prepared-statement metadata, so an empty table still reports its columns.

MySQL / MariaDB

Queries and introspection run over the binary protocol. Indexes and foreign keys are discovered from information_schema.

SQLite

Open a file and go — no server. Schema details come from PRAGMA table_info, index_list, and foreign_key_list.

Configuration

Settings live in ~/.ambry/settings.json. Missing keys fall back to defaults, so a partial file is fine.

KeyDefaultMeaning
theme"dark"Color scheme — light, dark, or auto.
editorFontSize13SQL editor font size, in points.
editorTabSize2Spaces per indent in the editor.
editorWordWraptrueWrap long lines in the editor.
gridPageSize100Rows fetched per page in the data grid.
gridRowHeight"compact"compact, normal, or comfortable.
gridAlternateRowstrueStripe alternating rows.
nullDisplay"NULL"How null values are printed in the grid.
dateFormat"ISO 8601"Date rendering format.

Storage & files

Everything Ambry remembers lives under ~/.ambry/ as plain JSON. There is no database of its own, no hidden state, and nothing is sent anywhere.

FileHolds
connections.jsonSaved connections (a corrupt file is backed up and treated as empty).
settings.jsonYour preferences.
history.jsonQuery history, newest first, capped at 500.
favorites.jsonSaved queries.
tabs.jsonOpen editor tabs.
macros.jsonRecorded macros.

A stored connection looks like this — including the optional SSL and SSH blocks:

{
  "id": "…",
  "name": "Production",
  "type": "postgres",
  "host": "db.internal",
  "port": 5432,
  "database": "app",
  "username": "app",
  "password": "…",
  "ssl": { "mode": "required" },
  "ssh": {
    "enabled": true,
    "host": "bastion.example.com",
    "port": 22,
    "username": "deploy",
    "authMethod": "key",
    "keyPath": "~/.ssh/id_ed25519"
  }
}

What’s next

Available today: connections, the editable data grid with commits, the SQL editor, structure, the database switcher, and mock data. Landing next:

  • In-app SSL and SSH editors in the connection form.
  • The filter panel and column-visibility controls.
  • CSV / JSON / SQL import and export with system file dialogs.
  • Data profiling, schema comparison, and the ER diagram.
  • Charts from query results, saved favorites, and the command palette.

Track progress or open an issue on GitHub.