Skip to main content

aws-appsync-js

A tiny, fully-typed, zero-dependency GraphQL client for AWS AppSync. Plain fetch under the hood, end-to-end TypeScript inference on top, ~3Β KB gzipped.

The whole API, basically
import { AppSyncClient } from 'aws-appsync-js';

const client = new AppSyncClient({
url: 'https://xxx.appsync-api.us-east-1.amazonaws.com/graphql',
auth: { type: 'apiKey', apiKey: 'da2-…' },
});

const { events } = await client.request<{ events: Event[] }>(`
query { events { id name } }
`);

Two lines of setup, one line per query, and the response is typed exactly the way you say it is. The rest of these docs are "and also…".

Why this exists​

The AppSync ecosystem has two extremes:

  1. aws-amplify β€” full SDK, ~200Β KB minified, expects you to live inside its world.
  2. Hand-rolled fetch + SigV4 + auth-mode plumbing β€” three subtle things to get right, per service.

aws-appsync-js is the missing middle: a tiny GraphQL-over-fetch client that:

  • Understands AppSync β€” every auth mode, retry semantics, the JSON error shape AppSync actually uses.
  • Speaks real TypeScript β€” not any-flavoured types. Discriminated auth unions, TypedDocumentNode inference, typed error classes.
  • Doesn't drag in anything else β€” zero runtime dependencies. SigV4 written from scratch on node:crypto / SubtleCrypto.
  • Works everywhere β€” Node β‰₯ 18.17, modern browsers, Cloudflare Workers, Vercel Edge, Deno, Bun.

At a glance​

What's inside​

CapabilityStatus
All 5 AppSync auth modesβœ…
TypedDocumentNode inferenceβœ…
AbortSignal + per-request timeoutsβœ…
Retries with exponential backoff + jitterβœ…
Typed error classes with stable codeβœ…
Introspection helperβœ…
Custom fetch injectionβœ…
Subscriptions (WebSocket / MQTT-over-WS)🚧 planned
Client-side cache / normalisation❌ by design β€” bring your own (TanStack Query, SWR, Zustand, …)

Next steps​