No description
  • Go 96.6%
  • Shell 1.9%
  • Makefile 1.5%
Find a file
github-actions[bot] 4c746774a1
Some checks failed
CI / test (push) Waiting to run
CI / check (push) Waiting to run
CI / check-releaser (push) Waiting to run
CI / status-check (push) Has been cancelled
Merge pull request #63 from kiki-ki/dependabot/go_modules/minor-patch-820560494d
chore(deps): bump modernc.org/sqlite from 1.50.1 to 1.51.0 in the minor-patch group
2026-05-30 00:58:18 +00:00
.github chore(deps): bump dependabot/fetch-metadata from 2 to 3 2026-04-11 00:03:01 +00:00
cmd feat(psv): add support for PSV files (pipe deliminated) 2026-02-13 14:58:14 -05:00
doc/demo fix(doc): update demo 2026-01-17 13:04:31 +09:00
internal refactor(parser): move ParseCSVBytes to csv.go 2026-04-02 20:14:06 +09:00
testdata feat(input): strip UTF-8 BOM from input data 2026-04-02 19:57:47 +09:00
.gitignore fix(doc): update demo 2026-01-17 13:04:31 +09:00
.golangci.yml add lint command 2025-11-27 01:06:24 +09:00
.goreleaser.yaml chore(cd): fix to create release notes using github-native 2025-12-13 14:25:52 +09:00
CLAUDE.md docs: add CLAUDE.md for Claude Code guidance 2026-02-28 18:07:50 +09:00
go.mod chore(deps): bump modernc.org/sqlite in the minor-patch group 2026-05-30 00:54:46 +00:00
go.sum chore(deps): bump modernc.org/sqlite in the minor-patch group 2026-05-30 00:54:46 +00:00
install.sh Change architecture name from x86_64 to amd64 2025-12-03 09:49:47 +09:00
LICENSE Initial commit 2025-11-25 23:06:57 +09:00
Makefile fix(doc): update demo 2026-01-17 13:04:31 +09:00
README.md fix: fix README.md 2026-02-14 12:16:54 +09:00

🥢 qo

Terminal Trove Tool of The Week

GitHub release CI Go Report License

qo [cue-oh] noun.

  1. A minimalist TUI for querying JSON, CSV using SQL.
  2. "query" what you need, and get it "out" to the pipeline.
qo demo: Querying JSON data with SQL in the TUI

Why qo?

  • Muscle Memory: Use the SQL syntax you've known for years.
  • Pipeline Native: Reads from stdin, writes to stdout.
  • Interactive: Don't guess the query. See the result, then hit Enter.

Install

macOS and Linux (amd64/arm64) are supported.

Homebrew (Package)

brew install kiki-ki/tap/qo

Shell (Binary)

curl -sfL https://raw.githubusercontent.com/kiki-ki/go-qo/main/install.sh | sh

Git (Source)

# The binary will be located at ./bin/qo
git clone --depth 1 https://github.com/kiki-ki/go-qo.git && cd go-qo && make build

Usage

qo reads from both file arguments and standard input (stdin).

# Interactive mode (Open TUI)
cat x.json | qo
qo x.json y.json

# Non-interactive mode (Direct output)
cat x.json | qo -q "SELECT * FROM tmp WHERE id > 100"
qo -q "SELECT * FROM x JOIN y ON x.id = y.x_id" x.json y.json"

Pipe-Friendly TUI

TUI mode works seamlessly with pipes. Explore data interactively, then pass the result to other tools.

# Fetch JSON API > Filter interactively with qo > Format with jq
curl -s https://api.github.com/repos/kiki-ki/go-qo/commits | qo | jq '.[].sha'

# Explore > Filter > Compress
cat large.json | qo | gzip > filtered.json.gz

Query Logs & Aggregate

Use SQL to analyze structured data.

# Filter error logs
cat app.log | qo -q "SELECT timestamp, message FROM tmp WHERE level = 'error'"

# Aggregate sales by region
qo -i csv sales.csv -o csv -q "SELECT region, SUM(amount) FROM sales GROUP BY region"

Convert Formats

Transform between various formats.

qo -o csv data.json -q "SELECT id, name FROM data"             # JSON → CSV
qo -i csv -o json users.csv -q "SELECT * FROM users"           # CSV → JSON
qo -o jsonl data.json -q "SELECT * FROM data"                  # JSON → JSON Lines
qo -i csv --no-header raw.csv -q "SELECT col1, col2 FROM raw"  # Headerless CSV

Options

Flag Short Default Description
--input -i json Input format: json, csv, tsv, psv ("json" includes "jsonl")
--output -o json Output format: json, jsonl, csv, tsv, psv, table
--query -q Run SQL query directly (Skip TUI)
--no-header Treat first row as data, not header (CSV/TSV/PSV only)

UI Controls

Key Mode Action
Tab ALL Switch between Query/Table mode
Esc ALL Output & Quit
Ctrl+C ALL Quit (Output nothing)
Enter QUERY Execute query
/ j k TABLE Scroll rows
/ h l TABLE Scroll columns

SQL Dialect

qo uses SQLite as its SQL engine. All queries follow SQLite syntax and support its built-in functions.

Querying Nested JSON

Use SQLite's json_extract() function to access nested fields in JSON data.

# Sample data: [{"user": {"name": "Alice", "age": 30}}, {"user": {"name": "Bob", "age": 25}}]

# Extract nested fields
qo data.json -q "SELECT json_extract(user, '$.name') AS name FROM data"
# Filter by nested value
qo data.json -q "SELECT * FROM data WHERE json_extract(user, '$.age') > 25"

For more details, see SQLite JSON Functions.

Built With

Category Library
TUI Framework Bubble Tea
Styling Lip Gloss
CLI Cobra
SQL Engine modernc.org/sqlite (Pure Go, CGO-free)

License

MIT