Formatting GraphQL queries and SDL with graphql.js

Published: 2026-09-05

How graphql.js parse and print pretty-print or minify operations and SDL, what syntax validation covers (and what it does not), and a local browser workflow for review-ready GraphQL.

GraphQL documents show up everywhere: client queries in PRs, mutation snippets in tickets, and schema definition language (SDL) in .graphql files. Hand-edited operations often mix indentation, bury nested selections, or arrive as one long line from a network log. Formatting does not prove the query will succeed against your API—but it makes selection sets, arguments, and type definitions readable so reviewers can focus on shape and intent.

Online “paste GraphQL” formatters often upload document text to a server. Operations can include field names, argument values, and fragments that hint at product surface area. Prefer a local pass that never leaves the tab. LocalTools’ GraphQL formatter uses graphql.js parse, print, and stripIgnoredCharacters in the browser with the same local-only model as other tools on the site.

Operations vs SDL

graphql.js treats both as documents—a sequence of definitions that the parser can turn into an AST:

Document kind Typical contents When you format it
Executable query, mutation, subscription, fragments Client code reviews, debugging payloads from DevTools
Type system (SDL) type, interface, enum, input, schema, directives Schema PRs, federation stubs, local .graphql drafts

You can paste either shape (or a file that mixes definitions, if it is still valid GraphQL syntax). The formatter does not care whether you meant “operation” or “schema”—it only asks whether parse succeeds.

What parse → print actually does

Pretty-print is a parse → AST → print round-trip, not a whitespace-only rewrite:

  1. parse builds a DocumentNode (or throws a GraphQLError with line and column).
  2. print serializes the AST with graphql.js’s default layout (2-space indent).
  3. Optional re-indent expands that layout to 4 spaces when you ask for it.
  4. Minify parses, prints, then runs stripIgnoredCharacters so insignificant whitespace and comments that GraphQL ignores are removed from the string.

Because printing walks the AST, equivalent documents can look more consistent after formatting—even if the original spacing was chaotic. Exact original bytes (quirky blank lines, comment placement you hoped to keep) may not survive. That is usually desirable for review; it is a problem only if you needed a byte-identical transform.

For a similar “readable vs compact” tradeoff in another format, see minifying JSON safely and formatting SQL for reviews.

Pretty-print vs minify

Mode Goal Use when…
Pretty-print Indented, multi-line GraphQL (2- or 4-space indent) PR review, reading nested selection sets, documenting an operation in a ticket
Minify Compact text via stripIgnoredCharacters after a successful parse Embedding a document in a string, shrinking fixtures, reducing noise in a log line

Pretty-print for humans; minify for machines or constrained paste. Do not minify a schema PR just before review—you lose the layout reviewers need. If you must ship a compact string in app code, keep a pretty-printed copy in the PR or a .graphql fixture for humans.

Minifying is not the same as optimizing query cost or changing the selection set. It only removes characters the GraphQL grammar treats as ignorable (after a valid parse), not fields, arguments, or types.

Syntax validation is not schema validation

A green “valid syntax” result means graphql.js could parse the document. It does not mean:

  • Fields exist on your real schema
  • Argument types match what the server expects
  • Fragments spread on compatible types
  • The operation would execute successfully against a remote API

Those checks need a schema (and usually a validator or the server itself). The local formatter intentionally stays at document syntax—useful for catching missing braces, bad punctuation, and broken SDL before you paste into an editor or CI step that does full validation.

When you compare two versions of an operation after formatting both sides the same way, a local text diff highlights real structural edits instead of indent churn. See text diffs: unified view and workflow.

A practical workflow

  1. Paste the query, mutation, subscription, fragment set, or SDL as you would commit it (or as copied from DevTools / a gateway log).
  2. Choose 2-space or 4-space indent if you will pretty-print.
  3. Run Pretty-print for review layout or Minify for a compact string.
  4. Read errors with line and column from graphql.js when parse fails—fix the document before treating output as trustworthy.
  5. Diff against the previous version after formatting both sides consistently.
  6. Copy or download formatted.graphql. Scrub secrets and PII in argument values before sharing screenshots or pasting into chat.

What formatting will not catch

  • Schema / type errors — Unknown fields and wrong argument types still look neat if the grammar is fine.
  • Authorization and cost — A pretty selection set can still over-fetch or request sensitive fields.
  • Exact byte stability — Two printers (or indent settings) can emit equivalent but different text. Agree on one tool for review diffs.
  • Huge dumps — Very large schemas can stress the tab; format the document under review when possible.
  • Non-GraphQL wrappers — JSON bodies that contain a query string need the GraphQL document extracted first; formatting the outer JSON is a different job (JSON formatter).

Try it locally

Open the GraphQL formatter:

  1. Paste an operation (for example a query { … } block) or an SDL type definition document.
  2. Pick indent width, then click Pretty-print or Minify.
  3. Copy the result or download formatted.graphql.

graphql.js parse, print, and minify run in your browser; document text is not uploaded to LocalTools.

Related reading

All learn articles