@ashmit_2k04/nlsql
v1.0.0
Published
Natural language SQL — query databases in plain English from the terminal
Maintainers
Readme
nlsql
Natural language SQL for the terminal.
nlsql translates plain-English questions into SQL, executes them against your database, and renders results as formatted tables — with optional Excel export. No SQL knowledge required.
Powered by Groq (Llama 3.3) with schema-aware generation, automatic query correction, and a bundled demo database so you can start immediately.
nlsql "show all employees over 40 who missed their 2026 sales target"Table of contents
- Features
- Requirements
- Quick start
- Installation
- Configuration
- Usage
- CLI reference
- Interactive mode
- Database support
- Demo database
- How it works
- Security
- Development
- Troubleshooting
- License
Features
- Natural language input — ask questions in plain English, get executable SQL
- Zero database setup — ships with a built-in SQLite demo database
- Multi-database support — PostgreSQL, MySQL, and SQLite
- Schema introspection — reads table structure, column types, and keys before generating queries
- Auto-correction — retries failed queries by feeding errors back to the model
- Conversation context — interactive mode supports follow-up questions
- Excel export — export results to
.xlsxwith one flag - Dry-run mode — generate and inspect SQL without executing
- Global or project-scoped config — works as a globally installed CLI or per-project tool
Requirements
| Dependency | Version | |------------|---------| | Node.js | ≥ 18.0 | | Groq API key | Free at console.groq.com |
Optional: Bun ≥ 1.0 (alternative package manager)
Quick start
Add to your project (recommended)
npm install nlsql
npx nlsql init # creates .env — add your free Groq API key
npx nlsql demo # try it instantly (built-in demo database)
npx nlsql "top 5 customers by revenue"
npx nlsql chat # conversation mode with follow-upsGet a free API key at console.groq.com/keys.
Optional shortcuts — add to your package.json:
{
"scripts": {
"ask": "nlsql",
"db:demo": "nlsql demo",
"db:chat": "nlsql chat"
}
}Then run: npm run db:demo or npm run ask -- "how many employees are there?"
Global install
npm install -g nlsql
nlsql init
nlsql demo
nlsql "top 5 customers by revenue"Expected output: a formatted terminal table with query results.
Commands
| Command | What it does |
|---------|--------------|
| nlsql init | Set up your project (creates .env) |
| nlsql demo | Try nlsql with the built-in demo database |
| nlsql "your question" | Ask a question in plain English |
| nlsql chat | Conversation mode — follow-up questions |
| nlsql --help | Show all options |
Installation
In your project (recommended)
npm install nlsql
npx nlsql init
npx nlsql demoGlobal install
npm install -g nlsql
nlsql initBun
bun add nlsql
bunx nlsql initRun without installing
npx nlsql demo
npx nlsql "how many employees are there?"Verify installation
nlsql --version
nlsql --help
nlsql initConfiguration
Environment variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| GROQ_API_KEY | Yes | — | Groq API key for SQL generation |
| NLSQL_DB | No | bundled demo | Database connection string |
| DATABASE_URL | No | — | Alternative to NLSQL_DB (Heroku/Railway convention) |
| NLSQL_MODEL | No | llama-3.3-70b-versatile | Groq model override |
Config file locations
Environment files are loaded from the first path that exists (later files do not override earlier values):
./.env(current working directory)./.nlsql(current working directory)~/.nlsql/.env(user home — recommended for global installs)~/.config/nlsql/.env(XDG config directory)
Example: persistent global config
mkdir -p ~/.nlsql
cp .env.example ~/.nlsql/.env
# Edit ~/.nlsql/.env and set GROQ_API_KEYProject config file
Create .nlsql.json in your project root to set a default database:
{
"db": "postgres://readonly:password@localhost:5432/production"
}Database connection priority
When resolving which database to use, nlsql applies the following order (highest priority first):
--dbCLI flagNLSQL_DBenvironment variableDATABASE_URLenvironment variable.nlsql.json→dbfield- Bundled demo database (
data/demo.sqlite)
Usage
Single query
nlsql "employees over 40 in the sales department"Show generated SQL
nlsql "top 10 customers by revenue" --show-sqlDry run (generate SQL only)
nlsql "average sale amount per employee" --dry-runExport to Excel
nlsql "all sales in 2026" --xlsx
nlsql "all sales in 2026" --xlsx --out sales-report.xlsxConnect to your own database
# PostgreSQL
nlsql "active users last 30 days" --db postgres://user:pass@localhost:5432/mydb
# MySQL
nlsql "orders over $500" --db mysql://user:pass@localhost:3306/shop
# SQLite
nlsql "count rows in events" --db /path/to/database.sqliteCombine flags
nlsql "revenue by customer" --db postgres://... --show-sql --xlsx --out revenue.xlsxCLI reference
Usage: nlsql [command] [options] [query]
Commands:
init Set up nlsql in your project (creates .env)
demo [query] Try nlsql with the built-in demo database
chat Conversation mode with follow-up questions
Arguments:
query Natural language query
Options:
-V, --version Output the current version
-d, --db <connection> Database connection string (overrides config)
-x, --xlsx Export results to Excel
-o, --out <file> Output Excel filename (default: "results.xlsx")
-s, --show-sql Print the generated SQL before running
-i, --interactive Start interactive REPL mode
-c, --config <path> Path to config file (default: ".nlsql.json")
--dry-run Generate SQL without executing
-h, --help Display help| Flag | Short | Description |
|------|-------|-------------|
| --db | -d | Database connection string; overrides all other DB config |
| --show-sql | -s | Print generated SQL before execution |
| --xlsx | -x | Export results to an Excel file |
| --out | -o | Excel output filename (default: results.xlsx) |
| --dry-run | | Generate SQL only; do not connect or execute |
| --interactive | -i | Start interactive REPL |
| --config | -c | Custom path to JSON config file |
| --version | -V | Print package version |
| --help | -h | Print usage information |
Interactive mode
Start a conversation for exploratory querying and follow-up questions:
nlsql chat
# or
nlsql -iREPL commands
| Command | Description |
|---------|-------------|
| :sql | Toggle display of generated SQL |
| :xlsx | Toggle Excel export for each query |
| :history | Show session query history |
| :clear | Clear conversation context (for follow-ups) |
| :exit | Exit the REPL |
Follow-up queries
Interactive mode maintains conversation context, so you can refine results iteratively:
❯ top 10 customers by revenue
❯ now only show ones created in 2024
❯ sort them alphabeticallyDatabase support
| Engine | Connection string format | Schema introspection | Execution |
|--------|--------------------------|----------------------|-----------|
| PostgreSQL | postgres://user:pass@host:5432/db | Full (tables, columns, keys, FKs) | Supported |
| MySQL | mysql://user:pass@host:3306/db | Full (tables, columns, keys) | Supported |
| SQLite | /absolute/or/relative/path.sqlite | Full (via PRAGMA table_info) | Supported |
Dialect is detected automatically from the connection string.
Demo database
If no database is configured, nlsql uses a bundled SQLite database with sample business data.
Schema
employees
| Column | Type | Notes |
|--------|------|-------|
| id | INTEGER | Primary key |
| name | TEXT | |
| age | INTEGER | |
| department | TEXT | e.g. Sales, Engineering |
| hire_date | TEXT | ISO date |
sales
| Column | Type | Notes |
|--------|------|-------|
| id | INTEGER | Primary key |
| employee_id | INTEGER | FK → employees.id |
| amount | REAL | Sale value |
| sale_date | TEXT | ISO date |
sales_targets
| Column | Type | Notes |
|--------|------|-------|
| id | INTEGER | Primary key |
| employee_id | INTEGER | FK → employees.id |
| year | INTEGER | Target year |
| target_amount | REAL | Annual target |
customers
| Column | Type | Notes |
|--------|------|-------|
| id | INTEGER | Primary key |
| name | TEXT | |
| revenue | REAL | Total revenue |
| created_at | TEXT | ISO date |
Example queries
nlsql "employees over 40 in the sales department"
nlsql "who missed their 2026 sales target"
nlsql "top 5 customers by revenue"
nlsql "total sales per employee in 2026"How it works
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ Your query │────▶│ Schema │────▶│ Groq API │
│ (English) │ │ introspection │ │ (Llama 3.3) │
└─────────────┘ └──────────────────┘ └──────┬──────┘
│
┌──────────────────┐ ▼
│ Terminal table / │ ┌─────────────┐
│ Excel export │◀────│ SQL execute │
└──────────────────┘ └──────┬──────┘
│
┌──────▼──────┐
│ Auto-fix on │
│ error (1x) │
└─────────────┘- Connect — resolves database config and establishes a connection
- Introspect — reads schema metadata (tables, columns, types, constraints)
- Generate — sends schema + natural language query to Groq; receives SQL
- Execute — runs the generated SQL against your database
- Correct — on failure, sends the error back to the model and retries once
- Render — displays results as a formatted table (up to 200 rows shown)
- Export — optionally writes results to Excel
Only schema structure and your query text are sent to the Groq API. Database credentials and row data never leave your machine.
Security
Data handling
| Data | Sent to Groq API? | |------|-------------------| | Natural language query | Yes | | Database schema (table/column names, types) | Yes | | Database credentials | No — stays local | | Query result rows | No — stays local |
Recommendations
- Use a read-only database user when connecting to production databases
- Store API keys in environment variables or
~/.nlsql/.env, never in source control - Review generated SQL with
--dry-runor--show-sqlbefore running against sensitive data - Generated queries are
SELECT-only by default; destructive operations require explicit intent in the query
API key management
# Do not commit .env — use the provided template
cp .env.example .env.env is listed in .gitignore by default.
Development
Local setup
git clone <repository-url>
cd nlsql
npm install
cp .env.example .env
# Set GROQ_API_KEY in .envScripts
| Command | Description |
|---------|-------------|
| npm start | Run CLI (node src/index.js) |
| npm test | Run test suite |
| npm run seed-demo | Regenerate the bundled demo database |
Project structure
nlsql/
├── data/
│ └── demo.sqlite # Bundled demo database
├── scripts/
│ ├── seed-demo.js # Demo DB generator
│ └── test.js # Test suite
├── src/
│ ├── index.js # CLI entry point
│ ├── ai.js # Groq integration
│ ├── config.js # Environment loading
│ ├── db.js # Database drivers & schema introspection
│ ├── demo-db.js # Bundled demo DB resolution
│ ├── display.js # Terminal table rendering
│ ├── export.js # Excel export
│ ├── interactive.js # REPL mode
│ └── query.js # Query pipeline orchestration
├── .env.example
├── package.json
└── README.mdPublishing
npm test
npm login
npm publishThe prepublishOnly hook runs tests and regenerates the demo database automatically.
Troubleshooting
No API key found. Set GROQ_API_KEY
Set the key via environment variable or config file:
export GROQ_API_KEY=gsk_your_key_hereOr create ~/.nlsql/.env with GROQ_API_KEY=....
Failed to generate SQL / rate limits
Groq free tier has request limits. Wait a moment and retry, or check usage at console.groq.com.
Query returns wrong results
- Use
--show-sqlto inspect the generated SQL - Use
--dry-runto validate SQL before execution - Ensure schema introspection succeeded (no connection errors during startup)
- In interactive mode, use
:clearto reset context if follow-ups drift
Cannot connect to database
- Verify the connection string format for your database engine
- Confirm the database server is running and reachable
- Test connectivity with a native client (
psql,mysql, etc.) - For SQLite, use an absolute path if relative paths fail
nlsql command not found after global install
Ensure npm global bin is on your PATH:
npm config get prefix
# Add <prefix>/bin to your PATHLicense
MIT
