lacspace-sql
Run SQL over your CSV, JSON, NDJSON and Excel files — no database.
npx lacspace-sql "SELECT * FROM ./data.csv LIMIT 5"Everything, in one command
lacspace-sql loads a file into memory and runs a genuine SQL engine over it — a tokenizer, parser and evaluator, not a regex. It now joins two files (INNER/LEFT/cross, aliases, qualified columns), evaluates arithmetic and scalar functions (UPPER/LOWER/TRIM/SUBSTR/CONCAT/COALESCE/ROUND/ABS…) with CASE WHEN, matches with BETWEEN/NOT IN/NOT LIKE/LIKE ESCAPE, combines result sets with UNION/UNION ALL, and reads a glob of files (`'./data/*.csv'`) or stdin as one table. Group and aggregate, order by multiple keys with NULLS FIRST/LAST, then print a table or Markdown or serialise to JSON/NDJSON/CSV/Excel — with --watch to re-run on change. Still one file per table; no subqueries or window functions yet.
What's inside
Any data file
CSV, JSON, NDJSON or Excel — name the file right in the FROM clause.
Real SQL
SELECT, DISTINCT, WHERE (=, !=, <, LIKE, IN, IS NULL, AND/OR/NOT, parens), ORDER BY, LIMIT/OFFSET.
Group & aggregate
GROUP BY with COUNT/SUM/AVG/MIN/MAX (and COUNT(DISTINCT)) plus HAVING.
Smart typing
Numeric strings compare numerically; columns match case-insensitively.
Query → convert
Pretty table by default, or -f json|ndjson|csv|md to export the result in one step.
Typed library
query() / runQuery() plus parseSql() for the AST — build on the engine.
Joins across files
INNER / LEFT / cross joins between two files, with aliases and qualified columns.
Expressions & CASE
Arithmetic + UPPER/LOWER/TRIM/SUBSTR/CONCAT/COALESCE/ROUND/ABS… and CASE WHEN in SELECT.
UNION & globs
UNION / UNION ALL, plus a glob FROM ('./exports/*.csv') or stdin read as one table.
Live --watch
Re-runs the query whenever the source file changes — a live view over your data.
Copy, paste, done
Real commands and snippets — from a one-liner to the typed library.
lacspace-sql "SELECT u.name, o.amount, o.qty*o.price AS total \
FROM users.csv u JOIN orders.json o ON u.id = o.user_id ORDER BY total DESC"Joins a CSV and a JSON on a key, with a computed column.
lacspace-sql "SELECT name, CASE WHEN revenue>=1000 THEN 'A' \
WHEN revenue>=500 THEN 'B' ELSE 'C' END AS grade FROM ./leads.csv"Bucket rows with a CASE expression.
lacspace-sql "SELECT city, COUNT(*) AS n FROM './exports/*.csv' \
GROUP BY city ORDER BY n DESC" -f mdReads every matching file as one table, emits a Markdown table.
cat leads.csv | lacspace-sql "SELECT UPPER(name) AS name FROM stdin \
WHERE city='Kathmandu'" --stdin csvPipe data straight in as the `stdin` table.
import { query, runQuery } from "lacspace-sql";
const rows = await query("SELECT * FROM ./data.csv WHERE age >= 30");
// or runQuery(sql, alreadyLoadedRows) — pure, no file I/OWhat people build with it
✓ Explore a scraped or leads export
✓ Filter + reshape a CSV without a spreadsheet
✓ Aggregate data inside a shell script or CI
✓ Convert a file while you query it
Run lacspace-sql today
Free, open-source, no API keys. It's a CLI and a typed library.
npx lacspace-sql "SELECT * FROM ./data.csv LIMIT 5"