# eslint-plugin-graphql: catching bad query strings in the editor, with a deprecation notice attached

> eslint-plugin-graphql validates tagged GraphQL query strings in JavaScript and .graphql files against a schema, with built-in settings for Apollo, Relay, Lokka and FraQL. Apollo has said it is working towards fully deprecating the repository in favour of the community-maintained graphql-eslint, and support here will be minimal.

**apollographql/eslint-plugin-graphql** — :vertical_traffic_light: Check your GraphQL query strings against a schema.

- Repository: https://github.com/apollographql/eslint-plugin-graphql
- Website: https://www.npmjs.com/package/eslint-plugin-graphql
- Stars: 1,215 · Forks: 92
- Language: JavaScript
- License: not declared
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/apollographql-eslint-plugin-graphql

## The README opens with a deprecation warning dated 2022-01-25

Before this project describes a single rule, it tells you it is on the way out. A note dated 2022-01-25 says Apollo is working towards fully deprecating the repository, and suggests migrating to the community-supported graphql-eslint. It adds that detailed migration documentation will follow when the deprecation is official, and it says in plain terms that if you are planning to adopt anything here for a new project you still can, but support for this project will be minimal. That is the single most decision-relevant fact about the package, and it sits above the installation command. The rest of the project still describes a coherent tool: an ESLint plugin that checks tagged query strings inside JavaScript, or queries inside.graphql files, against a GraphQL schema. The repository is not archived and the last push was on 2026-10-16, so the code still moves, but the intent stated by the owner is one of wind down rather than of expansion.

## The mechanism is a tagged template literal plus a schema, checked at lint time

The plugin looks for a template literal tag in your source and parses whatever is inside it as a GraphQL document, then validates that document against a schema. The tag name is configurable, and it defaults per client environment: 'relay' gives Relay.QL, 'internal' is a special automatic value, and everything else defaults to 'gql' or 'graphql'. The schema is what makes the check meaningful, and it can arrive four ways. schemaJson takes your schema as JSON, schemaString takes it in the Schema Language format as a string, schemaJsonFilepath points at an absolute path to a .json file, and a .graphqlconfig file can be used instead of all three, with projectName selecting one project when the config declares several. The first three require your ESLint config to be a JS file, since the plugin has to read the schema at config load time. Once the schema and the tag are set, the rule name in the example configuration is graphql/template-strings.

## Client presets exist because Apollo, Relay, Lokka and FraQL parse the same syntax differently

The env option accepts 'apollo', 'relay', 'lokka', 'fraql' and 'literal', and defaults to 'apollo'. The documentation gives the reason: the option handles the slight parsing differences in GraphQL syntax between those clients, and it also provides sensible defaults for other options. The built-in settings cover four clients, the Apollo client, Relay, Lokka and FraQL. This is a real design constraint rather than decoration. GraphQL documents are conventionally written as tagged template literals, and a tagged literal can contain interpolation, so a linter that treated every template literal as a query would break on ordinary code. Restricting the check to a named tag is how the plugin stays out of the way, and the per-client tag defaults are what let the same rule work across a codebase that mixes Apollo and Relay.

## Clients without a tag need fake-tag, and the plugin waits for GraphQL comment support

The plugin relies on GraphQL queries being prefixed with a special tag, which the documentation says is often done in Relay and Apollo but not in some other clients that take query strings without a tag. The documented workaround is the fake-tag package, an identity tag that does nothing except tell the linter that the string is a GraphQL query. The example imports it and wraps the query in it, so the linter recognises a document that would otherwise be invisible. The README is candid about the long term answer here, noting that fake tags will not be necessary once GraphQL comment tags are supported, and linking an issue in this repository for that feature. That is a fair signal about the shape of the plugin: it is built around a syntactic convention, and the convention is a workaround until the tooling catches up.

## Installing the plugin and wiring up the Apollo preset in .eslintrc.js

The install is a single npm command, and the configuration is a rules block in your ESLint config file. The schema is required for the rule to work at all, and the example shows the three mutually exclusive ways of supplying it, with the comment reminding you that the filepath variant does not work with eslint --cache. The plugin is registered in the plugins array as 'graphql', and the parser is set to babel-eslint in the example. The comment about tagName is worth reading carefully, because it is the difference between a rule that fires and a rule that never matches anything. Below is the Apollo example as the documentation writes it, trimmed to the parts that matter for a first run.

```bash
npm install eslint-plugin-graphql
```

```js
module.exports = {
  parser: "babel-eslint",
  rules: {
    "graphql/template-strings": ['error', {
      env: 'apollo',
      schemaJson: require('./schema.json'),
    }]
  },
  plugins: [
    'graphql'
  ]
}
```

## Linting .gql and .graphql files needs a separate env value and an extra --ext flag

The plugin also handles standalone GraphQL files ending in .gql or .graphql, but that is a different configuration path. You set env to 'literal' in your .eslintrc.js and you tell ESLint to look at those extensions explicitly, because ESLint does not lint them by default. The documented command passes three extension flags, for .js, .gql and .graphql. The literal mode is also a distinct tagName preset, since a standalone file has no tag at all. That combination, a config value plus a command line change, is the part people tend to miss, and it means the two halves of the setup live in two different places.

