graphql-web-lite

The small sibling of the graphql package, slimmed down for client-side libraries


NPM Version License Minified gzip size

The `graphql` package serves two purposes in being the reference implementation of the [GraphQL specification](https://spec.graphql.org/) and being used as the shared toolkit for implementing GraphQL in client-side and server-side JavaScript applications. This can cause bloat for client-side apps, where we'd rather choose lower bundlesize impact over fidelity. `graphql-web-lite` provides an alias package that can be swapped in for the standard `graphql` package in client-side applications. It aims to reduce the size of imports that are in common use by GraphQL clients and users, while still providing most `graphql` exports that are used in other contexts. It replaces the default `language` exports with [`@0no-co/graphql.web`](https://github.com/0no-co/graphql.web) for a leaner parser, printer, and visitor, which only support the GraphQL query language and are tested to 100% coverage and built to match GraphQL.js’ performance. ## Installation `graphql-web-lite` mirrors the folder structure of the regular `graphql` package and includes mostly the same files and imports as the `graphql` package, minus a couple that aren't commonly used for client-side GraphQL. This offers us several installation options, depending on how the package is aliased to the regular `"graphql"` import.
Installation with package.json aliases When your dependencies and `node_modules` folder isn't used by a _GraphQL server_ and only used by a _GraphQL clients_, you can use a quick and easy npm installation alias. In your `package.json` file you can define your `graphql` installation to use `graphql-web-lite` instead, which is supported by both Yarn and npm: ```diff { "dependencies": { - "graphql": "^16.6.0" + "graphql": "npm:graphql-web-lite@^16.6.0-3" } } ``` Alternatively, you can run an installation command to alias the package:
```sh npm install --save graphql@npm:graphql-web-lite # or yarn add graphql@npm:graphql-web-lite ``` When this isn't suitable — for instance, because the same dependencies are shared with an API or server-side GraphQL consumer, or you're working inside a monorepo — you can try one of the other aliasing techniques below.
Installation with Webpack aliases First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` package. ```sh npm install --save graphql-web-lite # or yarn add graphql-web-lite ``` To alias a package in Webpack, an entry must be added to your Webpack configuration's `resolve.alias` section. Depending on your implementation, the configuration may already contain some keys inside `resolve.alias`, and you'd want to add another entry for `"graphql"`. ```js const webpackConfig = { // ... resolve: { alias: { graphql: 'graphql-web-lite', }, }, }; ```
Installation with Next.js First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` package. ```sh npm install --save graphql-web-lite # or yarn add graphql-web-lite ``` In your [Next.js configuration file](https://nextjs.org/docs/api-reference/next.config.js/introduction), under `next.config.js`, you can add an additional `webpack()` function that is able to modify Next's Webpack configuration to add an alias for `graphql`. ```js module.exports = { webpack(config, { isServer }) { if (!isServer) { config.resolve.alias = { ...config.resolve.alias, graphql: 'graphql-web-lite', }; } return config; }, }; ``` Here we're also ensuring that the alias isn't applied on the server-side, in case an API route is using `graphql` for a server-side GraphQL schema.
Installation with Rollup's alias plugin First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` package. ```sh npm install --save graphql-web-lite # or yarn add graphql-web-lite ``` In Rollup, the easiest way to add a new alias is to use `@rollup/plugin-alias`. We'll have to install this plugin and ensure that every import and deep import to `graphql` is aliased to `graphql-web-lite`. Any Rollup-based build will fail when the import name of the package does not match the `name` field in the module's `package.json` file, so this step is necessary. ```js import alias from '@rollup/plugin-alias'; module.exports = { plugins: [ alias({ entries: [{ find: 'graphql', replacement: 'graphql-web-lite' }], }), ], }; ```
Installation with Vite First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` package. ```sh npm install --save graphql-web-lite # or yarn add graphql-web-lite ``` In your [Vite configuration file](https://vitejs.dev/config/#config-file-resolving) you may add a new entry for its `resolve.alias` entries. This entry works the same as Rollup's alias plugin. ```js import { defineConfig } from 'vite'; export default defineConfig({ resolve: { alias: { graphql: 'graphql-web-lite', }, }, }); ``` Here we're also ensuring that the alias isn't applied on the server-side, in case an API route is using `graphql` for a server-side GraphQL schema.
Installation with Parcel First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` package. ```sh npm install --save graphql-web-lite # or yarn add graphql-web-lite ``` In Parcel, we can add an entry in our `package.json` file for an alias. Specifically, the `alias` property may contain an object that maps packages to their aliases. ```diff { "alias": { + "graphql": "graphql-web-lite" } } ```
Installation with Jest's module mapping First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` package. ```sh npm install --save graphql-web-lite # or yarn add graphql-web-lite ``` Jest allows any module names to be remapped using regular expression-based mappings. In your Jest config you'll need to add an entry for `graphql` that remaps all imports and deep imports to `graphql-web-lite`. ```json { "moduleNameMapper": { "graphql(.*)": "graphql-web-lite$1" } } ```
## Impact & Changes In short, most utilities, functions, and classes exported by the `graphql` package are only used for server-side GraphQL. Some of them have been removed in `graphql-web-lite` to discourage its server-side usage, and help bundlers exlude them if tree-shaking were to fail. Most GraphQL clients rely on importing the parser, printer, visitor, and the `GraphQLError` class. These have all been modified to reduce their bundlesize impact and to remove any support for [GraphQL's schema language and type system](https://spec.graphql.org/June2018/#sec-Type-System). Any debugging calls, development-time warnings, and other non-production code is also being transpiled away, and `process.env.NODE_ENV` has been compiled away.
Full List of Changes | Export | Changes | Notes | | --------------------- | ---------- | ------------------------------------------------------------------- | | `visit` | _modified_ | works recursively and does not detect invalid AST nodes | | `print` | _modified_ | won't output any schema nodes and does not detect invalid AST nodes | | `printLocation` | _modified_ | won't output source snippets | | `printSourceLocation` | _modified_ | won't output source snippets | | `parse` | _modified_ | won't parse schema nodes or throw precise syntax errors | | `parseType` | _modified_ | won't throw precise syntax errors | | `parseValue` | _modified_ | won't throw precise syntax errors | | `GraphQLError` | _modified_ | doesn't handle locations and Error stacks |
### Bundlesize Impact Most GraphQL client-side libraries use the following common set of imports from the `graphql` library. Assuming a transformation like [`babel-plugin-modular-graphql`](https://github.com/kitten/babel-plugin-modular-graphql/) or granular imports in general this creates a short list of utilities. ```js export { valueFromASTUntyped } from 'graphql/utilities/valueFromASTUntyped.mjs'; export { GraphQLError } from 'graphql/error/GraphQLError.mjs'; export { Kind } from 'graphql/language/kinds.mjs'; export { parse } from 'graphql/language/parser.mjs'; export { print } from 'graphql/language/printer.mjs'; export { visit } from 'graphql/language/visitor.mjs'; ``` The minzipped size of the imports is about `11.2kB` in a given output bundle, which assumes all the above imports are in use. When the GraphQL language parser is dropped from the bundle, for instance by precompiling queries and excluding it in a compilation step, the resulting minzipped size drops to `5.55kB`. When `graphql-web-lite` replaces the `graphql` package the minzipped size drops from the `11.2kB` figure down to `5.44kB`, and `3.19kB` without the parser.