Querybara
A cross-platform desktop database manager built with Electron, React and Node.js, in TypeScript
end to end. The target is Navicat Premium parity for MySQL, MariaDB and PostgreSQL, Studio
3T-level tooling for MongoDB, and first-class Redis and Elasticsearch support in one app.
Status
The foundation, the SQL MVP and the NoSQL modules are built: MySQL, MariaDB and PostgreSQL work
end to end in the desktop app and on the command line, MongoDB and Redis (or Valkey) connect,
browse, query and edit there too, and Elasticsearch has documents, SQL, index and cluster
administration. Data moves between engines with transfers, backups and restores.
What works today:
- Connections: a new connection starts with its engine, then a tabbed form (General,
Advanced, TLS, SSH, Proxy); profiles with host/port, socket or URI endpoints; the four TLS
modes (off by default; a URI's sslmode, rediss://, https:// or mongodb+srv:// turns it on);
passwords saved in the OS keychain, remembered for the session, or asked every time; URI and
pgpass import; Import and Export connections in the side bar's menu and the CLI: a
passphrase-encrypted file, optionally with saved passwords, Navicat
.ncx files with their
saved passwords, MongoDB Compass exports (encrypted ones with their passphrase) and Robo 3T's
robo3t.json; stepwise Test Connection.
- Command palette: ⌘P (Ctrl+P) goes to a table, view or collection by a few of its
letters; ⌘⇧P (Ctrl+Shift+P) runs any command; key bindings as VS Code's, with chords, and a
Keyboard Shortcuts editor (⌘K ⌘S) to change them. A toolbar under the title bar shows the
tools of the connection in front and follows it from tab to tab: for MySQL, MariaDB and
PostgreSQL, query, query builder, SQL file, table, new table and database, ER diagram,
import, export, transfer, backup, restore, structure and data compare, and the server tools;
for MongoDB, Redis and Elasticsearch, their own tools. Each acts on the database, schema,
table, collection or index in front and asks for the rest; Ctrl+Alt+B hides it.
- Explorer: a side bar you resize by dragging its edge and hide with ⌘B (Ctrl+B), with search
and a filter by engine, environment and state; a click on a database, schema or folder lists
its objects in the Objects tab with rows, sizes, engine, dates and comments (documents, sizes
and indexes for MongoDB); a click on a table or collection opens its data. New database…
in a connection's menu (or the palette) creates one: character set and collation on MySQL and
MariaDB, owner, encoding and template on PostgreSQL, the statement shown before it runs;
MongoDB names the database and its first collection.
- SSH tunnels and proxies: SSH with password, private key (OpenSSH, PEM, PuTTY converted on
import) or ssh-agent, jump hosts and keep-alives, one SSH session shared by a connection's
tabs; SOCKS5 and HTTP proxies; MongoDB replica sets, Redis Sentinel and Cluster reached node by
node through them; host keys checked against a known_hosts file the app and the CLI share,
with a trust prompt for new keys and a blocking warning for changed ones.
- Querying: a Monaco editor with run all / statement at cursor / selection; a splitter that
understands
DELIMITER, dollar quoting and nested comments; :name / $1 / ? parameters;
confirmation before risky writes and for production profiles; streaming results into a canvas
grid 1,000 rows at a time; server-side cancel; transaction controls; history. Visual explain
(Explain and Explain Analyze) shows the plan tree with cost, estimated against actual rows and
the slowest node. Editor buffers are autosaved and come back as tabs after a crash.
- Visual query builder (MySQL, MariaDB, PostgreSQL): tables on a canvas with joins proposed
from foreign keys, side panels for columns, criteria, grouping, sort and limit, and the SQL
kept in step both ways; SQL the builder cannot show opens read-only. Runs go through the query
tab, with its safety checks, streaming and history.
- ER diagrams (MySQL, MariaDB, PostgreSQL): a database or schema reverse-engineered into
tables, keys and crow's-foot relationships, laid out automatically and draggable; all columns,
keys only or names only; a table selected brings out its relationships, with its columns and
references beside the canvas; search, hide and show only related tables; export as SVG, PNG or
Mermaid. Edit model turns the diagram into a designer: add and rename tables, columns,
keys and relationships (drag from a column to another table), with undo and redo; Review &
apply shows the exact CREATE/ALTER script (renames stay renames, data loss is flagged) and
runs it with the usual write-safety checks, or opens it in a SQL tab. Unapplied changes are
kept and come back when the diagram reopens, even after a restart; models save as
.model.json files that open on another database or schema to review and apply there.
- Autocomplete: keywords, schemas, tables, columns with alias resolution, join conditions
from foreign keys, functions with signature help, and snippets, computed in a Web Worker from
a per-connection metadata cache that is ready at connect and refreshes after DDL.
- Table data: tables open in an editable grid with server-side sort, a visual filter builder
or raw WHERE, keyset paging as you scroll, an estimated total with exact count on demand, and
grid, form and JSON views. Type-aware cell editors with NULL, empty and DEFAULT kept distinct;
staged edits, inserts and deletes with undo, applied in one transaction after showing the SQL,
with conflict detection; foreign key lookups and links; copy as TSV, CSV, JSON, Markdown or
SQL, and paste from spreadsheets. Columns can be hidden, reordered, pinned and resized, and
saved as named views with their sort and filter.
- Table designer: create and alter tables (columns, indexes, foreign keys, unique and check
constraints, triggers, partitions, options, comment) with validation as you type; Save shows
the script with data-loss warnings and row counts before running it. Drop table checks what
depends on the table.
- Structure sync: compare two databases, review create / alter / drop operations with
destructive ones unselected, generate a dependency-ordered script, apply it, and re-compare
to zero differences. Data compare with server-side range checksums and sync scripts; tick or
untick single rows to insert, update or delete.
Comparisons can be saved and re-run. MongoDB databases compare too: collections with their
options and validators, indexes and views, scripted for mongosh; documents compared by
_id, with the fields that differ shown and synced in batched commands.
- Data transfer: copy tables, collections or keys between connections in one streaming job:
SQL to SQL across engines (an editable type mapping; create, drop and create, truncate or
append; keys, indexes and foreign keys after the data), SQL to MongoDB (child rows embedded
through a foreign key), MongoDB to SQL (flattened fields, child tables or JSON columns for
arrays) and Redis to Redis (DUMP/RESTORE with TTLs, Cluster-aware).
- Import and export: wizards for CSV, TSV, JSON, JSON Lines (gzip too), Excel (.xlsx, streamed,
with a worksheet picker and header row), XML (rows at a detected or chosen path) and Parquet
(typed columns, every common codec, nested columns as JSON) into an existing or a new table,
with format, delimiter, header and encoding detection, a live preview, auto-matched columns,
inferred types for new tables, and append, update, upsert, delete and replace modes; exports
of tables or query results to CSV, TSV, JSON, JSON Lines, Excel (typed cells, real dates, a
worksheet per table), XML, Parquet (exact decimals, dates, timestamps and UUIDs; Snappy, ZSTD
or GZIP), SQL INSERTs, SQL with DDL, HTML or Markdown, one file per table or combined,
gzip-compressed or zipped; Run SQL File with stop or continue and an error log. Saved wizard
settings.
- Job runner: imports, exports and SQL files run in their own utility process, several at
once, with progress, cancel (which rolls back), failed rows by row, line and column, a job
history and a desktop notification when a long job ends.
- Backup and restore: logical backups of PostgreSQL, MySQL and MariaDB in one consistent
snapshot, MongoDB collections with their options and indexes, and Redis keys with their TTLs,
to SQL, gzipped SQL or the Querybara archive (.qbak: one file
per object, optional AES-256-GCM encryption with a passphrase); pg_dump and mysqldump when
installed; restores of everything or selected objects into any database, listing what would
be dropped before asking; a Redis BGSAVE button.
- MongoDB, laid out as Studio 3T's: host lists, SRV, SCRAM, LDAP, X.509, AWS IAM and
OIDC sign-in (in the browser, or as an Azure, GCP or Kubernetes workload); an
explorer of databases, collections, views, time series, GridFS buckets, indexes, users and
roles, with Studio 3T's menus (copy name, rename, duplicate with indexes, clear, statistics);
IntelliShell, an embedded mongosh (5.9, on driver 7) with completion of collections,
methods and sampled fields, F5/F6/F9 to run the script, the statement at the cursor or the
selection, Query Assist result tabs that keep exact BSON types and page like a collection,
writes checked against the profile (read-only refuses, destructive operations ask), and a
hard restart for a script that does not stop; a collection tab with Studio 3T's query grid
(query, projection, sort, skip, limit; find, findOne or count), a docked visual query builder
kept in step with the generated find(), Result, Query Code and Explain sections, tree, table
(with drill-down into arrays and sub-documents) and JSON views, a document editor with
Extended JSON types and conflict detection, bulk update and delete with a matched-count
preview, and visual explain that flags collection scans; an aggregation editor with per-stage
previews, an index manager, schema analysis exported as JSON Schema or applied as a validator,
collection and view options, a change stream viewer, a GridFS browser, and users and roles;
export of collections or a query to JSON, JSON Lines (relaxed or canonical Extended JSON), CSV,
SQL INSERT statements (with a CREATE TABLE) or BSON, and import of such files (mongoexport's and mongodump's included) with insert, upsert
by _id or replace modes; values edited in place in the table and tree views, typed; the
collection tab's query history and saved queries; copy and paste of documents and of whole
collections across databases and connections; Reschema (move, nest, convert, drop and compute
fields) and Data Masking (mask characters, replace, null, randomise numbers and dates) into
another collection, run on the server; a Data Generator that fills a collection with test
documents from a rule per field, read from its own documents; a collection history of the
documents inserted, edited and deleted in the app, each change undoable. A SQL tab translates a SELECT to
find() or aggregate() as it is typed, runs it, and opens it in the collection tab, IntelliShell
or the aggregation editor; any query exports as a Node.js, Python, Java, C#, Go, PHP or Ruby
program for the official driver, or as a mongosh script. The toolbar's MongoDB tools and
Studio 3T's keys reach it all: Ctrl+L IntelliShell, Ctrl+Shift+L SQL, F4 aggregation, Ctrl+Alt+1/2/3 the
tree, table and JSON views, Ctrl+D insert, Ctrl+U update, F8 delete, Ctrl+G Query Code.
- Redis and Valkey: standalone, Sentinel and Cluster with ACL users (Cluster nodes behind NAT,
Docker or Kubernetes NodePorts reached through the seed that answers as each); a SCAN-based key
browser with a namespace tree, type filters and lazy memory sizes (cluster-wide in Cluster mode);
editors for strings, hashes, lists, sets, sorted sets, streams (groups and pending entries),
RedisJSON, HyperLogLog, bitmaps and geo; TTL, rename and copy; bulk delete with a dry run; a CLI
with autocomplete and inline docs; Pub/Sub, an INFO dashboard, slow log, clients, latency,
MONITOR, big keys, ACL users, a configuration editor (per node in Cluster mode) and the
Sentinel/Cluster topology. Dump analysis reads an RDB file offline (Redis 2 to 8.6, Valkey 7
to 9, module types included): keys by type, encoding, expiry, database and pattern, and the
largest keys, whatever the file's size. Search indexes (RediSearch, the Redis Query Engine;
valkey-search): list, query with sort, paging, scores and FT.EXPLAIN, read the schema and the
FT.CREATE that rebuilds it, create an index with fields suggested from sample keys, drop one.
- Elasticsearch: node URLs or an Elastic Cloud ID; basic auth, API key or
bearer token; TLS modes; one node through an SSH tunnel or proxy; an explorer with index
health, data streams and aliases; a Kibana-style console with autocomplete from the open API
specification; a document grid paged past 10,000 hits with editing, conflict detection and
bulk actions; a query builder from the mapping (bool sections, nested groups, each field's top
values, date ranges with their format and time zone, sort and aggregations, with typed Query
DSL read back) whose aggregations show beside the documents;
SQL with Translate to DSL, and ES|QL, with aggregations as a tree or a table;
index operations, create index, a mapping editor that plans a reindex when a change cannot
apply in place, and reindex with live progress; cluster health, nodes, shard allocation with
its explanation, disk watermarks and tasks; aliases with atomic swaps, index and component
templates, ILM policies, ingest pipelines with simulate, and snapshots with restore.
Writes follow the same confirmation rules as SQL.
- Server tools (MySQL, MariaDB, PostgreSQL, MongoDB): a monitor polled at a chosen interval
with the history kept for the session (connections, QPS or TPS, cache and buffer pool hit
ratios, locks, replication and replica lag, the oplog window); sessions with cancel and
terminate (KILL QUERY / KILL CONNECTION, killOp); top queries from pg_stat_statements,
performance_schema digests or the profiler, with the reason and fix when they are off; users,
roles, membership and a grants matrix, plus default privileges and row-level security policies
on PostgreSQL; VACUUM, ANALYZE, REINDEX, CLUSTER, OPTIMIZE, CHECK, REPAIR, compact and
validate; settings with SET, ALTER DATABASE, ALTER SYSTEM, SET GLOBAL / PERSIST or
setParameter. Every change shows its exact statement first.
- Schedules: backups, SQL files, exports and saved comparisons run on a schedule while
Querybara is open (every N minutes or hours, times on chosen weekdays, or days of the month),
set up with Schedule… where each is run once. Each run writes a new file named from a template
and can keep only the newest N; comparisons keep a report when they find differences. Missed
runs are caught up once or skipped; notifications go out when a run fails or finds
differences; closing Querybara with schedules on asks first.
- querybara-cli: the same engine headless — test, query, compare, data-compare, ddl, import,
export, run-file, transfer and profile management; test and query for MongoDB, Redis and
Elasticsearch too, and compare and data-compare for MongoDB; backup and restore for every
engine.
Moving from version 0.1.0
Version 0.1.0 shipped under the previous name. On its first launch, Querybara copies that
version's data into its own folder: saved connections and folders, history, saved queries,
snippets, settings, schedules, ER model drafts, known SSH hosts and converted SSH keys. It does
this once, only when Querybara has no data yet, and leaves the old folder as it was.
Saved passwords come along sealed. On Windows they keep working. On macOS and Linux the old
app's keychain entry holds their key, so Querybara asks for each one the first time you connect
and saves it again. Backup archives, saved ER models and profile exports made by 0.1.0 do not
open in Querybara.
Repository layout
pnpm workspaces with Turborepo (ADR 0001).
| Path | Package | What it is |
|---|
apps/desktop | @querybara/desktop | Electron app: main, sandboxed preload, React renderer, connection hosts, job runner |
apps/cli | @querybara/cli | querybara command-line tool |
packages/core | @querybara/core | Domain types, capability flags, schema snapshot, driver adapter contract |
packages/ipc | @querybara/ipc | Typed RPC over MessagePort with zod-validated contracts |
packages/storage | @querybara/storage | Local SQLite store, migrations, sealed secrets, URI/pgpass import |
packages/sql-tools | @querybara/sql-tools | Lexer, statement splitter, parameters, safety checks, formatter, diagnostics, query builder model |
packages/sync | @querybara/sync | Structure diff and script generation, data compare (SQL engines and MongoDB) |
packages/table-data | @querybara/table-data | Table data paging, filters, staged changes and apply, cell parsing, copy/paste |
packages/drivers/sql-base | @querybara/driver-sql-base | Shared endpoint, TLS, error mapping and Test Connection logic |
packages/drivers/postgres | @querybara/driver-postgres | PostgreSQL adapter (pg, pg-cursor) |
packages/drivers/mysql | @querybara/driver-mysql | MySQL and MariaDB adapter (mysql2) |
packages/drivers/mongodb | @querybara/driver-mongodb | MongoDB adapter (mongodb): documents, indexes, GridFS, change streams, IntelliShell's mongosh |
packages/mongo-tools | @querybara/mongo-tools | mongosh-style query parsing, Extended JSON, find() text, schema analysis |
packages/drivers/redis | @querybara/driver-redis |
Packages under packages/ never import Electron, so the CLI and the tests use them directly.
Getting started
Requirements: Node.js 22.13 or later and pnpm 10 (corepack enable picks up the pinned
version).
pnpm install
pnpm check # format check, lint, typecheck and unit tests across the workspace
Run the desktop app in development:
pnpm --filter @querybara/desktop dev
Build a test installer for the current OS with pnpm --filter @querybara/desktop package (output
in apps/desktop/dist). The Package workflow builds and smoke-tests the installers of every
platform: AppImage, deb and rpm (x64, arm64), NSIS, MSI and zip (x64, arm64), and a universal
macOS DMG. A v* tag builds a release, signed and notarised when the signing secrets are set,
with auto-update (stable and beta channels, staged rollout, a policy switch for managed fleets),
a CycloneDX SBOM and third-party licence notices, into a draft GitHub release; see
docs/releasing.md. Test builds are not signed: macOS asks you to allow them
in System Settings → Privacy & Security the first time they open.
Build and use the CLI:
pnpm --filter @querybara/cli build
node apps/cli/dist/querybara.mjs --help
node apps/cli/dist/querybara.mjs compare postgres://app@db1/shop postgres://app@db2/shop --out sync.sql
node apps/cli/dist/querybara.mjs query "postgres://[email protected]/shop" --ssh [email protected] --ssh-agent -e "select 1"
node apps/cli/dist/querybara.mjs import dev --table public.people --file people.csv --mode upsert --key id
node apps/cli/dist/querybara.mjs export dev --table orders --table items --format sql-ddl --one-file --out shop.sql.gz --gzip
node apps/cli/dist/querybara.mjs import dev --table sales --file q3.xlsx --sheet July --create --key id
node apps/cli/dist/querybara.mjs export dev --table orders --table items --format xlsx --one-file --out shop.xlsx
node apps/cli/dist/querybara.mjs export dev --table events --format parquet --codec zstd --out events.parquet
node apps/cli/dist/querybara.mjs run-file dev migrate.sql --continue
QUERYBARA_BACKUP_PASSPHRASE=… node apps/cli/dist/querybara.mjs backup prod --out shop.qbak --encrypt
node apps/cli/dist/querybara.mjs restore dev shop.qbak --select public.orders --database shop_copy --create-database
The CLI shares the desktop app's saved connections (--store or QUERYBARA_STORE point it at
another store file).
Tests
-
pnpm test runs the unit tests of every package.
-
pnpm test:integration runs the driver, sync round-trip and CLI suites against real servers.
Each engine's suite runs only when its URL is set, for example:
export QUERYBARA_TEST_POSTGRES_URL=postgres://postgres:[email protected]:5432/querybara_test
export QUERYBARA_TEST_MYSQL_URL=mysql://root:[email protected]:3306/querybara_test
export QUERYBARA_TEST_MARIADB_URL=mariadb://root:[email protected]:3307/querybara_test
pnpm test:integration
Test URLs default to TLS off; add ?tls=verify-full (and the QUERYBARA_TEST_*_TLS_CA
variables) to test TLS.
-
xvfb-run -a pnpm --filter @querybara/desktop test:e2e drives the built Electron app with
Playwright against QUERYBARA_TEST_POSTGRES_URL (drop xvfb-run on a desktop).
CI runs format, lint, typecheck and unit tests, a dependency audit, the integration suites
against PostgreSQL, MySQL and MariaDB service containers (the full version matrix nightly), and
the desktop end-to-end tests.
Design documents
- Architecture decision records:
docs/adr.
- The product and technical specification is a living document shared separately; each ADR
cites the section it implements.
Conventions
Strict TypeScript with no any, ESLint and Prettier, an ADR for every major choice, and
conventional commits.
Licence
Querybara is open source under the Apache License 2.0. The name and the capybara logo
are trademarks; see NOTICE. Contributions are welcome: see
CONTRIBUTING.md.
Privacy
Querybara collects no usage data. It connects only to the servers you configure and to GitHub to
check for updates, which you can turn off. Details are in PRIVACY.md.
Code signing policy
macOS releases are signed with the maintainer's Apple Developer ID and notarised by Apple. Windows
releases are not code-signed yet: the project has applied to the SignPath Foundation's free code
signing for open-source projects.
Team roles and their members:
Every release is built from a tagged commit on main by the
Package workflow on GitHub-hosted runners, and published only
after an approver reviews the draft release.