@sqltools/formatter
@sqltools/formatter is the dependency-free SQL pretty-printer extracted from the SQLTools VS Code extension. It tokenizes a query, normalizes whitespace and indentation, optionally changes reserved-word case, separates semicolon-delimited statements, and has keyword tables for generic SQL, DB2, Couchbase N1QL, and Oracle PL/SQL. It can also replace named or positional placeholders while formatting. It does not parse a database grammar, validate syntax, understand schemas, execute queries, or safely bind values.
A reasonable compatibility dependency when you specifically want SQLTools output or one of its four supported modes. For a new standalone formatter, sql-formatter has broader dialect coverage and a healthier release cadence; never use this package's params option as SQL binding.
Use it if
- You need the exact formatting behavior used by the SQLTools VS Code extension in another Node or browser tool
- Your inputs fit its four language modes: sql, db2, n1ql, or pl/sql
- You want a zero-dependency formatter with included TypeScript declarations and a tiny two-function surface
- You need raw token output for editor coloring or simple SQL inspection in addition to formatted text
- You need PostgreSQL, MySQL, BigQuery, Snowflake, SQLite, Trino, Redshift, Spark, or Transact-SQL as an explicit dialect: the Config type recognizes only sql, db2, n1ql, and pl/sql
- You need a parser that preserves semantics across vendor extensions: this is a regex tokenizer with reserved-word lists, so unknown or newly introduced syntax can be spaced or broken incorrectly
- You might use params as database binding: the formatter inserts provided values directly into text without quoting or escaping, making it unsafe for executable SQL
- You require current published maintenance: version 1.2.5 was released in October 2022 even though the surrounding vscode-sqltools monorepo remains active
- You want native ESM packaging: the npm package exposes one CommonJS main file with no module field or exports map
Setup reality
npm install @sqltools/formatter is the whole install. Version 1.2.5 has no runtime dependencies, peer dependencies, native code, credentials, database drivers, or configuration files, and declarations ship under lib. The package is CommonJS-only. TypeScript projects with esModuleInterop can follow the README's default import, while named imports for format and tokenize map directly to the declaration file; strict ESM runtimes may need CommonJS interop. The default language is sql, indentation is two spaces, reserved-word case is preserved, and one newline is inserted after a semicolon. Supported language strings are exactly sql, db2, n1ql, and pl/sql; an unknown string falls through to generic SQL at runtime even though TypeScript rejects it. The formatter is lexical, not an AST parser. Run representative stored procedures, JSON operators, quoted identifiers, dollar-quoted bodies, vendor comments, and new dialect features through tests before adopting it for automatic rewrites. The params option is particularly dangerous-looking: arrays replace ? placeholders in order and objects replace names after :, @, %, or $ where the selected tokenizer supports them, but values are concatenated directly. A string must already contain any SQL quotes, and no value should ever come from a user or be sent to a database after substitution. Use a driver parameter API for execution. linesBetweenQueries only acts at semicolon separators; preserve keeps existing multi-line whitespace after a semicolon. tokenize() always uses the generic Standard SQL tokenizer regardless of cfg.language, as the published source shows. Finally, the SQLTools repository is active but this standalone package has not been published since 2022, so pin the version and treat dialect gaps as yours to test or patch.
Patterns
Format a SQL statementformat-basic-query
import { format } from '@sqltools/formatter';
const output = format('SELECT id,name FROM users WHERE active=true');
console.log(output);Generic sql mode is used by default. Formatting changes whitespace only according to its tokenizer and does not validate the statement.
Use the README's default import formuse-default-import
import sqlFormatter from '@sqltools/formatter';
const output = sqlFormatter.format('SELECT * FROM products');The published file is CommonJS; this default import is easiest with esModuleInterop or bundler interop, while named imports match the declarations directly.
Indent with tabsset-indentation
const output = format(
'SELECT id, name FROM users WHERE id IN (SELECT user_id FROM admins)',
{ indent: '\t' },
);indent accepts any string, including tabs or four spaces; the default is two spaces.
Uppercase recognized reserved wordsuppercase-keywords
const output = format('select id from users where active = true', {
reservedWordCase: 'upper',
});Only tokens present in the selected language's reserved-word lists change case; identifiers and string contents are left alone.
Lowercase recognized reserved wordslowercase-keywords
const output = format('SELECT id FROM users ORDER BY id', {
reservedWordCase: 'lower',
});Omit reservedWordCase to preserve the query's original keyword case.
Use DB2 keyword and placeholder rulesformat-db2
const output = format(
'SELECT EMPNO, LASTNAME FROM EMPLOYEE FETCH FIRST 10 ROWS ONLY',
{ language: 'db2', reservedWordCase: 'upper' },
);DB2 mode has its own reserved words, -- comments, ? placeholders, and :name placeholders.
Format Couchbase N1QLformat-n1ql
const output = format(
'SELECT META(bucket).id FROM bucket WHERE type = $type',
{ language: 'n1ql' },
);N1QL mode recognizes square and curly collection delimiters and $name placeholders, unlike the other dialect modes.
Format Oracle PL/SQLformat-plsql
const output = format(
'BEGIN SELECT name INTO result FROM users WHERE id = :id; END;',
{ language: 'pl/sql', reservedWordCase: 'upper' },
);PL/SQL mode is based on fixed keyword and tokenizer tables; test packages, procedures, q-quoted strings, and vendor extensions before mass rewrites.
Set blank lines between statementsspace-multiple-queries
const output = format(
'SELECT 1; SELECT 2; SELECT 3;',
{ linesBetweenQueries: 2 },
);The setting counts newline characters inserted after each semicolon, so 2 produces one visually blank line between statements.
Keep existing multi-line gaps after semicolonspreserve-query-spacing
const source = 'SELECT 1;\n\n\nSELECT 2;';
const output = format(source, { linesBetweenQueries: 'preserve' });Preservation applies to consecutive line breaks immediately after a semicolon; other whitespace is still reformatted.
Replace named placeholders for displaypreview-parameter-values
const output = format(
'SELECT * FROM users WHERE id = :id AND role = :role',
{ params: { id: 42, role: "'admin'" } },
);Values are inserted raw without escaping. This is suitable only for trusted display fixtures, never database execution or user input.
Inspect lexical SQL tokenstokenize-sql
import { tokenize } from '@sqltools/formatter';
import { TokenTypes } from '@sqltools/formatter/lib/core/types';
const tokens = tokenize('SELECT * FROM users WHERE id = :id');
const placeholders = tokens.filter(token => token.type === TokenTypes.PLACEHOLDER);TokenTypes is declared in an internal core file and is not exported by the package entry, so import it from @sqltools/formatter/lib/core/types or compare token.type to 'placeholder'; tokenize() always uses generic SQL rules.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| sql-formatter | npm | Choose it for a maintained formatter with explicit support for many current SQL dialects and more configuration |
| prettier-plugin-sql | npm | Choose it when SQL formatting should participate in the same Prettier workflow as the rest of a repository |
| pg-formatter | npm | Choose it for PostgreSQL-focused formatting from a CLI or Node API |