## Where the schema comes from: introspection results, graphql-cli or apollo-codegen

The plugin needs your schema in one of the accepted formats, and the README points at two sources for a remote schema. graphql-cli provides a get-schema command, used together with a .graphqlconfig file, and apollo-codegen provides an introspect-schema command that can fetch remote schemas as well. The local alternative is an introspection query result, which is the standard JSON document produced by the introspection query, or the schema as a string in Schema Language format. The practical consequence is a pipeline: something produces a schema.json or a .graphqlconfig, and the linter reads it. If that upstream step is missing or stale, the rule either fails to start or checks against an old schema, which is a failure mode that produces confusing errors rather than a clear message.

## Package constraints: graphql peer range, Node 10 engines, and a 2017 release tag list

The package manifest constrains what you can install it into. The peerDependencies allow graphql at ^0.12.0, ^0.13.0, ^14.0.0 or ^15.0.0, and the devDependencies pin graphql 15.0.0 with eslint 6.8.0, so the plugin is developed and tested against the ESLint 6 generation and GraphQL 15. The engines field requires node >=10.0, and the browserslist target is node 10, which places the tool in the previous major Node era. The version in package.json is 4.0.0, while the release history in the repository lists v0.6.0 from 2017-01-27 and v0.7.0 from 2017-03-15, so the tagged releases and the published version number are not the same line of history. The repository licence field is listed as unknown at the top level, but the manifest itself declares "license": "MIT", so the licence for the published package is MIT as stated in package.json.

## Comparison: a dedicated GraphQL linter against an ESLint rule

The alternatives named in the repository are worth separating. For linting the schema itself rather than queries, the README points at cjoudrey/graphql-schema-linter, a different job with a different target. For the migration path, the 2022 note points at graphql-eslint, the community-supported project that Apollo recommends. The difference in approach is that this plugin treats GraphQL documents as a special case inside an existing ESLint setup, keyed on a template literal tag, whereas a dedicated GraphQL linter can work on the documents themselves rather than requiring the surrounding JavaScript to be lintable and tagged. That difference is the reason the tag convention, the fake-tag workaround and the .graphqlconfig plumbing exist at all. If your GraphQL lives in .graphql files with no tag, the dedicated tool avoids the awkwardness entirely, at the cost of adding a second linting step to your pipeline.

## Conclusion

eslint-plugin-graphql still makes sense for a JavaScript codebase that lints its GraphQL documents in ESLint today and wants a small, familiar plugin rather than a new toolchain, but it is a poor choice for any project starting fresh, because Apollo has stated it is working towards fully deprecating the repository and that support will be minimal. The alternative named in the repository README is graphql-eslint, which the Apollo note points to as the migration destination. Before adopting anything, read the 2022-01-25 deprecation note at the top of the README, check that your graphql version satisfies the peerDependencies range of ^0.12.0, ^0.13.0, ^14.0.0 or ^15.0.0, and confirm the schema is supplied as schemaJson, schemaString, schemaJsonFilepath or a .graphqlconfig file before wiring the rule into a CI job.

## FAQ

### How do I install eslint-plugin-graphql?

Run npm install eslint-plugin-graphql, register it in the plugins array of your ESLint config as 'graphql', and enable the graphql/template-strings rule with a schema supplied through schemaJson, schemaString, schemaJsonFilepath or a .graphqlconfig file.

### Is eslint-plugin-graphql deprecated?

The README carries a note dated 2022-01-25 stating that Apollo is working towards fully deprecating the repository and suggesting migration to the community-supported graphql-eslint, with support for this project described as minimal. The repository is not archived and the last push was on 2026-10-16.

### How do I lint .graphql and .gql files with eslint-plugin-graphql?

Set env to 'literal' in your .eslintrc.js and run ESLint with the extra extension flags, for example eslint . --ext .js --ext .gql --ext .graphql. ESLint does not pick up those files by default.

### How does the plugin know which template literal holds a GraphQL query?

It uses the tagName option, which defaults to 'gql' or 'graphql' except for the relay env, where it is Relay.QL. For clients that pass query strings without a tag, the documentation points to the fake-tag package as an identity tag, and notes that GraphQL comment tag support would remove the need for it.

### Which GraphQL versions does eslint-plugin-graphql support?

The peerDependencies allow graphql ^0.12.0, ^0.13.0, ^14.0.0 or ^15.0.0, and the package declares node >=10.0 as its engine requirement. The manifest lists the package version as 4.0.0.

## Sources

- [apollographql/eslint-plugin-graphql on GitHub](https://github.com/apollographql/eslint-plugin-graphql)
- [Issues](https://github.com/apollographql/eslint-plugin-graphql/issues)
- [Project website](https://www.npmjs.com/package/eslint-plugin-graphql)
- [README](https://github.com/apollographql/eslint-plugin-graphql/blob/master/README.md)
- [Releases](https://github.com/apollographql/eslint-plugin-graphql/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/apollographql-eslint-plugin-graphql
