BytePane

SQL Formatter: Beautify SQL Queries Online Free

SQL15 min read

Key Takeaways

  • The sql-formatter npm package receives 2.27 million downloads per week (April 2026) and supports 19 SQL dialects including BigQuery, Snowflake, and DuckDB.
  • SQL formatting does not affect query execution plans — all major databases strip whitespace before optimization. Formatting is purely a developer experience investment.
  • The keyword case debate (UPPERCASE vs lowercase) is splitting along ecosystem lines: traditional DBAs favor UPPERCASE, while the dbt data engineering ecosystem is standardizing on lowercase.
  • SQLFluff (9,632 GitHub stars) is the only tool that combines linting + formatting — it catches semantic issues a pure formatter cannot, including unqualified column references and inconsistent alias patterns.
  • Per the Stack Overflow Developer Survey 2024, 51% of developers use SQL — 4th most-used language overall, making SQL formatting tooling high-impact infrastructure.

The SQL Formatting Problem in Production Codebases

Imagine onboarding to a data engineering codebase. The first file you open contains something like this:

Real production SQL (anonymized, genuinely found in the wild)
SELECT u.id,u.email,COUNT(o.id) as orders,
SUM(o.total) AS revenue ,
  AVG(o.total) as avg_order
FROM users u JOIN orders o ON u.id=o.user_id
where u.created_at >= '2024-01-01'
AND o.status='completed'
GROUP BY u.id ,u.email
ORDER BY revenue DESC LIMIT 100

Mixed keyword casing (SELECT uppercase, where lowercase), no consistent indentation, multiple columns per line, spaces before commas. This is not a strawman — it is a common state in repositories where no SQL formatter is enforced. Every developer who has touched this file left their personal formatting style.

Code review becomes noise instead of signal. Reviewers spend cognitive load parsing the formatting before they can evaluate the query logic. Git diffs show every whitespace change as meaningful. New team members cannot follow the existing conventions because there are none.

According to the Stack Overflow Developer Survey 2024 (65,000+ respondents), SQL is used by 51% of developers — the 4th most-used language after JavaScript, HTML/CSS, and Python, and second only to JavaScript among professional developers. PostgreSQL is used by 48.7% of pro developers, MySQL by 40.3%, and SQL Server by 25.3%. This is pervasive infrastructure. Formatting standards matter at scale.

How SQL Formatters Work: Tokenization and AST Reconstruction

Unlike HTML, SQL whitespace has no semantic significance — a formatter can add or remove any whitespace without changing query semantics. This makes SQL formatting conceptually simpler than HTML formatting. The challenge is dialect fragmentation: MySQL, PostgreSQL, T-SQL, BigQuery, Snowflake, and DuckDB all have non-trivial syntax differences, and a formatter that does not understand the target dialect will misparse operator precedence, function names, and reserved word lists.

A SQL formatter operates in three passes:

  1. Tokenization: The input string is split into a stream of tokens — keywords, identifiers, operators, string literals, comments, and whitespace. Dialect-specific keywords are recognized based on the selected dialect configuration.
  2. Token classification: Each token is classified by type and position within the SQL grammar (e.g., "this SELECT is the start of a subquery", "this comma separates column references in a SELECT list vs. a function argument list"). This is where dialect differences create complexity — BigQuery uses backtick quoting, PostgreSQL uses double-quote identifiers, T-SQL uses bracket identifiers.
  3. Serialization: Tokens are emitted with normalized whitespace, keyword casing, and indentation according to the formatter's configuration. Line breaks are inserted before major clauses (FROM, WHERE, JOIN, GROUP BY, ORDER BY) and continuation indentation is applied for multi-line expressions.

The output of a well-configured formatter on the messy query above should look like:

After: sql-formatter with PostgreSQL dialect, lowercase keywords
select
  u.id,
  u.email,
  count(o.id) as orders,
  sum(o.total) as revenue,
  avg(o.total) as avg_order
from users u
join orders o
  on u.id = o.user_id
where
  u.created_at >= '2024-01-01'
  and o.status = 'completed'
group by u.id, u.email
order by revenue desc
limit 100

sql-formatter npm: 2.27M Weekly Downloads, 19 Dialects

