Skip to content

Linting Overview

GraphQL Analyzer includes a configurable linting engine with rules for common GraphQL best practices.

Add to your .graphqlrc.yml:

extensions:
graphql-analyzer:
lint: recommended

The recommended preset enables rules that are objectively beneficial without being opinionated about architecture choices.

Rule Severity Description
noAnonymousOperations error Require named operations
noDeprecated warn Alert on deprecated field usage
noDuplicateFields warn Disallow duplicate fields in selection sets
noHashtagDescription warn Disallow # comments as type descriptions
noUnreachableTypes warn Detect types unreachable from root operations
redundantFields warn Detect fields duplicated by fragment spreads
requireDeprecationReason warn Require reason in @deprecated directives
uniqueEnumValueNames warn Detect duplicate enum values across enums
noUnusedFragments warn Detect unused fragment definitions
noUnusedFields warn Detect unused schema fields

These rules are available but not in the recommended preset — enable them based on your project’s needs:

Rule Description
alphabetize Enforce alphabetical ordering
descriptionStyle Enforce block vs inline description style
inputName Require configurable suffix on input types
loneExecutableDefinition Require one operation or fragment per file
namingConvention Enforce naming conventions
noOnePlaceFragments Detect fragments used in only one place
noScalarResultTypeOnMutation Require mutations to return object types
noTypenamePrefix Disallow field names prefixed with type name
operationNameSuffix Enforce operation name conventions
requireDescription Require descriptions on type definitions
requireFieldOfTypeQueryInMutationResult Require Query field in mutation results
selectionSetDepth Limit selection set nesting depth
strictIdInTypes Require ID field in object types
uniqueNames Ensure operation/fragment names are unique
noUnusedVariables Detect unused query variables
matchDocumentFilename Document — Enforces that operation and fragment names match the filename
noRootType Schema — Disallows certain root type definitions in the schema
relayArguments Schema — Enforce Relay-compliant pagination arguments on connection fields
relayConnectionTypes Schema — Enforces Relay connection type conventions on types ending in ‘Connection’
relayEdgeTypes Schema — Enforces Relay-compliant edge type definitions
relayPageInfo Schema — Enforces that the PageInfo type follows the Relay specification
requireDeprecationDate Schema — Requires @deprecated directives to include a deletion date
requireImportFragment Document — Requires fragment spreads to have a corresponding import comment
requireNullableFieldsWithOneof Schema — Requires all fields in @oneOf input types to be nullable
requireNullableResultInRoot Schema — Requires root type fields to return nullable types for error resilience
requireTypePatternWithOneof Schema — Enforces that types with @oneOf directive contain both ‘ok’ and ‘error’ fields

See the Rules Catalog for details on each rule.

If your project already uses ESLint, you can run the same rules through the @graphql-analyzer/eslint-plugin — a drop-in replacement for @graphql-eslint/eslint-plugin. Configuration lives in the same .graphqlrc.yaml, so your editor, CI, and ESLint all see an identical ruleset.

Rules run in different contexts depending on how much information they need:

Context Scope Speed Where it runs
Standalone Document Single document, no schema Fast LSP + CLI
Document-Schema Single document + schema Fast LSP + CLI
Project-Wide All documents + schema Slow CLI (by default)

Project-wide rules can be slow on large projects. If you experience latency in the editor, disable them in config and enable them in CI via graphql check --rule noUnusedFields=error.