Ctrl + K
GraphQL16 min read

GraphQL Variables Guide

A practical guide to GraphQL variables covering syntax, type declarations, default values, input objects, lists, nullability, mutations, and debugging.

Published: 2026-10-05

GraphQL variables allow clients to pass dynamic values into queries and mutations without embedding those values directly into the operation document. They are especially useful for values that come from user input, application state, URL parameters, forms, filters, pagination controls, and API requests.

Instead of constructing a new GraphQL query every time a value changes, the client can keep the operation document unchanged and provide different variable values with each request. GraphQL then validates those values against the variable types declared by the operation.

This guide explains GraphQL variable syntax, variable definitions, scalar types, non-null variables, default values, lists, input objects, queries, mutations, JSON variables, common errors, and practical best practices.

What Are GraphQL Variables?

A GraphQL variable is a named value supplied separately from a GraphQL operation. Variables are declared at the beginning of an operation and referenced inside the query or mutation with a dollar sign.

query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
  }
}

In this example, $id is the variable. The declaration says that the variable has the ID! type. The same variable is then passed to the user field as its id argument.

The actual value is provided separately as JSON.

{
  "id": "42"
}

Why Use GraphQL Variables?

Variables separate the GraphQL operation itself from the values used by that operation. This is useful because the same operation can be executed repeatedly with different values.

query SearchProducts($term: String!) {
  products(search: $term) {
    id
    name
    price
  }
}
{
  "term": "keyboard"
}

The operation does not need to be rewritten when the search term changes. The client can send another variables object containing a different value.

  • Keep operation documents reusable.
  • Avoid embedding dynamic values directly into GraphQL documents.
  • Allow GraphQL to validate variable values against declared types.
  • Pass structured data such as input objects and lists.
  • Work naturally with queries and mutations.
  • Make frontend forms and API calls easier to integrate.

GraphQL Variable Syntax

A variable definition uses the variable name followed by its GraphQL type.

query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
  }
}

The general structure is a dollar sign, variable name, colon, and type.

($variableName: VariableType)

The variable definition appears after the operation name. If an operation has several variables, they are separated by commas or whitespace.

query Search(
  $term: String!
  $limit: Int
  $active: Boolean
) {
  products(
    search: $term
    limit: $limit
    active: $active
  ) {
    id
    name
  }
}

Variable Definitions vs Variable Values

GraphQL separates the declaration of a variable from the value supplied with the request. The GraphQL document contains the variable definition, while the request's variables object contains the actual value.

query GetProduct($id: ID!) {
  product(id: $id) {
    id
    name
    price
  }
}
{
  "id": "100"
}

Here, ID! describes what type of value the operation expects. The JSON object provides the concrete value used during execution.

GraphQL Variable Types

Variables use GraphQL input types. Common built-in scalar types include String, Int, Float, Boolean, and ID.

TypePurposeExample value
StringText"hello"
IntInteger number42
FloatDecimal number19.95
BooleanTrue or falsetrue
IDUnique identifier"user-42"

A schema can also define custom scalar types and input object types. Variables must use types that are valid input types in the schema.

String Variables

String variables are useful for names, search terms, messages, descriptions, and other textual values.

query SearchUsers($name: String!) {
  users(name: $name) {
    id
    name
  }
}
{
  "name": "Anna"
}

Integer Variables

Int variables represent GraphQL integer values and are commonly used for limits, offsets, counts, and numeric identifiers when the schema expects Int.

query GetProducts($limit: Int!) {
  products(limit: $limit) {
    id
    name
  }
}
{
  "limit": 20
}

Float Variables

Float variables are used when the schema expects a floating-point value, such as a price, measurement, or calculated numeric value.

query ProductsAbovePrice($price: Float!) {
  products(minPrice: $price) {
    id
    name
    price
  }
}
{
  "price": 99.5
}

Boolean Variables

Boolean variables accept true or false values and are useful for filters, feature flags, visibility settings, and other binary conditions.

query GetProducts($available: Boolean!) {
  products(available: $available) {
    id
    name
  }
}
{
  "available": true
}

ID Variables

The ID scalar represents a unique identifier. GraphQL allows ID values to be serialized as strings, and GraphQL implementations can also accept integer input values where the specification permits ID input coercion.

query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
  }
}
{
  "id": "42"
}

Nullable GraphQL Variables

A variable without an exclamation mark is nullable. For example, String allows a string value or null, subject to the rules of the operation and schema.

