100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
GraphQL

Custom Scalars

How to model domain-specific leaf values beyond GraphQL's five built-in scalars using serialize, parseValue, and parseLiteral.

Schema DesignAdvanced10 min readJul 10, 2026
Analogies

Custom Scalars

GraphQL's five built-in scalars cover only the most basic value types, so any domain-specific leaf value — a date, an email address, a JSON blob, a URL, geographic coordinates — is typically modeled as a custom scalar, declared in SDL with scalar DateTime. A custom scalar isn't defined by structure like an object type; instead, the server implementation supplies serialize, parseValue, and parseLiteral functions that convert between the internal representation (say, a JavaScript Date object) and the wire format the client actually sends and receives (typically an ISO-8601 string).

🏏

Cricket analogy: A match's 'DRS review time remaining' isn't a plain Int or String — it needs its own formatting and parsing rules, just as a custom scalar like Duration needs its own serialize/parse logic beyond the five GraphQL built-ins.

Implementing Serialize, ParseValue, and ParseLiteral

The three functions a custom scalar needs each handle a different data direction: serialize runs when sending a value from server to client (converting the internal representation to something JSON-safe, like turning a Date into an ISO string), parseValue runs when the client sends the scalar as a query variable (JSON input), and parseLiteral runs when the client writes the value directly inline in the query string (an AST literal), which matters because GraphQL's AST literal parsing is stricter and type-specific — a DateTime! literal typed directly in a query arrives as a StringValueNode, not a parsed JSON value, so parseLiteral has to inspect the AST node kind itself.

🏏

Cricket analogy: Converting a raw ball-by-ball feed into a scorecard display (serialize) is different work from parsing a manually-entered over count from a scorer's tablet (parseValue), just as GraphQL's serialize and parseValue handle output and input directions separately for a custom scalar.

graphql
scalar DateTime

type Match {
  id: ID!
  scheduledAt: DateTime!
}
javascript
const { GraphQLScalarType, Kind } = require('graphql');

const DateTimeScalar = new GraphQLScalarType({
  name: 'DateTime',
  description: 'ISO-8601 encoded UTC date-time string',
  serialize(value) {
    return value instanceof Date ? value.toISOString() : value;
  },
  parseValue(value) {
    return new Date(value); // value from JSON query variables
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.STRING) {
      return new Date(ast.value); // value from inline query literal
    }
    return null;
  },
});

Popular libraries like graphql-scalars already ship well-tested implementations for common needs — DateTime, EmailAddress, URL, JSON, PositiveInt, and dozens more — so it's usually better to reuse a maintained scalar than hand-roll parsing edge cases like timezone offsets or Unicode email validation.

A custom scalar with no validation logic in parseValue/parseLiteral (e.g. one that just passes the raw value through) defeats the purpose — it becomes indistinguishable from String in practice and gives clients false confidence that the server is enforcing a format it actually isn't.

  • Custom scalars model domain-specific leaf values that don't fit the five GraphQL built-ins.
  • A custom scalar is defined by behavior (serialize/parseValue/parseLiteral), not by structural fields.
  • serialize handles server-to-client output; parseValue and parseLiteral handle client-to-server input.
  • parseLiteral must inspect the AST node kind because inline query literals aren't parsed as JSON.
  • Reusing a maintained library (like graphql-scalars) is usually safer than writing scalar logic from scratch.
  • A custom scalar without real validation logic provides no more guarantee than a plain String.

Practice what you learned

Was this page helpful?

Topics covered

#GraphQL#GraphQLStudyNotes#WebDevelopment#CustomScalars#Custom#Scalars#Implementing#Serialize#APIs#StudyNotes#SkillVeris