
Security News
Open VSX Unblocks Extension IDs Used in Malware Campaign
Open VSX has removed three extension IDs from its malicious-extension list as the legitimate publishers they impersonated move to claim the names for themselves.
This script helps identify unused GraphQL operations (queries, mutations, subscriptions) in your project. It scans .gql files for operations and checks if they are being used in your TypeScript/JavaScript files.
gqlPrune is a utility that identifies unused GraphQL operations (queries, mutations, subscriptions) and unused fragments in your project. It scans .gql/.graphql files and checks whether each operation is referenced in your TypeScript/JavaScript source, and whether each fragment is spread by an operation or referenced in source — all without needing a running server or schema.
gqlprune (lowercase), matching the package name — npx gqlprune and a global gqlprune both work.<Name>Document constant, not just use<Name><Type>. If you use a different client (urql, react-query, raw documents, …), set usagePatterns so your operations aren't reported as unused.excludedFolders matches by folder name or root-relative path, and node_modules/.git are always excluded. (In 1.x the documented node_modules entry silently did nothing.)An operation is considered used if any of a set of search strings derived from its name appears in your source files. By default gqlPrune looks for the conventions emitted by GraphQL Code Generator (the typescript-react-apollo / near-operation-file presets):
For an operation query GetUser, the defaults match:
| Pattern | Example |
|---|---|
use{Name}{Type} | useGetUserQuery |
use{Name}Lazy{Type} | useGetUserLazyQuery |
use{Name}Suspense{Type} | useGetUserSuspenseQuery |
{Name}Document | GetUserDocument |
If your project uses a different convention (urql, react-query, graphql-request, Vue, raw documents, etc.), override the patterns via usagePatterns in the config — see below. Without that, operations may be incorrectly reported as unused.
gqlPrune also reports fragments that are never used, across files and without a schema. A fragment is considered used when it is either:
.gql corpus, or<Name>FragmentDoc constant (e.g. under fragment masking). Override with fragmentUsagePatterns.A fragment spread only by another unused fragment is reported too. Note: a fragment is kept alive by any operation that spreads it, even an unused one — that operation is reported separately, so the fragment surfaces on the next run once you remove the operation.
Because usage is detected by string-matching srcDir, GraphQL Code Generator output that lives inside srcDir is a trap: a single generated file (e.g. src/gql/graphql.ts) references every operation, so everything looks used and nothing is ever reported unused — silently.
gqlPrune guards against this. When one source file alone references most of your operations, it prints a warning naming the file and pointing you at excludedFolders:
⚠ Suspected generated file "src/gql/graphql.ts" references 100% of all operations (50/50) and looks generated — exclude it via "excludedFolders" in gqlPrune.config.yaml or unused results will be unreliable.
Add that file's folder to excludedFolders and re-run. The warning goes to stderr (so it also surfaces in --json mode) and is included in the JSON report's warnings array; it does not change the exit code.
Requires Node.js ≥ 20.
npm install --save-dev gqlprune
Run the init command to launch a configurator that generates gqlPrune.config.yaml at the root of your project. It auto-detects your GraphQL and source directories (scanning the project, excluding node_modules/.git/dist) and offers them as defaults you can accept or override. After writing the file it prints a quick preview of what a real run would find:
npx gqlprune init
✓ Found 42 operations in 12 files; 5 look unused. Run "gqlprune" to see them.
graphqlDir: ./path/to/graphql
srcDir: ./src
excludedFolders:
- __generated__
# Optional — override how operation usage is detected.
# Supports {name}, {Name}, {type}, {Type} placeholders.
usagePatterns:
- use{Name}{Type}
- '{Name}Document'
# Optional — override how fragments are matched in source (e.g. masking).
# Supports {name}, {Name} placeholders.
fragmentUsagePatterns:
- '{Name}FragmentDoc'
graphqlDir: directory containing your .gql/.graphql files.srcDir: directory containing your source files (.ts, .tsx, .js, .jsx).excludedFolders (optional): folder names (e.g. __generated__, matched anywhere in the tree) or paths relative to the project root (e.g. src/legacy). node_modules and .git are always excluded.usagePatterns (optional): templates used to detect operation usage. Defaults to the table above when omitted.fragmentUsagePatterns (optional): templates for detecting fragments referenced directly in source (fragment masking). Defaults to {Name}FragmentDoc.Every config field has a matching flag, so you can run gqlPrune with no gqlPrune.config.yaml — handy for a one-off npx try with zero setup:
npx gqlprune --graphql ./graphql --src ./src --ignore __generated__
| Flag | Config field |
|---|---|
--graphql <dir> | graphqlDir |
--src <dir> | srcDir |
--ignore <folder> (repeatable) | excludedFolders |
--pattern <template> (repeatable) | usagePatterns |
--fragment-pattern <template> (repeatable) | fragmentUsagePatterns |
Both --flag value and --flag=value work, in any order. Precedence: a flag overrides the same field in the YAML; flags alone work with no YAML; YAML alone works exactly as before. A list flag (e.g. --ignore) replaces that list from the YAML rather than appending to it.
npx gqlprune
This prints any unused GraphQL operations and fragments. The command exits with:
Pass --json for a machine-readable report (CI, dashboards, scripting) instead of the human-readable tables:
npx gqlprune --json
{
"unusedOperations": [
{ "name": "GetUser", "type": "query", "file": "graphql/user.gql", "line": 1 }
],
"unusedFragments": [
{ "name": "UserFields", "file": "graphql/user.gql", "line": 8 }
],
"warnings": [],
"summary": { "unusedOperations": 1, "unusedFragments": 1 }
}
Only the JSON is written to stdout and the exit code is unchanged (0 clean / 1 unused), so it pipes cleanly into jq and CI gates. The warnings array carries advisory messages — currently a heads-up when a generated file may be masking results — and is empty when there are none.
Add a script and run it in your pipeline; the non-zero exit fails the job when unused operations are found:
{
"scripts": {
"gql:prune": "gqlprune"
}
}
Under GitHub Actions, gqlPrune emits inline ::warning annotations pointing at each unused operation/fragment (file + line), so they show up on the PR's Files changed tab. It's enabled automatically when GITHUB_ACTIONS is set, or force it anywhere with --annotate:
npx gqlprune --annotate
Annotations go to stderr, so they don't interfere with --json output on stdout (the two can be combined).
Unused operations and fragments are listed in separate sections — operations by type, name, and file; fragments by name and file:
--- Unused GraphQL Operations ---
Type Operation File
query OperationName operationFile.gql
--- Unused GraphQL Fragments ---
Fragment File
FragmentName fragmentFile.gql
Contributions are welcome — see CONTRIBUTING.md. This project uses Conventional Commits; releases and the changelog are automated with release-please.
See SECURITY.md for how to report a vulnerability.
See CHANGELOG.md.
FAQs
Finds unused GraphQL operations and fragments by scanning .gql/.graphql files and checking whether each one is referenced in your TypeScript/JavaScript source. No schema or running server needed.
We found that gqlprune demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Open VSX has removed three extension IDs from its malicious-extension list as the legitimate publishers they impersonated move to claim the names for themselves.

Product
Socket’s PHP and Composer support is now in Beta for all customers, with PHP reachability analysis generally available.

Product
Socket is bringing experimental protection to Firefox, scanning 97,000+ extensions in Mozilla's official directory for malware and risky updates.