Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quick Start

This walkthrough takes you from a fresh ferrule install to a real database in under five minutes. SQLite for the warm-up, then a disposable Postgres in Docker for everything else.

Step 1 — your first query

SQLite needs no setup. Run:

ferrule query "sqlite::memory:" "SELECT 1 + 1 AS answer;" --format table

Output:

┌────────┐
│ answer │
├────────┤
│ 2      │
└────────┘

Drop the --format table flag and you’ll get JSON instead — that’s the default. Either form is fine for now.

ferrule query "sqlite::memory:" "SELECT 1 + 1 AS answer;"
# [
#   {
#     "answer": 2
#   }
# ]

Step 2 — a real database

Spin up a throwaway Postgres in Docker. This mirrors the test setup in CLAUDE.md; copy and paste:

docker run -d --name ferrule-quickstart \
  -e POSTGRES_PASSWORD=ferrule \
  -e POSTGRES_USER=ferrule \
  -e POSTGRES_DB=ferrule \
  -p 127.0.0.1:15432:5432 \
  postgres:17-alpine

# Wait for it to come up (~3 seconds)
until docker exec ferrule-quickstart pg_isready -U ferrule >/dev/null 2>&1; do
  sleep 1
done

# Seed a tiny schema
PGPASSWORD=ferrule psql -h 127.0.0.1 -p 15432 -U ferrule -d ferrule -c "
CREATE TABLE customers (
  id SERIAL PRIMARY KEY,
  name TEXT,
  signed_up TIMESTAMPTZ DEFAULT now()
);
INSERT INTO customers (name) VALUES ('Alice'), ('Bob'), ('Carol');
"

Now query it directly:

ferrule query "postgres://ferrule:ferrule@127.0.0.1:15432/ferrule?sslmode=disable" \
  "SELECT * FROM customers;" --format table

Output something like:

┌────┬───────┬───────────────────────────────┐
│ id │ name  │ signed_up                     │
├────┼───────┼───────────────────────────────┤
│ 1  │ Alice │ 2026-04-26 18:01:23.456+00:00 │
│ 2  │ Bob   │ 2026-04-26 18:01:23.456+00:00 │
│ 3  │ Carol │ 2026-04-26 18:01:23.456+00:00 │
└────┴───────┴───────────────────────────────┘

When you’re done with the container:

docker stop ferrule-quickstart && docker rm ferrule-quickstart

Step 3 — save a named connection

Typing the full URL every time gets old. Add it to the registry:

ferrule conn add demo "postgres://ferrule@127.0.0.1:15432/ferrule?sslmode=disable"
ferrule conn set-password demo
# Password: ferrule

Now use the name:

ferrule query demo "SELECT COUNT(*) FROM customers;"
ferrule tables demo
ferrule describe demo customers
ferrule repl demo

The password is stored in your OS keyring under keyring://ferrule/demo, never on disk in plaintext.

Step 4 — pipe-friendly defaults

The default output format is JSON. That’s chosen so output piped to jq, awk, or another command “just works”:

ferrule query demo "SELECT * FROM customers" | jq '.[].name'
# "Alice"
# "Bob"
# "Carol"

If you’d rather see tables in your terminal, either pass --format table per command, or set a project default in .ferrule.toml (see Configuration).

Step 5 — save a bookmark

For queries you run all the time, bookmarks beat shell aliases:

ferrule bookmark add daily-count \
  "SELECT COUNT(*) FROM customers WHERE signed_up > now() - interval '1 day';" \
  --connection demo

ferrule bookmark run daily-count

Positional parameters work too:

ferrule bookmark add by-name "SELECT * FROM customers WHERE name = ${1};" \
  --connection demo

ferrule bookmark run by-name "'Alice'"

How passwords get resolved

Step 3 stored a password in the keyring. The next time you run ferrule query demo "..." without a password on the URL, ferrule walks this stack and stops at the first hit:

1. --password CLI flag        (you didn't pass one)
2. password_url in profile    (no .ferrule.toml profile yet)
3. FERRULE_DEMO_PASSWORD env  (unset)
4. keyring://ferrule/demo     ← FOUND (set by `conn set-password`)
5. Interactive prompt
6. Fail

This is described in detail in Concepts and Security. For now: storing in the keyring is the right default for a workstation.

Where to next

  • Querying Data — output formats, paging, parameterized queries.
  • Connections — profiles, environment interpolation, registry vs .ferrule.toml.
  • Interactive REPL — meta-commands, watch mode.
  • Concepts — the abstractions everything is built on.