Skip to content

Zero external CLI dependencies

A locked architectural rule: no Quay feature requires an external CLI binary on $PATH to function.

Database clients that shell out to mysqldump / pg_dump / mongodump look elegant in code reviews — “we just call the official tool”. In practice they create a fragile UX:

  • “Quay says I need to install pg_dump” — first-launch papercut
  • Wrong version mismatch between client and server — silent broken dumps
  • macOS Homebrew ↔ Apple Silicon Rosetta path confusion — random ENOENTs
  • Corporate machines where Homebrew + apt are blocked
  • New engines (BigQuery, Snowflake, vector DBs) that don’t have a canonical CLI to shell to

So Quay’s rule: every feature must be fully functional with only the Quay binary installed. Everything ships native, written in Rust against the engine’s wire protocol.

FeatureNative implementationWhat mysqldump-style would do
SQL dumppg_export.rs / mysql_export.rs walk system catalogs + write SQL grammar from scratchShell to pg_dump / mysqldump
Schema diffNative catalog walk + per-column comparisonShell to pg_dump --schema-only × 2 + diff output
Streaming importpg_import.rs / etc. parse statements, stream 1 MB chunksShell to psql / mysql
Mongo dumpmongo_dump_database.rs walks collections + JSONLs eachShell to mongodump
Redis dumpredis_dump_keys.rs does KEYS * + GET per keyShell to redis-cli --rdb
ER diagramNative graph layout + SVG/PNG rendern/a

A few engines have CLI tools that genuinely outperform native implementations for specific workloads — mongodump for hundreds of GB, pg_dump --format=directory for parallel dumps. Quay supports those as optional fast paths:

  1. The native path is the default
  2. If the CLI is detected (which path), an “Use mongodump for large dumps” toggle appears in the export dialog
  3. Selecting it shells out, with a clear progress indicator + the exact command surfaced in the log

Whenever Quay shells to a CLI binary, the missing-tool state must show:

  • The exact command Quay tried to run
  • A platform-aware install hint with copy + download buttons (brew install postgresql@16 on macOS, the corresponding apt command on Linux, the Postgres installer link on Windows)
  • A clear “Continue with native fallback” button that doesn’t require the CLI

The user is never stuck because Quay can’t find a tool. Worst case, they pick the native path with one click.

In code review. There’s no automated rule (yet) — but every PR that introduces a Command::new("…") shell-out gets reviewed against the question “does this feature work without that command?”. If the answer is no, the PR doesn’t merge until the native path exists.

Why this is the second rule, not the first

Section titled “Why this is the second rule, not the first”

The North Star is confidence over breadth — the first rule. Zero external deps follows from that: a feature that sometimes works (when the CLI is installed in the right version on the right path) doesn’t build confidence; it builds uncertainty. A user can’t trust “backup works” if “works” depends on which pg_dump.