sql-formatter-plus

A JavaScript library that pretty-prints Standard SQL, N1QL, DB2, and PL/SQL queries with configurable indentation and dialect-aware tokenization.

Library
npm
v1.3.6
94stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
32/100Needs Attention
Development Activity0
Maintenance0
Community48
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
73/100Good
Architecture78
Code Quality85
Innovation75
Learning Curve55

sql-formatter-plus is a fork of the original SQL Formatter library that reformats the whitespace in SQL queries so they’re readable, without altering the query’s semantics. It tokenizes the input string with a dialect-specific regex tokenizer, then walks the resulting tokens through a formatter that decides indentation, line breaks, and keyword casing based on token type (top-level reserved word, newline reserved word, opening/closing parenthesis, placeholder, comment, and so on).

Four dialects are supported out of the box — Standard SQL, Couchbase N1QL, IBM DB2, and Oracle PL/SQL — each implemented as its own class supplying dialect-specific reserved word lists to a shared Tokenizer/Formatter core. Beyond the upstream project, this fork adds an uppercase option to normalize keyword casing, a linesBetweenQueries option to control spacing between statements, and fixes for unicode handling, non-Unix line endings, and multi-statement indentation.

What You Get

  • A single format(query, cfg) entry point that accepts a dialect, indent string, uppercase flag, blank-line count, and named/indexed placeholder values
  • Dialect-aware tokenization that classifies reserved words, strings, comments, placeholders, and operators differently per SQL variant
  • Automatic inline-block collapsing so short expressions like COUNT(*) or DECIMAL(7,2) stay on one line instead of being split across indentation levels
  • Named (@foo, :foo) and indexed (?) placeholder substitution via a params config object
  • A prebuilt UMD bundle in dist/ for use directly in a <script> tag as window.sqlFormatter, alongside the CommonJS build for bundler-based projects

Common Use Cases

  • Pretty-printing raw SQL migration files before a code review so whitespace noise doesn’t obscure the actual schema change
  • Formatting N1QL queries in Couchbase-backed admin tools using the same API as Standard SQL formatting
  • Dropping the UMD build into a browser-based SQL editor or query-building tool with no bundler required
  • Normalizing dynamically constructed SQL before writing it to application logs so slow-query output stays readable

Under The Hood

Architecture Execution flows from src/sqlFormatter.js, which switches on cfg.language to select one of four dialect classes (StandardSqlFormatter, N1qlFormatter, Db2Formatter, PlSqlFormatter), each of which constructs a Tokenizer (src/core/Tokenizer.js) with its own reserved-word lists and hands the query to a shared Formatter (src/core/Formatter.js). The tokenizer turns the input into an ordered list of typed tokens (whitespace, comment, string, paren, placeholder, reserved word variants, operator), and the formatter walks that list maintaining two collaborator objects — Indentation (tracks top-level vs block-level indent depth as a stack) and InlineBlock (look-ahead bookkeeping that decides whether a parenthesized expression is short enough to stay on one line) — plus a Params helper for placeholder substitution. This is a clean, layered pipeline (tokenize -> classify -> emit) where the dialect classes are the only thing that would need to change to add a fifth SQL variant; the core tokenizer/formatter logic is dialect-agnostic and driven entirely by the reserved-word configuration passed in.

Tech Stack The library itself has a minimal runtime footprint, depending only on lodash (used narrowly for isEmpty, escapeRegExp, repeat, and last) and @babel/polyfill. The build pipeline compiles ES modules to CommonJS via Babel (@babel/preset-env plus babel-plugin-add-module-exports) for the lib/ output consumed by Node/bundler users, and bundles a browser-ready UMD file via Webpack for the dist/ output referenced directly from index.html. There is no runtime parser-generator dependency — dialect grammars are expressed as plain reserved-word arrays consumed by hand-written regexes.

Code Quality Testing is thorough for a library this size: a shared behavesLikeSqlFormatter.js helper (roughly 500 lines) defines a battery of formatting assertions that each dialect’s test file (StandardSqlFormatterTest.js, N1qlFormatterTest.js, Db2FormatterTest.js, PlSqlFormatterTest.js) runs against its own formatter instance, avoiding duplicated test logic across dialects. Jest is configured with coverage collection, and CI (Travis) runs npm run check — lint, Prettier format check, and tests — followed by a build step and a Coveralls upload. ESLint extends a shared config plus eslint-config-prettier, and every core class carries JSDoc comments describing its parameters. There’s no TypeScript, so type safety relies entirely on this test coverage and documentation rather than compile-time checks.

API Design The public surface is intentionally small: a single format(query, cfg) function with a flat configuration object (language, indent, uppercase, linesBetweenQueries, params) and sensible defaults for every option, so the common case (sqlFormatter.format('SELECT * FROM table1')) requires no configuration at all. The default export bundles the function under a { format } object matching common formatter-library conventions, and an unsupported language value throws an explicit, descriptive error rather than failing silently or producing malformed output.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search