sqlite3-parser
raw JSON → 0.7.1 verified Mon Apr 27 auth: no javascript
A fast, pure JavaScript LALR(1) parser for SQLite SQL syntax, generated from SQLite's parse.y grammar. Version 0.7.1 ships TypeScript types, runs in Node, Bun, and browsers, and is ~32 KB gzipped. It provides improved error messages with location, expected tokens, and common mistake hints. Compared to alternatives like sql.js or node-sqlite3, it is purely a parser (no database connection) and is 2x-200x faster than other JavaScript SQL parsers (e.g., @nene/query-lang, sql-parser-cst).
Common errors
error ERR_REQUIRE_ESM: Must use import to load ES Module: /node_modules/sqlite3-parser/index.js require() of ES modules is not supported. ↓
cause Trying to require() the package which is ESM-only since v0.7.0.
fix
Replace require('sqlite3-parser') with import { parse } from 'sqlite3-parser'.
error TypeError: result.ast is undefined ↓
cause Accessing result.ast in code written for pre-0.6.0 API.
fix
Use result.root instead of result.ast, and check result.status === 'ok' first.
error ParseError: unexpected token at position X ↓
cause Input SQL contains syntax errors or unsupported SQLite features.
fix
Check error message and location. Use parseStmt with allowTrailing to isolate problematic statements.
Warnings
breaking ESM-only since v0.7.0. Deep require('sqlite3-parser') will fail with ERR_REQUIRE_ESM. ↓
fix Use import syntax, or upgrade to Node >=14 and use dynamic import.
gotcha ParseDiagnostic is not a subclass of Error; catching 'instanceof Error' will not catch parse errors. ↓
fix Always check result.status === 'ok' before using result.root. Use parseOrThrow for exception-based flow.
gotcha parseStmt by default rejects trailing content (e.g., multiple semicolon-separated statements). This differs from parse which accepts multiple statements. ↓
fix Use parse for multi-statement scripts, or pass allowTrailing: true to parseStmt for incremental parsing.
breaking In v0.6.0, the return type changed from {ast} to {root} and added status field. Old code using result.ast will break. ↓
fix Access result.root instead of result.ast, and check result.status before accessing root.
Install
npm install sqlite3-parser yarn add sqlite3-parser pnpm add sqlite3-parser Imports
- parse wrong
const parse = require('sqlite3-parser').parsecorrectimport { parse } from 'sqlite3-parser' - parseStmt wrong
const { parseStmt } = require('sqlite3-parser')correctimport { parseStmt } from 'sqlite3-parser' - parseOrThrow
import { parseOrThrow } from 'sqlite3-parser' - type ParseOk wrong
import { ParseOk } from 'sqlite3-parser'correctimport type { ParseOk } from 'sqlite3-parser' - type ParseDiagnostic
import type { ParseDiagnostic } from 'sqlite3-parser'
Quickstart
import { parse, parseStmt, parseOrThrow } from 'sqlite3-parser';
// Parse multiple statements
const multi = parse(`SELECT * FROM t1; INSERT INTO t2 VALUES (1)`);
if (multi.status === 'ok') {
console.log(multi.root.cmds.length); // 2
console.log(multi.root.cmds[0].type); // SelectStmt
}
// Parse single statement
const single = parseStmt('SELECT id FROM users WHERE name = ?');
if (single.status === 'ok') {
console.log(single.root.type); // SelectStmt
}
// Parse or throw
const stmt = parseOrThrow('UPDATE t SET x = 1');
console.log(stmt.root.type); // CmdList (always contains one command)
// Incremental parsing with allowTrailing
const result = parseStmt('SELECT 1; SELECT 2', { allowTrailing: true });
if (result.status === 'ok') {
console.log(result.tail); // 9 (index where next statement starts)
}