GraphiQL
Security Notice: All versions of
graphiql<1.4.3are vulnerable to an XSS attack in cases where the GraphQL server to which the GraphiQL web app connects is not trusted. Learn more in our security advisory.
/ˈɡrafək(ə)l/ A graphical interactive in-browser GraphQL IDE. Try the live demo.
Features
- Full language support of the latest GraphQL Specification:
- Syntax highlighting
- Intelligent type ahead of fields, arguments, types, and more
- Real-time error highlighting and reporting for queries and variables
- Automatic query and variables completion
- Automatic leaf node insertion for non-scalar fields
- Documentation explorer with search and markdown support
- Persisted state using
localStorage - Simple API for adding custom plugins
Live Demos
- The latest stable version
- The current state of the
mainbranch:- An installable PWA with plugins (source)
- Using the minified bundles
- Using the development bundles (good for inspecting, debugging, etc)
- Each pull request will also get its own preview deployment on Netlify, you'll find a link in the GitHub checks
Examples
CDN- A single HTML file that loads GraphiQL directly from a CDNWebpack- A starter for WebpackCreate React App- An example using Create React AppParcel- An example using Parcel
Getting started
- Migration guide to GraphiQL 2
- Migration guide to GraphiQL 4
- Migration guide to GraphiQL 5
- Migration guide to GraphiQL 6
CDN usage
To use GraphiQL without a bundler, follow the CDN example.
Usage
Using as package
The graphiql package can be installed using your favorite package manager. You
also need to have react,react-dom and graphql installed which are peer
dependencies of graphiql.
npm install graphiql react react-dom graphql
The package exports a bunch of React components:
- The
GraphiQLProvidercomponents renders multiple context providers that encapsulate all state management - The
GraphiQLInterfacecomponent renders the UI that makes up GraphiQL - The
GraphiQLcomponent is a combination of both the above components
The GraphiQL component needs to know how to run operations against a GraphQL
API, which it gets from either a transport or a fetcher prop (the two are
mutually exclusive). A transport is an object with a send(request) method
that performs the request. send may return a Promise for queries or
mutations, or an AsyncIterable for subscriptions and multipart responses.
An easy way to create one is the
createTransport
function exported from the @graphiql/toolkit package. If you want to
implement your own transport, you can use the Transport type from
@graphiql/toolkit to make sure the shape matches what GraphiQL expects.
fetcher is still supported — it's deprecated but not removed, and predates
transport. Unlike a transport, a fetcher is a plain function that returns
an execution result directly, with no access to the underlying HTTP response.
See the v6 migration guide
if you're moving from fetcher to transport.
The following is everything you need to render GraphiQL in your React application:
import { createTransport } from '@graphiql/toolkit';
import { GraphiQL } from 'graphiql';
import { createRoot } from 'react-dom/client';
import 'graphiql/style.css';
const transport = createTransport({ url: 'https://my.backend/graphql' });
const root = createRoot(document.getElementById('root'));
root.render(<GraphiQL transport={transport} />);
When the connected server supports GraphQL.js 17 fragment arguments, opt in
with <GraphiQL fetcher={fetcher} experimentalFragmentArguments />. The syntax
is disabled by default.
Customize
GraphiQL supports customization in UI and behavior by accepting React props and children.
Props
For props documentation, see the API Docs
Children
Parts of the UI can be customized by passing children to the GraphiQL or the
GraphiQLInterface component.
<GraphiQL.Footer>: Add a custom footer shown below the response editor.
Branding and toolbar customization moved off the children API in graphiql@6:
- Replace the top bar's default hexagon icon + "GraphiQL" wordmark with the
brandprop, e.g.<GraphiQL brand="My Company" />. - Add custom toolbar buttons through a plugin's
sessionActions, which renders into the tab strip alongside prettify/merge/copy/save. See the v6 migration guide for details.
Plugins
Starting with graphiql@2 there exists a simple plugin API that allows you to
build your own custom tools right into GraphiQL.
GraphiQL includes the History, Query Builder, and Collections plugins by default. The documentation explorer is the default reference plugin. These can be toggled using icons in the sidebar on the left side of the screen. When opened, they appear next to the sidebar in a resizable portion of the screen.
To define your own plugin, all you need is a JavaScript object with three properties:
title: A unique title for the plugin (this will show up in a tooltip when hovering over the sidebar icon)icon: A React component that renders an icon which will be included in the sidebarcontent: A React component that renders the plugin contents which will be shown next to the sidebar when opening the plugin
You can pass a list of plugin objects to the GraphiQL component using the
plugins prop. Doing so replaces the default list. Start with the immutable
DEFAULT_PLUGINS export when adding or removing a plugin so you don't need to
import the built-in plugin packages directly:
import { DEFAULT_PLUGINS, GraphiQL } from 'graphiql';
const plugins = [...DEFAULT_PLUGINS, myPlugin];
<GraphiQL plugins={plugins} transport={transport} />;
You can also control the visibility state of plugins using the visiblePlugin
prop and react to changes of the plugin visibility state using the
onTogglePluginVisibility prop.
Inside the component you pass to content you can interact with the GraphiQL
state using the hooks provided by @graphiql/react.
Theming
The GraphiQL interface uses CSS variables for theming, in particular for colors.
As of v6 the supported set is the OKLCH design tokens in
tokens.css; the older --color-* HSL
variables in root.css are deprecated
(see the v6 migration guide).
Overriding these variables is the only officially supported way of customizing the appearance of GraphiQL. Starting from version 2, class names are no longer be considered stable and might change between minor or patch version updates.
Editor Theme
The query, variables, headers, and response editors are built on
Monaco, so editor theming goes
through Monaco's theme system, not CSS. The editorTheme prop takes a
{ dark, light } pair of Monaco theme names, one for each GraphiQL theme:
<GraphiQL editorTheme={{ dark: 'graphiql-DARK', light: 'graphiql-LIGHT' }} />
graphiql-DARK and graphiql-LIGHT are the built-in themes and also the
default value, so you only need to pass editorTheme if you want something
else. To use your own colors, register a theme with Monaco's editor.defineTheme
API before rendering GraphiQL, then reference it by name:
import * as monaco from 'monaco-editor';
monaco.editor.defineTheme('my-dark-theme', {
base: 'vs-dark',
inherit: true,
rules: [],
colors: {},
});
// When rendering GraphiQL:
<GraphiQL editorTheme={{ dark: 'my-dark-theme', light: 'graphiql-LIGHT' }} />;
Usage with a Custom Storage Namespace
When multiple GraphiQL instances run on the same origin—such as in different apps or
environments—they can conflict by reading from and writing to the same localStorage keys. To
prevent this, you can provide a custom storage object that prefixes all keys with a unique
namespace, isolating each instance’s state and avoiding collisions.
import type { FC } from 'react';
import { GraphiQL } from 'graphiql';
import { createTransport } from '@graphiql/toolkit';
const transport = createTransport({ url: 'https://my.backend/graphql' });
const NAMESPACE = 'my-namespace';
const storage: typeof localStorage = {
...localStorage,
getItem(key) {
return localStorage.getItem(`${NAMESPACE}:${key}`);
},
setItem(key, value) {
return localStorage.setItem(`${NAMESPACE}:${key}`, value);
},
removeItem(key) {
return localStorage.removeItem(`${NAMESPACE}:${key}`);
},
};
export const App: FC = () => {
return <GraphiQL transport={transport} storage={myStorage} />;
};
