{"id":25499959,"url":"https://github.com/mkrl/graphql-detective","last_synced_at":"2026-02-23T22:12:22.380Z","repository":{"id":278251853,"uuid":"917205133","full_name":"mkrl/graphql-detective","owner":"mkrl","description":"Track unused fields in your GraphQL queries at runtime","archived":false,"fork":false,"pushed_at":"2025-04-11T23:09:07.000Z","size":153,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-19T17:18:58.596Z","etag":null,"topics":["apollo-client","apollographql","graphql","graphql-client","proxy","urql"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mkrl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-01-15T14:57:28.000Z","updated_at":"2025-04-11T23:09:10.000Z","dependencies_parsed_at":"2025-02-18T20:26:16.596Z","dependency_job_id":"4c7a60ab-13ec-4afe-858f-6634a9fd5737","html_url":"https://github.com/mkrl/graphql-detective","commit_stats":null,"previous_names":["mkrl/graphql-detective"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mkrl/graphql-detective","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkrl%2Fgraphql-detective","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkrl%2Fgraphql-detective/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkrl%2Fgraphql-detective/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkrl%2Fgraphql-detective/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mkrl","download_url":"https://codeload.github.com/mkrl/graphql-detective/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkrl%2Fgraphql-detective/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262598162,"owners_count":23334668,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apollo-client","apollographql","graphql","graphql-client","proxy","urql"],"created_at":"2025-02-19T03:28:33.394Z","updated_at":"2026-02-23T22:12:17.332Z","avatar_url":"https://github.com/mkrl.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003egraphql-detective\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003eTrack unused fields in your GraphQL queries at runtime\u003c/p\u003e\n\n\n## Installation\n\nThe core package is framework-agnostic, but specific to a GraphQL client you use.\n\nPlease see the corresponding docs for the client you are using:\n\n- [Apollo](./lib/apollo/README.md)\n- [Urql](./lib/urql/README.md)\n\n## Why?\n\nWhen working with GraphQL on a scale, it is easy to lose track of which fields are actually being used in your application. This usually leads to over-fetching and performance issues.\n\nStatic analysis and good type-safe code generation can certainly help, but in a lot of cases like dynamic queries, object spreads and destructuring, or passing objects as props, it is not always possible to know which fields are actually being accessed at runtime.\n\nYes, you heard this right, this is not a static analysis tool.\n\n## How?\n\nProxies! The basic idea is very simple and was around for quite some time.\n\nWhen data comes back from the GraphQL endpoint, we take the entire data object, and recursively traverse it to create a tracking proxy. The app then receives the proxied object instead of the original data.\n\nIn the meantime, we also parse the GraphQL query document and store the representation of all potential usage paths.\n\nWhen the app accesses a field on the proxied object, we record the accessed path.\n\nFinally, when we want to know which fields are unused, we compare the accessed paths with the potential usage paths.\n\nWhile this idea was talked about a while ago (see [Reddit Engineering Blog](https://www.reddit.com/r/RedditEng/comments/x0rasj/identifying_unused_fields_in_graphql/)), it was never released as an open-source solution.\n\n## Disclaimer\n\nThis is NOT intended to be used in production. This should never end up in your final bundle, you set it up, test your suspicions, and roll it back.\n\nVery early in development, but somewhat battle-tested in a few pretty big codebases.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkrl%2Fgraphql-detective","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmkrl%2Fgraphql-detective","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkrl%2Fgraphql-detective/lists"}