query SearchProducts($term: String) {
  products(search: $term) {
    id
    name
  }
}

If the variable is omitted or supplied as null, the behavior depends on how the corresponding field argument and resolver are defined.

Non-Null GraphQL Variables

Adding ! to a variable type makes the variable non-null. The client must provide a non-null value unless a default value changes the variable's requirements.

query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
  }
}

The variable cannot be explicitly set to null when its type is ID!. If the required variable is missing, GraphQL validation or execution will report an error.

GraphQL Lists as Variable Types

GraphQL uses square brackets to represent list input types. For example, [ID!]! means a non-null list containing non-null ID values.

query GetProducts($ids: [ID!]!) {
  products(ids: $ids) {
    id
    name
  }
}
{
  "ids": ["10", "20", "30"]
}

The placement of ! matters. [ID!]! means the list itself cannot be null and its individual elements cannot be null.

TypeMeaning
[ID]Nullable list of nullable IDs
[ID!]Nullable list of non-null IDs
[ID]!Non-null list of nullable IDs
[ID!]!Non-null list of non-null IDs

GraphQL Input Object Variables

Input objects allow clients to pass structured data as one variable. They are especially common in mutations, where an operation may require several related values.

mutation CreateUser($input: CreateUserInput!) {
  createUser(input: $input) {
    id
    name
    email
  }
}
{
  "input": {
    "name": "Anna",
    "email": "[email protected]"
  }
}

CreateUserInput is an input object type defined by the GraphQL schema. Its fields and their types determine which values can be supplied.

Nested Input Objects

Input objects can contain nested input objects when the schema defines them that way.

mutation CreateOrder($input: CreateOrderInput!) {
  createOrder(input: $input) {
    id
    total
  }
}
{
  "input": {
    "customer": {
      "id": "42"
    },
    "shipping": {
      "city": "Berlin",
      "postalCode": "10115"
    }
  }
}

The exact structure is determined by the schema. A client cannot arbitrarily add fields to an input object if those fields are not defined by its input type.

Default Values for GraphQL Variables

A variable definition can include a default value. The default is used when the client does not provide a value for that variable.

query GetProducts($limit: Int = 20) {
  products(limit: $limit) {
    id
    name
  }
}

If the variables object does not provide limit, the operation can use 20. If the client supplies another value, that supplied value is used instead, provided it satisfies the variable's type and the field's requirements.

{
  "limit": 50
}

Variables in GraphQL Queries

Variables are particularly useful for queries that depend on changing filters, IDs, pagination values, or search terms.

query GetPosts(
  $category: String
  $limit: Int = 10
  $offset: Int = 0
) {
  posts(
    category: $category
    limit: $limit
    offset: $offset
  ) {
    id
    title
  }
}
{
  "category": "graphql",
  "limit": 20,
  "offset": 0
}

The same query document can be reused for another category or pagination position simply by changing the variables object.

Variables in GraphQL Mutations

Mutation variables are commonly used when submitting form data or other user-generated input.

mutation UpdateUser(
  $id: ID!
  $name: String!
  $active: Boolean!
) {
  updateUser(
    id: $id
    name: $name
    active: $active
  ) {
    id
    name
    active
  }
}
{
  "id": "42",
  "name": "Anna Smith",
  "active": true
}

For larger mutations, an input object often provides a cleaner interface.

mutation UpdateUser($input: UpdateUserInput!) {
  updateUser(input: $input) {
    id
    name
    active
  }
}

GraphQL Variables and JSON

Variables are commonly transported as a JSON object alongside the GraphQL document. The variable names in JSON correspond to the variable names declared in the operation.

query GetProduct($id: ID!, $includeReviews: Boolean!) {
  product(id: $id) {
    id
    name
    reviews @include(if: $includeReviews) {
      id
      rating
    }
  }
}
{
  "id": "42",
  "includeReviews": true
}

The JSON object is not itself a GraphQL document. It contains values that are supplied to the variables declared by the GraphQL operation.

Variable Names Must Match

The variable name in the request must correspond to a variable declared by the operation.

query GetUser($userId: ID!) {
  user(id: $userId) {
    id
    name
  }
}
{
  "id": "42"
}

This request uses id instead of userId, so it does not provide the declared $userId variable. The correct variables object is:

{
  "userId": "42"
}

Variables Are Not String Interpolation

A common mistake is treating GraphQL variables as string interpolation. Variables are not inserted into a GraphQL document by manually replacing placeholders. They are values supplied separately to the GraphQL execution process.