The sql-formatter npm package (GitHub: sql-formatter-org/sql-formatter, 2,836 stars, 445 forks) is the most widely used JavaScript SQL formatting library. It received 2,273,938 downloads in the week of March 31–April 6, 2026 — roughly 26.8 million downloads in the first 13 weeks of 2026.

The library is currently in maintenance mode — bug fixes only, no new features planned. This is actually appropriate for a formatting library: the API is stable, the dialect support is complete, and aggressive feature development often introduces regressions in edge cases.

Supported dialects: BigQuery, ClickHouse, IBM DB2, DuckDB, Apache Hive, MariaDB, MySQL, TiDB, Couchbase N1QL, Oracle PL/SQL, PostgreSQL, Amazon Redshift, SingleStoreDB, Snowflake, Spark, SQL Server (T-SQL), Trino/Presto, and ANSI SQL.

Programmatic usage (Node.js)
import { format } from 'sql-formatter';

const result = format(
  'SELECT id,name FROM users WHERE active=1',
  {
    language: 'postgresql',
    tabWidth: 2,
    keywordCase: 'lower',     // or 'upper'
    indentStyle: 'standard',  // or 'tabularLeft', 'tabularRight'
    logicalOperatorNewline: 'before', // AND/OR on new line
    expressionWidth: 50,      // max inline expression width
  }
);

console.log(result);
// select
//   id,
//   name
// from users
// where active = 1

The indentStyle: 'tabularLeft' option produces "river style" formatting (right-aligned keywords) as advocated by Simon Holywell's SQL style guide. The standard style is what most teams and style guides use today.

BytePane's SQL Formatter is built on top of sql-formatter and runs entirely in your browser — no SQL data is transmitted to a server. You can verify this in Chrome DevTools Network panel.

SQL Style Guides: What Major Organizations Actually Use

SQL lacks a governing style authority like Python's PEP 8 or Google's language-specific guides. The result is genuine fragmentation across six widely-referenced style guides — and the fragmentation is not just aesthetic. The keyword case debate tracks real ecosystem splits between traditional database administration culture and modern data engineering culture.

Organization / GuideKeywordsCommasIndentLine Max
Simon Holywell (sqlstyle.guide)UPPERCASETrailingRiver-aligned
dbt LabslowercaseTrailing4 spaces80 chars
Matt MazurlowercaseTrailing4 spaces
GitLablowercaseTrailing4 spaces80 chars
Kickstarter (Benenson)UPPERCASETrailing2 spaces
Mozilla TelemetryUPPERCASETrailingStandard

Two observations from this table are worth internalizing:

Trailing commas are universal. Every style guide in this table uses trailing commas. The minority "leading comma" preference (where commas start the next line) is sometimes found on individual teams but has no official backing from any major organization. If your team debates this, trailing commas win on precedent.

Keyword case tracks ecosystem, not correctness. The UPPERCASE vs lowercase split is real and persistent. UPPERCASE is traditional DBA culture — SQL Server, Oracle shops, database certification materials. Lowercase is modern data engineering culture — dbt, Airflow, BigQuery, Snowflake analytics pipelines. There is no technical argument for either; SQL parsers are case-insensitive. Pick the standard that matches your team's ecosystem and enforce it consistently.

For more depth on style guide comparison and tool selection, our earlier SQL Formatter Online guide covers pgFormatter, SQLFluff, and VS Code setup in detail.

SQLFluff: The Difference Between Formatting and Linting

