{"id":47266844,"url":"https://github.com/jxdones/stoat","last_synced_at":"2026-04-11T05:14:03.568Z","repository":{"id":343367266,"uuid":"1161801274","full_name":"jxdones/stoat","owner":"jxdones","description":"The database client for people who don't leave the terminal.","archived":false,"fork":false,"pushed_at":"2026-04-11T02:01:53.000Z","size":17934,"stargazers_count":27,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-11T03:24:56.882Z","etag":null,"topics":["database-viewer","go","terminal-ui","tui"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jxdones.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-19T14:34:04.000Z","updated_at":"2026-04-11T02:02:01.000Z","dependencies_parsed_at":"2026-03-31T03:00:56.136Z","dependency_job_id":null,"html_url":"https://github.com/jxdones/stoat","commit_stats":null,"previous_names":["jxdones/stoat"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/jxdones/stoat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxdones%2Fstoat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxdones%2Fstoat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxdones%2Fstoat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxdones%2Fstoat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jxdones","download_url":"https://codeload.github.com/jxdones/stoat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxdones%2Fstoat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31669224,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T17:19:37.612Z","status":"online","status_checked_at":"2026-04-11T02:00:05.776Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database-viewer","go","terminal-ui","tui"],"created_at":"2026-03-15T06:03:46.418Z","updated_at":"2026-04-11T05:14:03.563Z","avatar_url":"https://github.com/jxdones.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cp\u003e\n    \u003cimg src=\"assets/stoat.png\" alt=\"Stoat logo\" width=\"150\"/\u003e\n    \u003ch2\u003eStoat\u003c/h2\u003e\n  \u003c/p\u003e\n\n  \u003cp\u003eThe database client for people who don't leave the terminal.\u003c/p\u003e\n\n  \u003cp\u003e\n    \u003cimg src=\"assets/stoat.gif\" alt=\"Stoat demo\" width=\"830\"/\u003e\n  \u003c/p\u003e\n\n![License](https://img.shields.io/badge/license-MIT-blue.svg)\n![Go Version](https://img.shields.io/badge/go-1.26+-00ADD8.svg)\n\n[Quick Start](#quick-start) • [Features](#features) • [Installation](#installation) • [Database Support](#database-support) • [Key Controls](#key-controls) • [Themes](#themes) • [Configuration](#configuration) • [Contributing](#contributing)\n\u003c/div\u003e\n\n## Why Stoat?\n\nYou're already in a shell. You need to check a table, inspect a schema, or run a quick query. Opening a GUI for that is friction you don't need.\n\nRaw CLI clients like `psql` or `sqlite3` are great for scripts but rough for browsing data. You have no visual navigation, no schema overview, no easy paging.\n\nStoat sits between those two extremes: a keyboard-driven TUI that gives you real database inspection without leaving your workflow.\n\nBuilt for anyone who lives in the terminal and wants database access that doesn't interrupt their flow.\n\nBuilt with [Bubbletea](https://github.com/charmbracelet/bubbletea) by Charmbracelet.\n\n## Quick start\n\n```bash\n# Open the connection picker (reads from ~/.stoat/config.yaml)\nstoat\n\n# SQLite (one-off, bypasses picker)\nstoat --db path/to/database.sqlite\n\n# PostgreSQL (one-off, bypasses picker)\nstoat --dsn \"postgres://user:password@host:5432/dbname?sslmode=disable\"\n\n# Pass credentials via environment variable (keeps secrets out of shell history)\nexport MY_DSN=\"postgres://user:password@host:5432/dbname?sslmode=disable\"\nstoat --dsn-env MY_DSN\n\n# Print version\nstoat --version\n\n# Write per-call timings to ~/.stoat/debug.log\nstoat --db path/to/database.sqlite --debug\n\n# Open in read-only mode (works with --db, --dsn, or the connection picker)\nstoat --read-only\n```\n\nRun `stoat` with no arguments to open the connection picker and choose from your saved connections. Pass `--db` or `--dsn` to connect directly, bypassing the picker. Use `--dsn-env` instead of `--dsn` to read the connection string from an environment variable. Credentials won't appear in shell history or the process argument list.\n\n## Features\n\n- Schema exploration — browse columns, indexes, constraints, and foreign keys in dedicated tabs without writing `PRAGMA` or `\\d`\n- Inline SQL — run ad-hoc queries from a built-in query box; save snippets you reuse often\n- Open in `$EDITOR` — press `Ctrl+E` to write multi-line SQL in your editor; saves and runs on close\n- Vim-style navigation — `hjkl`, `gg`/`G`, count prefixes (`10j`), all the muscle memory you already have\n- Edit in place — press `Enter` on any cell to edit its value inline; confirm with `Enter`, cancel with `Esc`\n- Filter without SQL — narrow down loaded rows without rewriting your query\n- Read-only mode — connect safely to production with `--read-only` or `read_only: true` per connection in config; enforced at the DB level and in the UI\n- SQL syntax highlighting — keywords, strings, numbers, comments, and operators are colored as you type; palette adapts to the active theme\n- Themes — 11 built-in themes including dracula, catppuccin, gruvbox, rose-pine, and more\n\n## Installation\n\n**One-liner:**\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/jxdones/stoat/main/install.sh | sh\n```\n\nTo install a specific version:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/jxdones/stoat/main/install.sh | sh -s -- v0.14.7\n```\n\n**Homebrew** (macOS):\n\n```bash\nbrew tap jxdones/stoat\nbrew install --cask stoat\n```\n\n**Go install:**\n\n```bash\ngo install github.com/jxdones/stoat@latest\n```\n\n**Docker:**\n\n```bash\ndocker build -t stoat .\ndocker run --rm -it -v \"$(pwd)/data:/data\" stoat --db /data/your.db\n```\n\n**From the repo root** (developers):\n\n```bash\nmake install\n```\n\nTo install to a specific prefix (e.g. user-local without sudo):\n\n```bash\nPREFIX=$HOME/.local\nmake install-prefix\n```\n\nThen add `$HOME/.local/bin` to your `PATH` if needed.\n\n## Database support\n\nSQLite, PostgreSQL, MySQL, and MariaDB are supported.\n\n## Works with hosted databases\n\nIf you use Supabase, Neon, Railway, or Render, paste your connection string and you're in. No browser, no dashboard, no context switch.\n\n```bash\n# Supabase\nstoat --dsn \"postgres://postgres:[password]@db.[project].supabase.co:[port]/postgres?sslmode=require\"\n\n# Neon\nstoat --dsn \"postgres://[user]:[password]@[host].neon.tech/[dbname]?sslmode=require\"\n\n# Railway\nstoat --dsn \"postgres://[user]:[password]@[host].railway.app:[port]/[dbname]?sslmode=require\"\n\n# Render\nstoat --dsn \"postgres://[user]:[password]@[host].render.com:[port]/[dbname]?sslmode=require\"\n```\n\nAny provider that gives you a `postgres://` connection string works. Including AWS RDS, GCP Cloud SQL, and Azure Database for PostgreSQL.\n\n## Key controls\n\nThe options bar at the bottom shows shortcuts for the currently focused pane. When focus is clear, it shows `q` to quit.\n\n### Global\n\n| Key | Action |\n| --- | --- |\n| `Ctrl+C` | Quit (always) |\n| `q` | Quit (only when focus is clear) |\n| `Esc` | Clear focus |\n| `Tab` / `Shift+Tab` | Cycle focus forward / backward |\n| `/` | Focus filter box |\n| `c` | Show connection picker (only when focus is clear) |\n| `R` | Reload current table (first page) |\n| `?` | Show help |\n\n### Sidebar\n\n| Key | Action |\n| --- | --- |\n| `h` `j` `k` `l` | Move cursor |\n| `g` / `G` | Jump to top / bottom |\n| `Enter` | Open selected table |\n\n### Table\n\n| Key | Action |\n| --- | --- |\n| `h` `j` `k` `l` | Move cursor |\n| `g` / `G` | Jump to top / bottom |\n| `Ctrl+1` – `Ctrl+5` | Switch tabs (Records, Columns, Constraints, Foreign Keys, Indexes) |\n| `Ctrl+N` / `Ctrl+B` | Next / previous page |\n| `0` / `$` | Go to first / last column |\n| `N` + motion (e.g. `4h`, `10j`) | Repeat motion N times (vim count prefix) |\n| `Enter` | Enter inline edit mode for the selected cell |\n| `y` | Copy value from active cell to clipboard |\n| `dd` | Delete selected row |\n\n### Table — Edit mode\n\n| Key | Action |\n| --- | --- |\n| `Enter` | Confirm edit and run UPDATE |\n| `Esc` | Cancel edit |\n\n### Table — Delete mode\n\n| Key | Action |\n| --- | --- |\n| `y` | Confirm delete |\n| `n` / `Esc` | Cancel delete |\n\n### Filter box\n\n| Key | Action |\n| --- | --- |\n| `Enter` | Apply filter to currently loaded rows (empty filter resets table) |\n\n### Query box\n\n| Key | Action |\n| --- | --- |\n| `Ctrl+R` | Run query |\n| `Ctrl+E` | Open `$EDITOR` with a SQL template; save and close to run |\n| `Ctrl+N` | Expand saved query (type `@Name` then Ctrl+N to insert) |\n| `Ctrl+L` | Clear query |\n\n## Themes\n\n| | |\n|---|---|\n| ![Dracula](assets/stoat_dracula.png) | ![Everforest](assets/stoat_everforest.png) |\n| ![Gruvbox](assets/stoat_gruvbox.png) | ![Princess](assets/stoat_princess.png) |\n\nAvailable themes: `default`, `dracula`, `solarized`, `catppuccin`, `everforest`, `gruvbox`, `one-dark`, `rose-pine`, `princess`, `one-shell`, `blueish`. Set via `theme` in `~/.stoat/config.yaml`.\n\n## Configuration\n\nStoat reads configuration from **`~/.stoat/config.yaml`**. This file is created automatically on first run.\n\n| Option | Description |\n|--------|-------------|\n| `theme` | UI theme. Available: `default`, `dracula`, `solarized`, `catppuccin`, `everforest`, `gruvbox`, `one-dark`, `rose-pine`, `princess`, `one-shell`, `blueish`. |\n| `connections` | Saved database connections. Each connection supports `read_only: true` to enforce read-only mode at the DB and UI level, and `saved_queries` to define named SQL snippets scoped to that connection. |\n\nExample:\n\n```yaml\n# ~/.stoat/config.yaml\ntheme: default\n\nconnections:\n  - name: local\n    type: sqlite\n    path: /path/to/database.sqlite\n    saved_queries:\n      - name: recent_users\n        query: SELECT * FROM users ORDER BY updated_at DESC LIMIT 10\n      - name: schema\n        query: SELECT name, sql FROM sqlite_master WHERE type = 'table'\n\n  - name: my-postgres\n    type: postgres\n    host: localhost\n    port: 5432        # optional, defaults to 5432\n    user: postgres\n    password: secret\n    database: mydb\n\n  - name: supabase-prod\n    type: postgres\n    host: db.[project].supabase.co\n    port: 5432\n    user: postgres\n    password: secret\n    database: postgres\n    read_only: true   # blocks writes in the UI and at the DB level\n\n  - name: local-mysql\n    type: mysql\n    host: 127.0.0.1\n    port: 3306        # optional, defaults to 3306\n    user: root\n    password: secret\n    database: mydb\n    # tls_mode: true  # set to true for hosted/remote MySQL, skip-verify to skip cert validation\n\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjxdones%2Fstoat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjxdones%2Fstoat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjxdones%2Fstoat/lists"}