query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
  }
}

The client should provide the variables through the GraphQL client's variables mechanism rather than constructing the query by concatenating strings.

⚠️ Do not build GraphQL operations by directly concatenating untrusted user input into query strings when variables can be used instead. Variables provide a structured way to pass input and allow GraphQL to validate it against the declared type.

Variable Compatibility with Field Arguments

A variable's type must be compatible with the argument type expected by the field where the variable is used. Declaring a variable with the wrong type can cause the operation to fail validation before execution.

query GetUser($id: String!) {
  user(id: $id) {
    id
    name
  }
}

If the user field expects an ID! argument, using String! may not be valid even though both types can represent textual-looking values. GraphQL type compatibility is determined by the schema and input type rules, not simply by the runtime appearance of the value.

Variable Nullability and Argument Nullability

Variable and argument nullability interact. If a field argument requires a non-null value, the variable supplied to that argument generally needs to guarantee a compatible non-null value.

query GetUser($id: ID!) {
  user(id: $id) {
    id
  }
}

Using ID! makes it clear that the operation expects a non-null ID. Understanding where ! appears is important when working with variables, lists, and input objects.

Variables with Enum Types

GraphQL schemas can define enum types that restrict a value to a predefined set of names. Variables can use those enum types just like scalar types.

query GetProducts($sort: ProductSort!) {
  products(sort: $sort) {
    id
    name
  }
}
{
  "sort": "PRICE_ASC"
}

Enum values are GraphQL enum values, not arbitrary strings. The value must match one of the enum members defined by the schema.

Variables with Custom Scalars

GraphQL schemas can define custom scalar types for values such as dates, timestamps, URLs, UUIDs, or other application-specific formats.

query GetEvents($date: DateTime!) {
  events(after: $date) {
    id
    title
  }
}
{
  "date": "2026-09-03T12:00:00Z"
}

The serialization and validation rules for a custom scalar are determined by the GraphQL server implementation. The client should follow the format documented by the API.

Variables and Directives

Variables can be passed to GraphQL directives when the directive accepts arguments of compatible types. Built-in directives such as @include and @skip are common examples.

query GetUser(
  $id: ID!
  $includeEmail: Boolean!
) {
  user(id: $id) {
    id
    name
    email @include(if: $includeEmail)
  }
}
{
  "id": "42",
  "includeEmail": true
}

Multiple Variables in One Operation

An operation can declare as many variables as its schema and application requirements need. Each variable has its own type and can be used in one or more compatible positions.

query SearchProducts(
  $term: String!
  $categoryId: ID
  $minPrice: Float
  $limit: Int = 20
) {
  products(
    search: $term
    categoryId: $categoryId
    minPrice: $minPrice
    limit: $limit
  ) {
    id
    name
    price
  }
}
{
  "term": "keyboard",
  "categoryId": "5",
  "minPrice": 50,
  "limit": 10
}

Variables Used Multiple Times

A variable can be used more than once when every usage is compatible with its declared type.

query Search(
  $term: String!
) {
  products(search: $term) {
    id
    name
  }

  categories(search: $term) {
    id
    name
  }
}

Using one variable for related arguments can keep an operation concise and ensures that those arguments receive the same input value.

Unused GraphQL Variables

A variable declared by an operation should be used by that operation. Declaring unnecessary variables can cause validation errors according to GraphQL's operation validation rules.

query GetUser(
  $id: ID!
  $name: String
) {
  user(id: $id) {
    id
    name
  }
}

In this example, $name is declared but not used. Removing unused variables makes the operation cleaner and avoids validation problems.

Common GraphQL Variable Errors

  • Required variable was not provided.
  • A variable was supplied with null even though its type is non-null.
  • The variable type does not match the expected argument type.
  • The variables JSON uses the wrong variable name.
  • An input object contains fields not defined by its input type.
  • A list contains values that do not match the declared element type.
  • An enum variable uses a value that is not defined by the enum.
  • A variable is declared but never used.
  • A variable is used in a location where its type is incompatible.
  • A custom scalar receives a value in an unsupported format.

How to Debug GraphQL Variable Errors

When a GraphQL operation fails because of variables, inspect the operation and variables object separately. This makes it easier to determine whether the problem is the declaration, the supplied value, or the way the variable is used.

  • Check every variable declaration in the operation.
  • Verify the variable name in the JSON object.
  • Compare the declared type with the schema argument type.
  • Check whether required variables are present.
  • Look for null values assigned to non-null variables.
  • Verify list structure and element types.
  • Check input object field names and nested structures.
  • Verify enum values against the schema.
  • Check custom scalar formats.
  • Inspect the GraphQL errors returned by the server.