SQLFluff (9,632 GitHub stars, 973 forks) is categorically different from sql-formatter. While sql-formatter normalizes whitespace and keyword casing, SQLFluff detects semantic problems that formatting cannot address:

  • Unqualified column references in JOINs: SELECT id FROM users JOIN orders ON ... — which table does id come from? SQLFluff flags this.
  • Inconsistent alias styles: Some places using AS, others without. SQLFluff enforces the aliasing.expression rule consistently.
  • Implicit type conversions: Operations that will silently coerce types at runtime but will not fail at parse time.
  • Deprecated syntax: != vs <>, USING clauses in Snowflake (which produce inaccurate results per GitLab's style guide).

SQLFluff v4.0 introduced an optional Rust parser (pip install sqlfluff[rs]) for significant performance improvements on large SQL files. Version 4.1 added support for dbt 1.10 and extended BigQuery dialect coverage.

.sqlfluff (project root)
[sqlfluff]
dialect = postgres
templater = dbt          # use 'jinja' if not a dbt project
indent_unit = space
tab_space_size = 4
max_line_length = 80

[sqlfluff:rules:capitalisation.keywords]
capitalisation_policy = lower   # or 'upper'

[sqlfluff:rules:aliasing.expression]
aliasing = explicit              # always require AS keyword

[sqlfluff:rules:references.qualification]
force_enable = True              # qualify all column refs in JOINs

The dbt integration is SQLFluff's strongest differentiator. The sqlfluff-templater-dbt package resolves Jinja macros and {{ ref() }} calls before linting, so SQLFluff can lint the fully-rendered SQL rather than the template source. Without this, any model referencing {{ ref('dim_users') }} would produce false-positive parse errors.

Dialect-Specific Formatting: Snowflake, BigQuery, PostgreSQL

Cloud-native SQL platforms have their own formatting conventions layered on top of general SQL standards. These are not just aesthetic preferences — some are correctness requirements:

Snowflake

  • Never use USING in JOINs — GitLab's data team documented that USING produces inaccurate results in Snowflake due to how it handles case-insensitive column matching. Always use explicit ON conditions.
  • Canonical type names: Use NUMBER not DECIMAL/NUMERIC/INTEGER/BIGINT; FLOAT not DOUBLE/REAL; VARCHAR not STRING/TEXT.
  • Prefer UNION ALL over UNIONUNION implies deduplication; using it accidentally masks data integrity issues and is more expensive.

PostgreSQL

  • Double-quote identifiers for mixed-case or reserved-word column names: SELECT "userId" FROM .... PostgreSQL lowercases all unquoted identifiers, so userId and userid are the same — a frequent source of bugs for developers coming from MySQL or SQL Server.
  • pgFormatter (1,920 GitHub stars, Perl-based) produces highest-quality output for PostgreSQL-specific syntax including JSONB operators, window functions, CTEs with RECURSIVE, and PostgreSQL extensions. Use it for PostgreSQL-specific code; use sql-formatter for polyglot environments.

BigQuery

  • Backtick quoting for project.dataset.table references: `project.dataset.table`. Formatters must not strip or replace backticks with double-quotes in BigQuery dialect mode.
  • Standard SQL vs Legacy SQL: BigQuery supports both; standard SQL is preferred and default as of 2016. A formatter configured for BigQuery standard SQL will reject Legacy SQL syntax like TABLE_DATE_RANGE functions.

Automating SQL Formatting in CI/CD

For pure formatting enforcement (no linting), the simplest approach is a pre-commit hook using sqlfluff fix to auto-correct violations. For linting enforcement, sqlfluff lint in CI blocks merges on any violation.

.pre-commit-config.yaml
repos:
  - repo: https://github.com/sqlfluff/sqlfluff
    rev: 4.1.0
    hooks:
      # Auto-fix formatting violations on commit
      - id: sqlfluff-fix
        args: [--dialect, postgres]
      # Block commits with unfixable lint violations
      - id: sqlfluff-lint
        args: [--dialect, postgres]
GitHub Actions: .github/workflows/sql-lint.yml
name: SQL Lint

on: [push, pull_request]

jobs:
  sql-lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install SQLFluff
        run: pip install sqlfluff[rs]==4.1.0

      - name: Lint SQL files
        run: sqlfluff lint --dialect postgres models/

For dbt projects, add sqlfluff-templater-dbt to the installation and set templater = dbt in .sqlfluff. This resolves all {{ ref() }} and macro calls before linting so you get accurate results on the compiled SQL.

The same principle that applies to HTML formatting CI applies here: pre-commit hooks can be bypassed with --no-verify. GitHub Actions as a required PR check cannot be bypassed and should be your enforcement mechanism.

Does SQL Formatting Affect Query Performance?

No. This is worth stating emphatically because the question comes up often from developers who notice that production systems sometimes run formatted and minified SQL differently — and attribute the difference to formatting.

Every major SQL database engine — PostgreSQL, MySQL, SQL Server, BigQuery, Snowflake, Oracle, DuckDB — parses SQL and strips all whitespace (spaces, tabs, newlines) before building a logical query plan. The query optimizer receives a normalized token stream, not the original SQL text. Execution plans are determined by:

  • Query logic: JOIN types, filter predicates, aggregation groupings
  • Table and column statistics: row counts, histogram distribution, null ratios
  • Available indexes: B-tree, hash, GiST, GIN (PostgreSQL), columnstore (SQL Server)
  • Query hints and optimizer directives: /*+ PARALLEL */, OPTION (RECOMPILE)
  • Session settings: work_mem, enable_seqscan, SET NOCOUNT ON

Keyword case does not matter either: SELECT and select and SeLeCt compile to identical bytecode. Any performance difference you observe between formatted and unformatted SQL is caused by something else — different query logic, different parameter values, plan cache hits/misses, or measurement methodology.

For learning SQL concepts and joining patterns referenced in this article, our SQL Joins Explained guide covers INNER, LEFT, RIGHT, FULL OUTER, and CROSS JOINs with visual examples.

Frequently Asked Questions

Does SQL formatting affect query performance?

No. SQL formatting is purely cosmetic. All major database engines (PostgreSQL, MySQL, SQL Server, BigQuery, Snowflake) parse SQL and strip all whitespace before building execution plans. Execution plans are determined by query logic, table statistics, and available indexes — not indentation, keyword case, or line breaks. A minified single-line query and a beautifully formatted multi-line one produce identical execution plans.

Should SQL keywords be uppercase or lowercase?

No universal standard. UPPERCASE is the traditional convention in DBA culture and SQL Server/Oracle environments. Lowercase is the standard for the dbt data engineering ecosystem (Snowflake, BigQuery, Redshift analytics workloads). Both Simon Holywell's sqlstyle.guide (UPPERCASE) and dbt's official style guide (lowercase) are widely cited. Pick one and enforce it via SQLFluff — mixing styles is the only clearly wrong answer.

What SQL dialects does sql-formatter npm support?

The sql-formatter npm package (2.27M weekly downloads as of April 2026) supports 19 dialects: BigQuery, ClickHouse, IBM DB2, DuckDB, Apache Hive, MariaDB, MySQL, TiDB, Couchbase N1QL, Oracle PL/SQL, PostgreSQL, Amazon Redshift, SingleStoreDB, Snowflake, Spark, SQL Server (T-SQL), Trino/Presto, and standard ANSI SQL. Specify the target dialect via the language option to get dialect-accurate keyword handling.

What is SQLFluff and how is it different from sql-formatter?

sql-formatter normalizes whitespace and keyword casing — it is a pure formatter. SQLFluff (9,632 GitHub stars) is both a linter and formatter. It detects semantic violations: unqualified column references in JOINs, inconsistent alias styles, deprecated syntax, and implicit type conversions. It supports 30+ dialects, integrates with dbt Jinja templating via sqlfluff-templater-dbt, and is the enforcement tool recommended by dbt Labs.

What is the difference between leading and trailing commas in SQL?

Trailing commas end each line (col1,\ncol2,\ncol3). Leading commas start each line after the first (col1,\n, col2,\n, col3). Every major style guide (dbt, GitLab, Mozilla, Mazur, Holywell) uses trailing commas — they are the overwhelming majority convention. Leading commas make missing commas visually obvious but produce unusual-looking code. Both are syntactically valid in all SQL dialects.

How do I format SQL in VS Code?

Install the 'SQL Formatter' extension by sql-formatter-org. Open a .sql file, press Shift+Alt+F (Windows/Linux) or Shift+Option+F (Mac). Configure your dialect in settings.json under 'sql-formatter.dialect'. For dbt projects, use the dbt Power User extension which includes SQLFluff integration. For SQL embedded in JavaScript template literals, prettier-plugin-sql applies formatting automatically.

How do I set up SQL formatting in a CI/CD pipeline?

Use SQLFluff with pre-commit hooks: add sqlfluff-fix to auto-correct formatting on commit, and sqlfluff-lint to block commits with unfixable violations. In GitHub Actions, run 'sqlfluff lint --dialect postgres models/' as a required PR check. Pair local hooks with server-side CI enforcement — developers can bypass hooks with --no-verify, but required CI checks cannot be bypassed.

Format SQL Queries Instantly — Free, No Sign-Up

Paste your SQL and get clean, consistently-formatted output. Supports MySQL, PostgreSQL, T-SQL, BigQuery, Snowflake, and 15+ more dialects. Runs entirely in your browser.

Open SQL Formatter →