A cross-platform desktop SQL client for Snowflake, MySQL, PostgreSQL, SQLite, Salesforce, and MotherDuck (DuckDB) with a clean, minimalistic UI.
- Multi-Database Support: Connect to Snowflake, MySQL, PostgreSQL, SQLite, Salesforce, and MotherDuck (DuckDB) databases
- SQL Editor: Full-featured editor with syntax highlighting powered by CodeMirror 6
- Database Browser: Explore databases, schemas, tables, and columns with lazy loading
- Auto-Complete: Context-aware autocomplete for schemas, tables, and columns
- In SELECT/WHERE clauses: suggests columns from tables in your FROM clause
- In FROM clause: suggests schemas and tables
- Query Management: Organize queries in folders, save and load queries
- Query History: Track executed queries with execution time and row counts
- Results Panel: View query results in a virtualized table that handles large datasets
- Export: Export results to CSV or JSON
- SQL Formatting: Format your SQL with proper indentation and uppercase keywords
- Electron - Cross-platform desktop framework
- React 18 - UI framework
- TypeScript - Type safety
- Vite - Fast bundling and HMR
- Zustand - Lightweight state management
- CodeMirror 6 - SQL editor with syntax highlighting
- Tailwind CSS - Styling with custom pastel theme
- sql-formatter - SQL formatting
# Install dependencies
npm install
# Run in development mode
npm run dev
# Build for production
npm run build
# Package as distributable
npm run package| Action | Mac | Windows/Linux |
|---|---|---|
| Run Query | Cmd+Enter |
Ctrl+Enter |
| Save Query | Cmd+S |
Ctrl+S |
| Format SQL | Cmd+Shift+F |
Ctrl+Shift+F |
| Accept Autocomplete | Tab |
Tab |
- Click Add Connection in the sidebar
- Select your database type (Snowflake, MySQL, PostgreSQL, SQLite, Salesforce, or MotherDuck)
- Enter connection details
- Click Test Connection to verify
- Click Save to add the connection
- Click on a connection to connect
- Write your SQL in the editor
- Press
Cmd/Ctrl+Enteror click Run to execute - View results in the bottom panel
- Type a schema name and press
.to see tables - Type a table name and press
.to see columns (in SELECT/WHERE) - Press
Tabto accept the first suggestion - Press
Ctrl+Spaceto manually trigger autocomplete
- Right-click in the Queries section to create folders
- Right-click on a folder to create new queries
- Double-click to rename queries or folders
- Drag to reorder (coming soon)
src/
├── main/ # Electron main process
│ ├── database/ # Database adapters
│ │ ├── postgres.ts
│ │ ├── mysql.ts
│ │ ├── snowflake.ts
│ │ └── motherduck.ts
│ ├── storage/ # Local storage for queries
│ └── index.ts # Main entry point
├── renderer/ # React frontend
│ ├── components/ # UI components
│ ├── stores/ # Zustand stores
│ └── assets/ # Images and icons
└── shared/ # Shared types
# Build for current platform
npm run packageOutput will be in the release/ folder:
- macOS:
.dmginstaller and.appbundle - Windows:
.exeinstaller - Linux:
.AppImage
The test suite uses Vitest and covers all database adapters, the connection manager, query storage, SQL utilities, and export functions (98 tests across 9 test files). All tests use mocked dependencies — no real database connections are needed.
# Run all tests once
npm test
# Run tests in watch mode (re-runs on file changes)
npm run test:watch
# Run a specific test file
npx vitest run src/main/database/__tests__/postgres.test.tsTests live in __tests__/ directories alongside the source code they cover:
src/
main/
database/__tests__/
connection-manager.test.ts
postgres.test.ts
mysql.test.ts
snowflake.test.ts
salesforce.test.ts
sqlite.test.ts
motherduck.test.ts
storage/__tests__/
query-storage.test.ts
shared/__tests__/
sql-utils.test.ts
renderer/utils/__tests__/
export.test.ts
- Fork the repository and create a feature branch from
main - Make your changes
- Run
npm testand ensure all tests pass - Run
npm run buildto verify the build succeeds - Submit a pull request
- TypeScript strict mode is enabled
- Use existing patterns in the codebase as a guide
- Keep changes minimal and focused
- Place test files in a
__tests__/directory next to the source file - Use
vi.mock()with factory functions to mock external dependencies - Use
vi.hoisted()for mock variables referenced insidevi.mock()factories - Use class-based mocks when mocking constructors (e.g.,
class MockPool { ... }) - Reset mock state in
beforeEachwithvi.clearAllMocks()
- Create the adapter in
src/main/database/implementing theDatabaseAdapterinterface - Register it in the
ConnectionManagerfactory - Add the connection type to
ConnectionConfiginsrc/shared/types.ts - Write tests in
src/main/database/__tests__/ - Use
await import()for lazy-loading optional SDK dependencies (notrequire())
MIT
Samir Madhavan
