Does Fastify Work With Sanity?
Fastify and Sanity work together seamlessly—use Fastify as your backend API server to fetch and serve content from Sanity's headless CMS.
Quick Facts
How Fastify Works With Sanity
Fastify is an excellent choice for building APIs that consume Sanity content. The pattern is straightforward: use Fastify's lightweight routing to create endpoints that query Sanity's Content Delivery Network via the `@sanity/client` library. Sanity provides real-time APIs and webhooks, making it simple to build dynamic backends that respond to content changes. Fastify's low overhead and plugin architecture make it particularly suited for this—you can build a performant content API in minutes. The developer experience is smooth: define Sanity schemas in your CMS, install the client SDK, and start querying from your Fastify routes. You'll typically wrap Sanity queries in route handlers, optionally caching results with Fastify's built-in caching or Redis integration. This combination scales well from simple blogs to complex multi-tenant applications.
Best Use Cases
Quick Setup
npm install fastify @sanity/client dotenvimport Fastify from 'fastify';
import { createClient } from '@sanity/client';
const fastify = Fastify();
const sanity = createClient({
projectId: process.env.SANITY_PROJECT_ID,
dataset: process.env.SANITY_DATASET,
apiVersion: '2024-01-01',
useCdn: true,
});
fastify.get('/posts', async (request, reply) => {
const posts = await sanity.fetch(
`*[_type == "post"] | order(publishedAt desc)[0...10]`
);
return posts;
});
fastify.get('/posts/:slug', async (request, reply) => {
const { slug } = request.params as { slug: string };
const post = await sanity.fetch(
`*[_type == "post" && slug.current == $slug][0]`,
{ slug }
);
return post || reply.notFound();
});
await fastify.listen({ port: 3000 });Known Issues & Gotchas
Sanity's Content Delivery API has rate limits (500 req/min on free tier)
Fix: Implement caching in Fastify using decorators or a cache plugin. Consider upgrading Sanity plan for production traffic.
CORS headers needed if frontend is on different origin
Fix: Use @fastify/cors plugin: `await fastify.register(require('@fastify/cors'))`
Stale content if not handling webhooks properly
Fix: Set up Sanity webhooks to POST to Fastify endpoints that invalidate cached content on publish
Alternatives
- •Next.js API routes + Sanity (tighter integration, built-in caching, but less flexible)
- •Express.js + Sanity (more ecosystem plugins, heavier framework overhead)
- •Remix + Sanity (better data loading patterns, but opinionated framework)
Resources
Related Compatibility Guides
Explore more compatibility guides