{"id":13727227,"url":"https://github.com/lynxtaa/awesome-graphql-client","last_synced_at":"2025-08-20T14:30:39.643Z","repository":{"id":45257571,"uuid":"279082916","full_name":"lynxtaa/awesome-graphql-client","owner":"lynxtaa","description":"GraphQL Client with file upload support for NodeJS and browser","archived":false,"fork":false,"pushed_at":"2024-04-20T15:50:45.000Z","size":2766,"stargazers_count":49,"open_issues_count":6,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-05-19T18:55:41.285Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://npm.im/awesome-graphql-client","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/lynxtaa.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2020-07-12T14:36:32.000Z","updated_at":"2024-05-14T14:06:37.000Z","dependencies_parsed_at":"2022-09-01T13:40:26.386Z","dependency_job_id":"38cc00e1-48d6-42e4-b22b-acfe77c2df57","html_url":"https://github.com/lynxtaa/awesome-graphql-client","commit_stats":{"total_commits":149,"total_committers":4,"mean_commits":37.25,"dds":0.3087248322147651,"last_synced_commit":"279633c648a0ac88b8c7be0d7e3407d7c69cca93"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lynxtaa%2Fawesome-graphql-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lynxtaa%2Fawesome-graphql-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lynxtaa%2Fawesome-graphql-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lynxtaa%2Fawesome-graphql-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lynxtaa","download_url":"https://codeload.github.com/lynxtaa/awesome-graphql-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230431100,"owners_count":18224655,"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":[],"created_at":"2024-08-03T01:03:45.064Z","updated_at":"2025-08-20T14:30:39.626Z","avatar_url":"https://github.com/lynxtaa.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/lynxtaa/awesome-graphql-client\"\u003e\n    \u003cimg width=\"180\" height=\"180\" src=\"logo.svg\" alt=\"Logo\"\u003e\n  \u003c/a\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n  \u003cimg alt=\"CI/CD\" src=\"https://github.com/lynxtaa/awesome-graphql-client/workflows/CI/CD/badge.svg\"\u003e\n  \u003ca href=\"https://badge.fury.io/js/awesome-graphql-client\"\u003e\n    \u003cimg alt=\"npm version\" src=\"https://badge.fury.io/js/awesome-graphql-client.svg\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/lynxtaa/awesome-graphql-client\" alt=\"npm version\"\u003e\n    \u003cimg alt=\"Codecov\" src=\"https://img.shields.io/codecov/c/github/lynxtaa/awesome-graphql-client\"\u003e\n  \u003c/a\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n  \u003ch1\u003eAwesome GraphQL Client\u003c/h1\u003e\n  \u003cp\u003eGraphQL Client with file upload support for NodeJS and browser\u003c/p\u003e\n\u003c/div\u003e\n\n## Features\n\n- [GraphQL File Upload](https://github.com/jaydenseric/graphql-multipart-request-spec) support\n- Works in browsers and NodeJS\n- Zero dependencies\n- Small size (around 2Kb gzipped)\n- Full Typescript support\n- Supports queries generated by [graphql-tag](https://www.npmjs.com/package/graphql-tag)\n- Supports GraphQL GET requests\n- Perfect for React apps in combination with [react-query](https://www.npmjs.com/package/react-query). See [Next.js example](https://github.com/lynxtaa/awesome-graphql-client/tree/master/examples/next-js)\n\n## Install\n\n```sh\nnpm install awesome-graphql-client\n```\n\n## Quick Start\n\n### Browser\n\n```js\nimport { AwesomeGraphQLClient } from 'awesome-graphql-client'\n\nconst client = new AwesomeGraphQLClient({ endpoint: '/graphql' })\n\n// Also query can be an output from graphql-tag (see examples below)\nconst GetUsers = `\n  query getUsers {\n    users {\n      id\n    }\n  }\n`\n\nconst UploadUserAvatar = `\n  mutation uploadUserAvatar($userId: Int!, $file: Upload!) {\n    updateUser(id: $userId, input: { avatar: $file }) {\n      id\n    }\n  }\n`\n\nclient\n  .request(GetUsers)\n  .then(data =\u003e\n    client.request(UploadUserAvatar, {\n      id: data.users[0].id,\n      file: document.querySelector('input#avatar').files[0],\n    }),\n  )\n  .then(data =\u003e console.log(data.updateUser.id))\n  .catch(error =\u003e console.log(error))\n```\n\n### NodeJS\n\n```js\nimport { openAsBlob } from 'node:fs'\nimport { AwesomeGraphQLClient } from 'awesome-graphql-client'\n\nconst client = new AwesomeGraphQLClient({\n  endpoint: 'http://localhost:8080/graphql',\n})\n\n// Also query can be an output from graphql-tag (see examples below)\nconst UploadUserAvatar = `\n  mutation uploadUserAvatar($userId: Int!, $file: Upload!) {\n    updateUser(id: $userId, input: { avatar: $file }) {\n      id\n    }\n  }\n`\n\nconst blob = await openAsBlob('./avatar.png')\n\nclient\n  .request(UploadUserAvatar, { file: new File([blob], 'avatar.png'), userId: 10 })\n  .then(data =\u003e console.log(data.updateUser.id))\n  .catch(error =\u003e console.log(error))\n```\n\n## Table of Contents\n\n- API\n  - [AwesomeGraphQLClient](#awesomegraphqlclient)\n  - [GraphQLRequestError](#graphqlrequesterror)\n  - [gql](#approach-2-use-fake-graphql-tag)\n  - [isFileUpload](#custom-isfileupload-predicate)\n- Examples\n  - [Typescript](#typescript)\n  - [Error Logging](#error-logging)\n  - [GraphQL GET Requests](#graphql-get-requests)\n  - [GraphQL Tag](#graphql-tag)\n  - [Cookies in NodeJS](#cookies-in-nodejs)\n  - [Custom _isFileUpload_ Predicate](#custom-isfileupload-predicate)\n  - [More Examples](#more-examples)\n\n## API\n\n## `AwesomeGraphQLClient`\n\n**Usage**:\n\n```js\nimport { AwesomeGraphQLClient } from 'awesome-graphql-client'\nconst client = new AwesomeGraphQLClient(config)\n```\n\n### `config` properties\n\n- `endpoint`: _string_ - The URL to your GraphQL endpoint (required)\n- `fetch`: _Function_ - Fetch polyfill\n- `fetchOptions`: _object_ - Overrides for fetch options\n- `FormData`: _object_ - FormData polyfill\n- `formatQuery`: _function(query: any): string_ - Custom query formatter (see [example](#graphql-tag))\n- `onError`: _function(error: GraphQLRequestError | Error): void_ - Provided callback will be called before throwing an error (see [example](#error-logging))\n- `isFileUpload`: _function(value: unknown): boolean_ - Custom predicate function for checking if value is a file (see [example](#custom-isfileupload-predicate))\n\n### `client` methods\n\n- `client.setFetchOptions(fetchOptions: FetchOptions)`: Sets fetch options. See examples below\n- `client.getFetchOptions()`: Returns current fetch options\n- `client.setEndpoint(): string`: Sets a new GraphQL endpoint\n- `client.getEndpoint(): string`: Returns current GraphQL endpoint\n- `client.request(query, variables?, fetchOptions?): Promise\u003cdata\u003e`: Sends GraphQL Request and returns data or throws an error\n- `client.requestSafe(query, variables?, fetchOptions?): Promise\u003c{ ok: true, data, response } | { ok: false, error, partialData }\u003e`: Sends GraphQL Request and returns object with 'ok: true', 'data' and 'response' or with 'ok: false', 'error' and 'partialData' fields. See examples below. _Notice: this function never throws_.\n\n## `GraphQLRequestError`\n\n### `instance` fields\n\n- `message`: _string_ - Error message\n- `query`: _string_ - GraphQL query\n- `variables`: _string | undefined_ - GraphQL variables\n- `response`: _Response_ - response returned from fetch\n- `fieldErrors`: _GraphQLFieldError[]_ - GraphQL field errors\n\n## Examples\n\n## Typescript\n\n```ts\ninterface getUser {\n  user: { id: number; login: string } | null\n}\ninterface getUserVariables {\n  id: number\n}\n\nconst query = `\n  query getUser($id: Int!) {\n    user {\n      id\n      login\n    }\n  }\n`\n\nconst client = new AwesomeGraphQLClient({\n  endpoint: 'http://localhost:3000/graphql',\n})\n\nclient\n  .request\u003cgetUser, getUserVariables\u003e(query, { id: 10 })\n  .then(data =\u003e console.log(data))\n  .catch(error =\u003e console.log(error))\n\nclient.requestSafe\u003cgetUser, getUserVariables\u003e(query, { id: 10 }).then(result =\u003e {\n  if (!result.ok) {\n    throw result.error\n  }\n  console.log(`Status ${result.response.status}`, `Data ${result.data.user}`)\n})\n```\n\n### Typescript with TypedDocumentNode (even better!)\n\nYou can generate types from queries by using [GraphQL Code Generator](https://www.graphql-code-generator.com/) with [TypedDocumentNode plugin](https://github.com/dotansimha/graphql-typed-document-node)\n\n```graphql\n# queries.graphql\nquery getUser($id: Int!) {\n  user {\n    id\n    login\n  }\n}\n```\n\n```ts\n// index.ts\nimport { TypedDocumentNode } from '@graphql-typed-document-node/core'\nimport { AwesomeGraphQLClient } from 'awesome-graphql-client'\nimport { print } from 'graphql/language/printer'\n\nimport { GetCharactersDocument } from './generated'\n\nconst gqlClient = new AwesomeGraphQLClient({\n  endpoint: 'https://rickandmortyapi.com/graphql',\n  formatQuery: (query: TypedDocumentNode) =\u003e print(query),\n})\n\n// AwesomeGraphQLClient will infer all types from the passed query automagically:\ngqlClient\n  .request(GetCharactersDocument, { name: 'Rick' })\n  .then(data =\u003e console.log(data))\n  .catch(error =\u003e console.log(error))\n```\n\nCheck out full example at [examples/typed-document-node](https://github.com/lynxtaa/awesome-graphql-client/tree/master/examples/typed-document-node)\n\n## Error Logging\n\n```js\nimport { AwesomeGraphQLClient, GraphQLRequestError } from 'awesome-graphql-client'\n\nconst client = new AwesomeGraphQLClient({\n  endpoint: '/graphql',\n  onError(error) {\n    if (error instanceof GraphQLRequestError) {\n      console.error(error.message)\n      console.groupCollapsed('Operation:')\n      console.log({ query: error.query, variables: error.variables })\n      console.groupEnd()\n    } else {\n      console.error(error)\n    }\n  },\n})\n```\n\n## GraphQL GET Requests\n\nInternally it uses [URLSearchParams API](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams). Consider [polyfilling URL standard](https://github.com/zloirock/core-js#url-and-urlsearchparams) for this feature to work in IE\n\n```js\nclient\n  .request(query, variables, { method: 'GET' })\n  .then(data =\u003e console.log(data))\n  .catch(err =\u003e console.log(err))\n```\n\n## GraphQL Tag\n\n### Approach #1: Use `formatQuery`\n\n```ts\nimport { AwesomeGraphQLClient } from 'awesome-graphql-client'\nimport { DocumentNode } from 'graphql/language/ast'\nimport { print } from 'graphql/language/printer'\nimport gql from 'graphql-tag'\n\nconst client = new AwesomeGraphQLClient({\n  endpoint: '/graphql',\n  formatQuery: (query: DocumentNode | string) =\u003e\n    typeof query === 'string' ? query : print(query),\n})\n\nconst query = gql`\n  query me {\n    me {\n      login\n    }\n  }\n`\n\nclient\n  .request(query)\n  .then(data =\u003e console.log(data))\n  .catch(err =\u003e console.log(err))\n```\n\n### Approach #2: Use fake `graphql-tag`\n\nRecommended approach if you're using `graphql-tag` only for syntax highlighting and static analysis such as linting and types generation. It has less computational cost and makes overall smaller bundles. GraphQL fragments are supported too.\n\n```js\nimport { AwesomeGraphQLClient, gql } from 'awesome-graphql-client'\n\nconst client = new AwesomeGraphQLClient({ endpoint: '/graphql' })\n\nconst query = gql`\n  query me {\n    me {\n      login\n    }\n  }\n`\n\nclient\n  .request(query)\n  .then(data =\u003e console.log(data))\n  .catch(err =\u003e console.log(err))\n```\n\n### Approach #3: Use TypedDocumentNode instead\n\nPerfect for Typescript projects. See [example above](#typescript-with-typeddocumentnode-even-better)\n\n## Cookies in NodeJS\n\n```js\nimport { AwesomeGraphQLClient } from 'awesome-graphql-client'\nimport fetchCookie from 'fetch-cookie'\n\nconst client = new AwesomeGraphQLClient({\n  endpoint: 'http://localhost:8080/graphql',\n  fetch: fetchCookie(globalThis.fetch),\n})\n```\n\n## Custom _isFileUpload_ Predicate\n\n```js\nimport { AwesomeGraphQLClient, isFileUpload } from 'awesome-graphql-client'\n\nconst client = new AwesomeGraphQLClient({\n  endpoint: 'http://localhost:8080/graphql',\n  // By default File, Blob, Buffer, Promise and stream-like instances are considered as files.\n  // You can expand this behaviour by adding a custom predicate\n  isFileUpload: value =\u003e isFileUpload(value) || value instanceof MyCustomFile,\n})\n```\n\n## More Examples\n\n[https://github.com/lynxtaa/awesome-graphql-client/tree/master/examples](https://github.com/lynxtaa/awesome-graphql-client/tree/master/examples)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flynxtaa%2Fawesome-graphql-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flynxtaa%2Fawesome-graphql-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flynxtaa%2Fawesome-graphql-client/lists"}