Skip to content

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.

Terminal window
npm install gql.tada
npm install --save-dev @0no-co/graphqlsp

Next, we’ll have to add @0no-co/graphqlsp as a plugin to our TypeScript configuration.

tsconfig.json
{
"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.

tsconfig.json
{
"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"
}
]
}
}

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.

tsconfig.json
{
"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:

graphql-env.d.ts
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:

src/graphql.ts
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.

src/graphql.ts
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.