Online GraphQL Query Prettifier, Indenter & Minifier
Paste any GraphQL query, mutation, subscription, fragment or schema to beautify or minify it instantly. A real GraphQL parser keeps your comments and never breaks strings. It points to the exact line of any syntax error and offers a fix. It also checks variables, fragments and aliases, and can export the result as a JSON body or cURL command.
GraphQL input paste a query, JSON body or schema
Formatted output Empty
Your formatted GraphQL appears here as you type.
Document checks no schema needed
- iPaste GraphQL to run the checks.
Query stats
Variables (JSON) optional
Quick answer: Paste your GraphQL into the box above and it is formatted as you type: one field per line, two-space indents, and long argument lists wrapped at 80 characters. That is the same layout Prettier and graphql-js produce. Switch to Minify to get the smallest valid version. Formatting only changes whitespace, commas and comments, which GraphQL ignores, so the server runs exactly the same operation and returns fields in the same order.
What Is a GraphQL Query Formatter?
A GraphQL query formatter takes a GraphQL document and rewrites its layout so it is easy to read: each field on its own line, nested fields indented, one space after every colon, and long lists of arguments or variables broken over several lines. The fields, arguments and values stay exactly the same. Only the spacing changes.
Many online formatters do this by counting { and } characters and adding a new line after each one. That works on simple queries but breaks on real ones. A brace inside a string such as search(text: "a{b}"), a # comment containing a bracket, or a multi-line """block string""" all get mangled. Some tools even join lines in a way that changes the query.
This tool works the way GraphQL servers do. It splits your text into tokens, following the lexical rules of the GraphQL specification. It then parses the tokens into a syntax tree and prints that tree again. Because it understands the document, it can:
- format queries, mutations, subscriptions, fragments and schema (SDL) files, including descriptions on operations and variables from the September 2025 spec;
- keep your # comments and the blank lines you use to group fields;
- wrap long arguments, variables and input objects at the width you choose, like Prettier does;
- show the exact line and column of a syntax error and suggest a one-click fix;
- run the document checks that don’t need a schema, such as unused variables, unknown fragments and conflicting aliases.
We checked the output against the reference implementation, graphql-js. For thousands of randomly edited queries, the tool accepted and rejected exactly the same documents, and every formatted or minified result parsed back to the same syntax tree as the original.
How to Format a GraphQL Query Online
- Paste your GraphQL into the input box, or click Open file for a
.graphqlor.gqlfile. You can also paste a full JSON request body, an escaped string from a log, a JavaScriptgql`…`template or a URL-encoded GET request. The tool extracts the query for you and says what it found. - Pick Beautify or Minify. Beautify is for reading, reviewing and committing. Minify is for URLs and payloads.
- Choose the indent and the wrap width. Two spaces and 80 characters match Prettier’s defaults, and so match most codebases. Choose 4 spaces or tabs if your style guide says so.
- Read the checks. A red status means a syntax error. The panel shows the line, a code excerpt with a caret under the problem and, where possible, a Fix button. Below the output, Document checks lists problems a server would reject even when the syntax is fine.
- Copy or export. Copy the query, download it, or copy it as a JSON body or cURL command, ready for Postman, Insomnia,
fetch()or a terminal.
Other ways to do the same thing: GraphiQL and most GraphQL IDEs have a Prettify button (Shift+Ctrl+P in GraphiQL). Prettier formats .graphql files and gql tags in JavaScript, which is best inside a project. In code, print(parse(query)) from graphql-js reprints a query, but it drops comments. Use this page when you need a quick, readable version without opening an editor.
GraphQL Query Beautifier vs. Minifier
Both produce the same operation. They make opposite trade-offs. The byte counts below are for the Query with variables example, a GitHub-style repository and issues query:
| Beautified (2 spaces) | Beautified (4 spaces) | Minified | |
|---|---|---|---|
| Size | 518 bytes | 692 bytes | 297 bytes (43% smaller) |
| After gzip | 281 bytes | 292 bytes | 227 bytes |
| URL-encoded for a GET request | 1,056 characters | 1,578 characters | 393 characters |
| Comments | Kept (with “Keep comments” on) | Removed. They are ignored by servers. | |
| Best for | Code review, docs, debugging, storing in Git | GET URLs, logs, payload limits, embedding in JSON | |
A safe minifier can’t just delete every space. name description needs its space, or it becomes a single field called namedescription, and two strings written side by side need one too. This minifier removes only what the grammar allows. It also drops commas, which GraphQL treats like whitespace, and turns block strings into ordinary one-line strings with the same value.
The gzip row shows why minifying POST requests usually isn’t worth the loss in readability: compression already removes most of the repeated whitespace. Minifying pays off for GET requests, where the query goes into the URL and many servers and CDNs cap URLs at about 8 KB, and for tools with strict payload limits. To cut bandwidth further, use persisted queries, which send a short hash instead of the query.
How to Format Minified GraphQL Queries
Minified GraphQL usually comes from one of four places. The tool handles each one when you paste it as-is:
- Browser DevTools. In the Network tab, the request payload is JSON such as
{"query":"query GetUser($id:ID!){…}","variables":{"id":"42"}}. Paste the whole thing. The query is formatted and the variables go into the Variables box. - Server logs. Logged queries are often escaped, with
\nand\"instead of real line breaks and quotes. The tool detects this and unescapes it. - JavaScript source. Paste
const Q = gql`…`and the template is unwrapped.${Fragment}interpolations are removed, and the tool tells you so, so you can paste those fragments too. - GET requests. A URL like
/graphql?query=%7B%20user…is decoded, including itsvariablesandoperationNameparameters.
The issues(…) arguments are broken over several lines because keeping them on one line would pass 80 characters. Set Wrap at to 120 or No wrap if you prefer long lines.
Formatting GraphQL Queries With Variables
Variables are declared after the operation name, each with a $, a type and an optional default: query Search($term: String!, $first: Int = 20). The formatter writes $name: Type = default with single spaces. When the declarations don’t fit on one line, it puts each one on its own line, which makes diffs much easier to read when a variable is added.
Variable values never go inside the query text. They are sent next to it as JSON in the variables field of the request. Paste them into the Variables (JSON) box and the tool compares them with the declarations of the selected operation:
- a required variable (
ID!,[String!]!) that has no default and no value; - values of the wrong built-in type.
Intmust be a whole number within the 32-bit range (±2,147,483,647),IDmust be a string or whole number,Booleanmust betrue/false, not"true"; - list coercion: a single value for a
[String]variable is allowed, because the server wraps it in a list; - keys in the JSON that the operation doesn’t declare, which many servers reject.
Build from query creates a starting JSON object from the declarations. The document checks also make sure that every $variable used in a field, including inside fragments, is declared by the operation, and that every declared variable is used. Both are errors in the GraphQL spec.
Avoid building queries by inserting values into the string, like `user(id: "${id}")`. It breaks caching and persisted-query hashes, and a quote in the value can change the query. Document checks points out named operations that have several hard-coded values.
Formatting GraphQL Mutations and Subscriptions
Mutations are formatted like queries. The part that benefits most is the input object. A long input: {…} is expanded into one key per line, with nested objects and lists indented further:
Two rules are worth knowing. Top-level mutation fields run one after another, in the order you write them, while query fields may run in parallel. The formatter never reorders fields, so that order is safe. And if you call the same mutation twice in one request, give each call an alias (first: addTag(…) second: addTag(…)), or the two fields conflict.
Subscriptions use the same syntax, with one extra rule: a subscription must select exactly one top-level field, and it can’t be an introspection field such as __typename. The checks flag a subscription with more than one root field, even when the extra field comes from a fragment. How the subscription is delivered (WebSocket with graphql-ws, server-sent events, or multipart HTTP) doesn’t affect formatting.
How to Format GraphQL Fragments and Nested Fields
Named fragments (fragment UserFields on User { … }) are printed as separate definitions with a blank line between them. Spreads (...UserFields) stay on their own line inside the selection. Inline fragments for unions and interfaces are written ... on Droid { primaryFunction }, or ... @include(if: $full) { … } when there is no type condition.
Formatting shows the depth of the query at a glance, and the stats panel measures it for you, including the fields brought in through fragments. That matters because many GraphQL servers enforce a depth limit (often between 7 and 15 levels) to block expensive queries. The checks warn above 7 levels.
The checks also catch the fragment mistakes a server rejects: a spread of a fragment that isn’t defined in the document, a fragment that is defined but never used, two fragments with the same name, and fragments that include each other in a loop (A spreads B, B spreads A). A file that contains only fragments, as codegen tools often use, is treated as a fragments file, and unused fragments aren’t reported.
Formatting GraphQL Aliases, Arguments, and Directives
Aliases rename a field in the response and are written alias: field: smallPic: profilePic(size: 64). You need them when you ask for the same field twice with different arguments. Without them, the server returns an error because both results would get the same key. The checks detect that conflict, and also two different fields sharing one alias, before you send the query.
Arguments are printed as name: value with a comma and space between them. When they don’t fit on the line, each argument gets its own line. Values follow GraphQL rules, which differ from JSON. Strings use double quotes, enum values such as DESC have no quotes, object keys have no quotes ({ field: CREATED_AT }), and there are no trailing commas or semicolons.
| Directive | Where it’s used | What the formatter checks |
|---|---|---|
@include(if: $flag) | Fields, fragment spreads, inline fragments | It has exactly one if argument, isn’t repeated, and isn’t on an operation or fragment definition. It also warns when the value is a constant true/false. |
@skip(if: $flag) | Same as @include, with the opposite effect | The same checks as @include. |
@defer / @stream | Incremental delivery (Apollo, GraphQL Yoga and others) | Formatted like any directive. Support depends on your server. |
@client, @connection | Apollo Client local fields and cache keys | Formatted and kept. They are stripped before the request reaches the server. |
@deprecated(reason: "…"), @oneOf | Schema (SDL) definitions | Formatted in the schema layout. @oneOf became part of the spec in September 2025. |
How to Fix Common GraphQL Formatting Errors
A formatter can only format a document it can parse, so syntax errors show first. These are the messages you’ll see most often. They use the same wording as graphql-js, the parser behind most JavaScript GraphQL servers, so they match what many servers return. Many have a Fix button:
| Error message | Usual cause | Fix |
|---|---|---|
Expected Name, found <EOF>. | A }, ) or ] is missing at the end, often from an incomplete copy. | The panel lists the missing characters. Fix adds them. |
Unexpected "}". | One closing brace too many. | Fix removes the extra brace at the reported position. |
Unexpected single quote character (') | Single-quoted strings copied from JavaScript. | GraphQL only accepts "double quotes". Fix converts them. |
Unexpected character: U+201C (“) | Smart quotes from a document or chat app. | Fix replaces them with straight quotes. |
Expected Name, found String "name". | JSON-style quoted keys in an input object: {"name": "x"}. | Remove the quotes around the keys: {name: "x"}. Fix does this. |
Expected ":", found "=". | user(id = 1) instead of user(id: 1). | Arguments use a colon. = is only for variable defaults. |
Expected Name, found "}". | An empty selection set: user { }. | Add at least one field, or remove the braces for a scalar field. |
Expected "$", found Name "id". | A variable declared without $: query Q(id: ID!). | Write ($id: ID!). |
Unterminated string. | A missing closing quote, or a line break inside "…". | Close the string, or use a """block string""" for multi-line text. |
Invalid number, unexpected digit after 0 | A leading zero such as 007, often a zip code or ID. | Send it as a string: "007". |
Unexpected variable "$x" in constant value. | A variable used as a default value or in a schema. | Defaults must be literal values. |
Unexpected character: "\" or ";" | An escaped query from a log, or a semicolon from code. | Paste the whole JSON body, or use Fix to unescape or remove them. |
Click the line number in the error panel to jump to the problem in the input. After a fix, the formatted result appears straight away. If the fix wasn’t what you wanted, undo it with Ctrl+Z in the input box.
GraphQL Formatting vs. Schema Validation
A GraphQL document can be wrong in three different ways, and it helps to know which checks catch which:
| Level | Examples | Checked here? |
|---|---|---|
| 1. Syntax | Missing braces, bad quotes, a = instead of :, invalid numbers | Yes, by the parser, with line and column |
| 2. Document rules (no schema) | Duplicate operation, fragment or argument names. A lone anonymous operation. Undefined or unused variables and fragments. Fragment cycles. Aliases that conflict. Subscriptions with several root fields. Misused @skip/@include. | Yes, in Document checks |
| 3. Schema rules | The field or type exists. Argument types and required arguments. Scalar fields must not have a selection set, object fields must have one. A fragment type is possible at that position. A variable’s type fits where it is used. | No. These need your API’s schema. |
A green status therefore means the query is well formed and internally consistent. It doesn’t mean your server has a user field. For level 3, run the query in GraphiQL or Apollo Sandbox against your endpoint, which load the schema by introspection, or validate in code:
Schema files (SDL) are formatted too, but the tool doesn’t check whether the types they reference exist. It warns if you mix schema definitions and operations in one document, because servers reject that in a request.
Does Formatting Change a GraphQL Query?
Not its meaning. The GraphQL spec lists spaces, tabs, line breaks, commas, comments and the byte-order mark as ignored tokens. They exist only to make documents readable. A formatted query and a minified query give the same syntax tree, and therefore the same result. Response keys also come back in the order the fields were written, and neither mode reorders fields, so your JSON output looks the same too.
Block strings stay safe as well. The value of a """block string""" ignores the indentation shared by its lines, so re-indenting it as part of a nested argument keeps its value. Where moving the text would change it (for example when a value starts with spaces), the formatter keeps it on one line.
What does change is the text, and a few systems compare text rather than meaning:
- Automatic persisted queries (APQ) identify a query by the SHA-256 hash of its exact string. Reformatting creates a new hash. The client then gets
PERSISTED_QUERY_NOT_FOUNDonce and re-registers the query. That costs one extra round trip, but nothing breaks. - Trusted documents and operation safelists only allow queries that were registered ahead of time. Format the query before you generate the manifest, not after, or the server will refuse it.
- Cache keys for GET requests are usually the full URL, so the same query written two ways is cached twice.
- Comments disappear in minified output. If a comment explains something important, keep the beautified version in your repository.
Apollo Client and similar libraries parse gql documents and print them again before sending. So the whitespace in your source code usually never reaches the server anyway.
GraphQL Query Formatter FAQs
What does a GraphQL query formatter do?
It reads your GraphQL document with a real parser and prints it again with consistent indentation, one field per line, spaces after colons and long argument lists wrapped. This formatter also minifies, checks for syntax and document errors, and keeps your # comments.
Does formatting change what my GraphQL query returns?
No. Whitespace, line breaks, commas and comments are "ignored tokens" in the GraphQL spec, so the server sees the same operation. Field order is never changed, so the JSON response keeps the same key order. The only thing that changes is the text itself, which matters if you use persisted queries or query hashes.
How do I format a minified GraphQL query?
Paste it into the input box. It is formatted instantly. You can also paste the whole JSON request body from your browser’s Network tab, an escaped query from a log, a gql`…` template from JavaScript or a URL-encoded GET request, and the tool extracts the query and variables for you.
Should I minify GraphQL queries in production?
It helps most for GET requests, where the query goes into the URL, and for large documents. For normal POST requests with gzip, the saving is small: our 518-byte example shrank to 297 bytes, but only from 281 to 227 bytes after gzip. Persisted queries save far more, because only a hash is sent.
Does this tool validate my query against a schema?
No. It checks syntax and the GraphQL rules that don’t need a schema: unique names, defined and used variables and fragments, fragment cycles, duplicate arguments, conflicting aliases, single-field subscriptions and @skip/@include usage. Whether a field or type exists can only be checked against your API’s schema, for example in GraphiQL.
Can it format GraphQL schema (SDL) files?
Yes. It formats type, interface, union, enum, input, scalar, schema and directive definitions, including extend and descriptions, with the same layout as Prettier.
Why is my output showing "Expected Name, found <EOF>"?
The query ended before every brace or bracket was closed. The error panel shows exactly which closing characters are missing, and the Fix button adds them for you.
Are my comments kept?
Yes, when you beautify with "Keep comments" on. Comments stay above the line they describe, and comments at the end of a line stay there. Minified output always drops comments, because they are not part of the query.
Is my query sent to a server?
No. Parsing, formatting and checking all run in your browser. Nothing you paste is uploaded. Your last query and variables are saved only in your own browser.
Resources and Sources
- GraphQL Specification (September 2025)The official grammar, including ignored tokens, descriptions on operations and validation rules.
- GraphQL.org: QueriesOfficial guide to fields, arguments, aliases, fragments, variables and directives.
- GraphQL.org: ValidationHow servers check operations against the schema before running them.
- graphql-js utilitiesReference docs for
stripIgnoredCharacters, the reference minifier. - PrettierThe code formatter whose GraphQL layout this tool follows.
- Apollo: Automatic persisted queriesWhy query hashes depend on the exact query text.
- GraphiQL on GitHubThe official GraphQL IDE, for running and validating queries against a schema.
- Spec: Ignored tokensWhy whitespace, commas and comments don’t change a document’s meaning.
Related Tools
Last reviewed: September 2026.