Installation
The gql.tada
package provides typings and the runtime API as a library,
while @0no-co/graphqlsp
integrates with the TypeScript language server
to integrate with an IDE or editor.
On this page, we’ll go through the steps to get everything set up properly.
A quick demo of what this looks like can be found in an example project in the gql.tada
repository.
Step 1 — Installing packages
We’ll start by installing gql.tada
as a dependency, and @0no-co/graphqlsp
as
a dev-dependency using out project’s package manager.
npm install gql.tadanpm install --save-dev @0no-co/graphqlsp
pnpm add gql.tadapnpm add --save-dev @0no-co/graphqlsp
yarn add gql.tadayarn add --dev @0no-co/graphqlsp
bun add gql.tadabun add --dev @0no-co/graphqlsp
Next, we’ll have to add @0no-co/graphqlsp
as a plugin to our TypeScript
configuration.
{ "compilerOptions": { "strict": true, "plugins": [ { "name": "@0no-co/graphqlsp", "schema": "./schema.graphql", "tadaOutputLocation": "./src/graphql-env.d.ts" } ] }}
This will start up a “TypeScript Language Service Plugin” which runs when TypeScript is analyzing a file in our IDE or editor.
gql.tada
on its own won’t provide you with editor hints, diagnostics, or errors, so @0no-co/graphqlsp
is crucial
in providing you feedback and help when writing GraphQL documents.
Step 2 — Configuring a schema
@0no-co/graphqlsp
needs to have a GraphQL API’s schema to function correctly.
The schema provides it with the types, fields, and description information of a GraphQL API.
We can set @0no-co/graphqlsp
up with our schema in our tsconfig.json
file.
In the plugin options we’ll update the schema
key.
{ "compilerOptions": { "plugins": [ { "name": "@0no-co/graphqlsp",
"schema": "./schema.graphql", "tadaOutputLocation": "./src/graphql-env.d.ts" } ] }}
The schema
option currently allows for three different formats to load a schema. It accepts either:
- a path to a
.graphql
file containing a schema definition (in GraphQL SDL format) - a path to a
.json
file containing a schema’s introspection query data - a URL to a GraphQL API that can be introspected
{ "compilerOptions": { "plugins": [ { "name": "@0no-co/graphqlsp", "schema": "./schema.graphql" } ] }}
{ "compilerOptions": { "plugins": [ { "name": "@0no-co/graphqlsp", "schema": "./introspection.json" } ] }}
{ "compilerOptions": { "plugins": [ { "name": "@0no-co/graphqlsp", "schema": "http://localhost:4321/graphql" } ] }}
{ "compilerOptions": { "plugins": [ { "name": "@0no-co/graphqlsp", "schema": { "url": "http://localhost:4321/graphql", "headers": { "Accept": "application/graphql-response+json" } } } ] }}
Step 3 — Configuring typings
Afterwards, @0no-co/graphqlsp
is ready to also output a typings file for gql.tada
.
The latter needs a type of an introspected GraphQL schema to infer types of
GraphQL documents automatically.
This is configured by providing an output location to @0no-co/graphqlsp
in our tsconfig.json
file.
In the plugin options we’ll update the tadaOutputLocation
key.
{ "compilerOptions": { "plugins": [ { "name": "@0no-co/graphqlsp", "schema": "./schema.graphql",
"tadaOutputLocation": "./src/graphql-env.d.ts" } ] }}
The tadaOutputLocation
path can either be a .ts
file, a .d.ts
file, or
a folder, in which case a introspection.d.ts
file will be created.
Once we start up our editor, @0no-co/graphqlsp
will run and will create
the output file. In this example, we’ve created a src/graphql-env.d.ts
file.
When opening this file we should see code that looks like the following:
declare const introspection: {10 collapsed lines
"__schema": { "queryType": { "name": "Query" }, "mutationType": null, "subscriptionType": null, "types": [ // ... ] }};
import * as gqlTada from 'gql.tada';
declare module 'gql.tada' { interface setupSchema { introspection: typeof introspection }}
This file declares our schema’s introspection data in gql.tada
. After this file
is created by @0no-co/graphqlsp
automatically, gql.tada
is set up project-wide
and is ready to be used.
Initializing gql.tada
manually
Above, we let @0no-co/graphqlsp
generate a src/graphql-env.d.ts
file, which sets
gql.tada
up project-wide for us.
This allows us to import graphql()
from gql.tada
directly, but it limits what we
can do, since we can’t customize any scalars, or further configuration
for gql.tada
. This setup also fails if we have multiple schemas (for example, in a monorepo),
since the declaration in graphql-env.d.ts
sets a schema up project-wide.
To work around this, we’ll create a file that uses the introspection data manually with the
initGraphQLTada()
function to create our own graphql()
function:
import { initGraphQLTada } from 'gql.tada';import type { introspection } from './graphql-env.d.ts';
export const graphql = initGraphQLTada<{ introspection: introspection;}>();
export type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada';export { readFragment } from 'gql.tada';
Instead of declaring our schema project-wide, we now have created a graphql
function
that specifically uses the introspection inside the graphql-env.d.ts
file that
@0no-co/graphqlsp
outputs for us.
Instead of importing graphql
from gql.tada
, we should now import it from our
custom src/graphql.ts
file.
Customizing scalar types
Now that we’ve set up a src/graphql.ts
file, which uses initGraphQLTada<>()
to create
a custom graphql
function, we may also use this function to customize our scalars.
By default, gql.tada
will have types defined for the built-in scalars
in GraphQL. However, it won’t be able to know the serialized type of your custom scalars.
For instance, our schema may contain a DateTime
scalar which, when queried, becomes
a string of new Date().toISOString()
, however, gql.tada
won’t know that this type
is a string.
import { initGraphQLTada } from 'gql.tada';import type { introspection } from './graphql-env.d.ts';
export const graphql = initGraphQLTada<{ introspection: introspection;
scalars: { DateTime: string, JSON: any, },}>();
export type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada';export { readFragment } from 'gql.tada';
When using these scalars, they’ll now be mapped to the types in the scalars
object type.