graphql-list-fields

Extracts the list of fields a client requested from a GraphQL resolver's info object, fragments and directives included.

Library
npm
v2.0.4
125stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
35/100Needs Attention
Development Activity0
Maintenance0
Community60
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
64/100Good
Architecture70
Code Quality65
Innovation45
Learning Curve75

graphql-list-fields solves a narrow but common problem in GraphQL server development: knowing exactly which fields a client asked for inside a resolver, so you only fetch or compute what’s needed instead of everything a type could expose. Given the GraphQLResolveInfo object every resolver already receives, it walks the query’s AST and returns a flat array of field names in dot notation for nested selections.

The implementation resolves fragments (both named fragment ... on Type and inline ... on Type) and honors @skip/@include directives, so the returned field list matches what will actually be included in the response rather than what’s merely present in the query text. An optional maxDepth argument caps how many levels of nesting are traversed, which is useful when you only need top-level field names for something like a database projection or an external API’s sparse fieldset parameter.

It has no runtime dependencies and is a single ~70-line file, making it easy to audit and drop into any graphql-js-based server (Apollo Server, express-graphql, Yoga, etc.) without pulling in additional weight.

What You Get

  • A getFieldNames(info, maxDepth?) function that returns a plain array of requested field names
  • Automatic resolution of named fragments (fragment X on Type { ... }) into the flat field list
  • Automatic resolution of inline fragments (... on Type { ... })
  • Correct handling of @skip and @include directives, including variable-based conditions
  • Dot-notation paths for nested selections (e.g. address.city)
  • Optional depth limiting via the second argument to restrict how deep nested fields are reported

Common Use Cases

  • Passing only the requested fields to a downstream REST API’s sparse-fieldset query parameter
  • Building a MongoDB/SQL projection so a resolver only selects the columns or fields actually queried
  • Deciding whether an expensive nested field was requested before computing it
  • Logging or metrics on which GraphQL fields are queried most often in production

Under The Hood

Architecture The entire package is a single file, index.js, exporting one function, getFieldList, which delegates to an internal getFieldSet that recursively walks the GraphQL AST reachable from info.fieldASTs/info.fieldNodes. Each AST node’s kind (Field, InlineFragment, FragmentSpread) is switched on to decide whether to record a dot-notation field path, recurse into an inline fragment’s selection set, or look up a named fragment from info.fragments and recurse into that; a small helper (isExcludedByDirective) evaluates @skip/@include directives against info.variableValues before a node is included, and the recursion stops early once maxDepth is exhausted. Because there’s a single entry point and no internal state, the whole module is one dependency-free tree walk with an accumulator object as its only data structure — nothing else in a consuming application can break by depending on it beyond the shape of the returned array.

Tech Stack The package itself has zero runtime dependencies; it operates purely on the AST shapes defined by the graphql (graphql-js) reference implementation, which is listed only as a devDependency for the test suite. Tests run under Jest with coverage collection, and formatting is standardized through Prettier with an explicit tab-width/quote-style configuration. There is no build step — index.js is published as-is, and CI (GitHub Actions, .github/workflows/node.js.yml) runs npm ci && npm test on Node 24 against pushes and PRs to master.

Code Quality The test suite in __tests__/test.js builds a small real GraphQLSchema with nested object types and runs actual graphql() executions against it, asserting on the field list captured inside a resolver spy — this exercises the library through its real integration surface rather than mocking the AST, and covers basic fields, fragments, inline fragments, directive-based skipping, and depth limiting. There are no TypeScript types or type declarations, and error handling is minimal (a malformed AST node kind is silently ignored via the switch falling through), which is a reasonable tradeoff for a small, stable utility but means misuse gives no explicit feedback. Naming is plain and consistent throughout the small file, and there’s no linter configured beyond Prettier.

API Design The library exposes exactly one export — a default function — matching the common require('graphql-list-fields') pattern shown directly in the README, which lowers the integration cost to a single import and a one-line call inside any resolver. The optional maxDepth parameter has a sensible default (Number.MAX_SAFE_INTEGER, i.e. unlimited) so the common case needs no configuration at all, and dot-notation output composes naturally with projection-building code without requiring the caller to walk a tree themselves.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search