Does NestJS Work With Payload CMS?

Partially CompatibleLast verified: 2026-02-20

You can use NestJS with Payload CMS, but they're better as separate services rather than tightly integrated—NestJS handles your API/business logic while Payload runs as a headless CMS.

Quick Facts

Compatibility
partial
Setup Difficulty
Moderate
Official Integration
No — community maintained
Confidence
high
Minimum Versions
NestJS: 9.0.0
Payload CMS: 2.0.0

How NestJS Works With Payload CMS

NestJS and Payload CMS can coexist in the same project, but the typical architecture treats them as distinct services communicating via REST or GraphQL APIs. Payload is a full-featured headless CMS with its own Express server, authentication, and database layer, while NestJS excels at building business logic and microservices. You have two main approaches: run them as separate services (recommended) where NestJS consumes Payload's API, or embed Payload as a plugin within a NestJS monorepo using Payload's custom server configuration. The latter requires careful dependency management since both frameworks have strong opinions about routing, middleware, and database connections. Most developers prefer the decoupled approach because it gives you independence—you can scale, update, or replace either service without affecting the other. If you need tight coupling (like accessing Payload's database directly from NestJS), you'll need to configure shared database connections and handle ORM conflicts between Payload's MongoDB integration and your NestJS TypeORM/Prisma setup.

Best Use Cases

Building a headless publishing platform where NestJS handles user subscriptions/payments and Payload manages editorial content
Enterprise CMS with custom microservices—Payload provides content management UI while NestJS services handle complex business logic (workflows, integrations, reporting)
E-commerce platform combining Payload for product catalogs and NestJS for order processing, inventory, and third-party APIs
Multi-tenant SaaS where Payload manages customer-facing content and NestJS handles tenant isolation, billing, and custom features

NestJS Service Consuming Payload CMS API

bash
npm install @nestjs/common @nestjs/core axios
typescript
import { Injectable } from '@nestjs/common';
import axios from 'axios';

@Injectable()
export class PayloadService {
  private readonly payloadUrl = 'http://localhost:3000/api';
  private readonly apiKey = process.env.PAYLOAD_API_KEY;

  async getPages() {
    const response = await axios.get(`${this.payloadUrl}/pages`, {
      headers: { Authorization: `Bearer ${this.apiKey}` },
    });
    return response.data;
  }

  async createArticle(data: any) {
    const response = await axios.post(
      `${this.payloadUrl}/articles`,
      data,
      { headers: { Authorization: `Bearer ${this.apiKey}` } }
    );
    return response.data;
  }
}

@Injectable()
export class ContentController {
  constructor(private payloadService: PayloadService) {}

  async getPublishedContent() {
    return this.payloadService.getPages();
  }
}

Known Issues & Gotchas

critical

Both frameworks want to own the Express/HTTP server if you try to run them together in one process

Fix: Keep them as separate services. Run Payload on port 3000 and NestJS on port 3001, communicate via HTTP/REST or GraphQL. This is the recommended architecture.

warning

Payload's authentication (JWT tokens) won't automatically work with NestJS guards unless you implement custom validators

Fix: Create a custom NestJS authentication strategy that validates Payload JWTs, or use separate auth systems and sync via API calls.

info

TypeScript type generation from Payload isn't automatic in NestJS—you need to manually maintain DTOs or use Payload's generated types

Fix: Use Payload's TypeScript collection type exports and import them into NestJS for end-to-end type safety across services.

warning

Database transaction coordination is difficult when services use different databases or connection pools

Fix: Design your system to avoid distributed transactions. Use eventual consistency patterns and webhooks for cross-service data synchronization.

Alternatives

  • Strapi + NestJS: Strapi is more lightweight than Payload and integrates more naturally with custom Node backends
  • Sanity + NestJS: Sanity is cloud-hosted and pairs well with NestJS through their GraphQL API, reducing operational overhead
  • NestJS + Directus: Directus is simpler and more API-first, making service decoupling cleaner

Resources

Related Compatibility Guides

Explore more compatibility guides