graphqlade

A complete library for GraphQL + TypeScript development on server- and client-side

Usage no npm install needed!

<script type="module">
  import graphqlade from 'https://cdn.skypack.dev/graphqlade';
</script>

README

GraphQLade

NPM version Build status Coverage

GraphQLade is a lightweight but complete library for GraphQL + TypeScript development on both server- and client-side. It emphasizes a GraphQL first approach with maximum type-safety through interface/type generation from GraphQL schemata and GraphQL client operations.

With a rich feature set and zero dependencies besides GraphQL.js, it provides a highly integrated foundation for GraphQL servers and clients at around 4000 lines of readable, tested code—all in one place.

Why?

Existing stacks (e.g. Apollo, GraphQL Tools, TypeGraphQL) are obtrusive in some ways (high lock-in, missing features) and over-engineered in others, while type-safety is often a secondary concern rather than a design principle.

Additionally, most stacks suffer from significant fragmentation. Issues are spread across many packages and maintainers, making it hard to reason about fitness of a particular combination of dependencies and stalling improvements to the ecosystem.

Design principles

GraphQL first

GraphQL schemata and operations are defined through spec-compliant, plain GraphQL files.

Type-safety through code generation

GraphQLade generates a complete set of TypeScript types and interfaces from GraphQL sources, both for schemata and operations, including type tables mapping operation names to their variable and result interfaces.

Enhance and integrate with GraphQL.js

GraphQLade provides a library of type-safe runtime helpers for building HTTP and WebSocket servers, resolvers and clients. They transparently integrate with GraphQL.js, introducing very few additional concepts and staying close to the "language" used by GraphQL.js.

Features

Server-side

  • Server-side code generation from GraphQL schemata
    • Generates types for
      • objects,
      • interfaces,
      • unions,
      • enums,
      • resolvers,
      • arguments,
      • directives,
      • ...
    • Source type substitution
    • Type mapping for scalars
    • Generated types are compatible with
    • Watch mode
  • Runtime helpers for building executable GraphQL.js schemata
  • Runtime helpers for serving GraphQL over HTTP
  • Operation parser with LRU-cache
  • Server-side GraphQL web sockets, including convenient server helpers

Learn more about GraphQLade's server-side workflow →

Client-side

  • Client-side code generation from GraphQL operations and remote schemata.
    • Generates interfaces for variables and results of named operations.
    • Generates tables mapping operation names to their respective variable and result interfaces.
    • Validates operations against a GraphQL API at build time.
    • Type mapping for scalars
    • Watch mode
  • Client-side GraphQL web sockets

Learn more about GraphQLade's client-side workflow →

General

  • Reads combined GraphQL documents recursively from directories.
    • Raises syntax errors with useful locations in source files.
  • Almost dependency-free:
    • graphql (peer dependency)
    • typescript (optional, required for watch mode, but you'll have typescript anyway)
    • prettier (optional, but you'll get ugly code)
    • ws (optional, required for server-side web socket support)
    • got or some other HTTP request library (optional, required only for remote introspection during client-side code generation)
  • Class-based implementation with granular methods
    • Customization is easily possible through inheritance and method overrides.

Missing features

  • Federation compatible with the Apollo Federation specification is planned, including a gateway implementation.
  • Automatic persisted queries are planned. There's no clear/emerging standard but it seems viable to add APQs in an opt-in fashion and make the protocol compatible with the Apollo stack.
  • Caching was ignored so far. Apollo's @cacheControl style is viable but the benefit seems questionable.
  • Writing operations inline (with e.g. template strings tagged gql) are not planned. The current approach of separate and named operations in pure GraphQL, combined with interface/client generation, requires the least tooling and has great developer ergonomics (type safety, auto-completion, no duplication).
  • File uploads are out of scope. It's recommended to use regular HTTP endpoints.
  • IDE plug-ins are out of scope or not even required since GraphQLade doesn't introduce non-standard concepts. Existing plug-ins work well so far.