query GetProduct($id: ID!) {
  product(id: $id) {
    id
    name
    price
  }
}
{
  "id": "42"
}

Starting with a small operation and a simple variables object is often easier than debugging a large query with many nested inputs and directives.

GraphQL Variables in JavaScript

GraphQL clients commonly represent variables as a JavaScript object. For example, a request library can send the GraphQL document together with the variables object.

const variables = {
  id: "42",
  includeReviews: true,
};

The exact request API depends on the GraphQL client or HTTP library. The important part is that the variable names and values match the GraphQL operation's declarations.

GraphQL Variables in TypeScript

TypeScript applications can define types for variables to catch some mistakes before a request is sent. Many GraphQL development workflows can also generate TypeScript types from a GraphQL schema and operation documents.

type GetUserVariables = {
  id: string;
};

const variables: GetUserVariables = {
  id: "42",
};

Generated types can provide stronger synchronization between GraphQL operations and application code, especially in larger projects.

GraphQL Variables vs Hardcoded Values

ApproachExampleTypical use
Hardcoded valueuser(id: "42")Fixed example or static request
Variableuser(id: $id)Dynamic application input

Hardcoded values are perfectly valid when a value is genuinely static. Variables become more useful when the same operation needs to work with changing input.

Best Practices for GraphQL Variables

  • Use variables for dynamic values instead of constructing GraphQL documents through string concatenation.
  • Choose the variable type that matches the schema argument type.
  • Use non-null types when the operation genuinely requires a value.
  • Use input objects for complex mutation data when the schema provides them.
  • Keep variable names descriptive and consistent with their purpose.
  • Avoid declaring variables that the operation does not use.
  • Validate variable values before sending requests when appropriate.
  • Keep variables separate from the GraphQL operation document.
  • Use generated GraphQL types in TypeScript projects when practical.
  • Inspect both the GraphQL document and variables object when debugging.
  • Do not log sensitive variable values unnecessarily.
💡 A useful development pattern is to treat the GraphQL document and variables object as two separate pieces of a request. If the same operation can be reused with different values, variables are usually a better fit than generating a new query string for every request.

Frequently Asked Questions

What are variables in GraphQL?

GraphQL variables are named values supplied separately from a query or mutation. They allow an operation to receive dynamic input without embedding that input directly into the GraphQL document.

How do you define a variable in GraphQL?

A variable is defined after the operation name using a dollar sign, a variable name, and an input type, such as $id: ID!.

Where are GraphQL variable values provided?

Variable values are commonly provided in a separate JSON object called the variables object. Its property names correspond to the variables declared by the GraphQL operation.

What does ! mean in a GraphQL variable type?

The exclamation mark makes the type non-null. A variable such as $id: ID! must receive a non-null value unless the operation's default-value rules provide an applicable alternative.

Can GraphQL variables contain objects?

Yes. Variables can use schema-defined input object types, including nested input objects and lists. This is especially common with complex mutations.

Can GraphQL variables be used in mutations?

Yes. Variables are widely used with mutations to pass form data, identifiers, configuration values, and structured input objects.

Why is my GraphQL variable not working?

Common causes include a missing required variable, a variable name mismatch, an incompatible type, an invalid input object, a null value for a non-null type, an invalid enum value, or an incorrectly formatted custom scalar.

Helpful GraphQL and JSON Tools

Several developer tools can make working with GraphQL variables easier. Variable formatters can help keep complex variables JSON readable, while query formatters improve the structure of GraphQL documents. Endpoint testers can send complete GraphQL requests for debugging, and JSON formatters and validators can help verify the variables object before it is submitted to an API.

Conclusion

GraphQL variables provide a clean way to separate an operation from the dynamic values it receives. They work with queries, mutations, directives, lists, input objects, enums, custom scalars, and default values.

The basic pattern is simple: declare each variable with a compatible GraphQL input type, reference it with a dollar sign inside the operation, and provide its value separately in the variables object. Understanding nullability, list syntax, input objects, and type compatibility is especially important when working with larger GraphQL APIs.

Found an issue?

Found an error, outdated information, or something missing from this article? Let me know through the Contact page.

Your feedback helps improve our articles and keep them accurate and useful.