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.

RuleSeverityDescription
noAnonymousOperationserrorRequire named operations
noDeprecatedwarnAlert on deprecated field usage
noDuplicateFieldswarnDisallow duplicate fields in selection sets
noHashtagDescriptionwarnDisallow # comments as type descriptions
noUnreachableTypeswarnDetect types unreachable from root operations
redundantFieldswarnDetect fields duplicated by fragment spreads
requireDeprecationReasonwarnRequire reason in @deprecated directives
uniqueEnumValueNameswarnDetect duplicate enum values across enums
noUnusedFragmentswarnDetect unused fragment definitions
noUnusedFieldswarnDetect unused schema fields

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

RuleDescription
alphabetizeEnforce alphabetical ordering
descriptionStyleEnforce block vs inline description style
inputNameRequire configurable suffix on input types
loneExecutableDefinitionRequire one operation or fragment per file
namingConventionEnforce naming conventions
noOnePlaceFragmentsDetect fragments used in only one place
noScalarResultTypeOnMutationRequire mutations to return object types
noTypenamePrefixDisallow field names prefixed with type name
operationNameSuffixEnforce operation name conventions
requireDescriptionRequire descriptions on type definitions
requireFieldOfTypeQueryInMutationResultRequire Query field in mutation results
selectionSetDepthLimit selection set nesting depth
strictIdInTypesRequire ID field in object types
uniqueNamesEnsure operation/fragment names are unique
noUnusedVariablesDetect unused query variables
matchDocumentFilenameDocument — Enforces that operation and fragment names match the filename
noRootTypeSchema — Disallows certain root type definitions in the schema
relayArgumentsSchema — Enforce Relay-compliant pagination arguments on connection fields
relayConnectionTypesSchema — Enforces Relay connection type conventions on types ending in ‘Connection’
relayEdgeTypesSchema — Enforces Relay-compliant edge type definitions
relayPageInfoSchema — Enforces that the PageInfo type follows the Relay specification
requireDeprecationDateSchema — Requires @deprecated directives to include a deletion date
requireImportFragmentDocument — Requires fragment spreads to have a corresponding import comment
requireNullableFieldsWithOneofSchema — Requires all fields in @oneOf input types to be nullable
requireNullableResultInRootSchema — Requires root type fields to return nullable types for error resilience
requireTypePatternWithOneofSchema — 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:

ContextScopeSpeedWhere it runs
Standalone DocumentSingle document, no schemaFastLSP + CLI
Document-SchemaSingle document + schemaFastLSP + CLI
Project-WideAll documents + schemaSlowCLI (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.