Build at Light Speed

Payload can power everything from headless CMS to advanced internal enterprise tools—all in modern TypeScript and React. It’s meant to give you what you need, and then get out of your way.

See the Docs

Define your schema in code and get a full TypeScript backend and CMS admin panel—instantly.

  • Step 01

    Write a TypeScript config.

    • Dead simple to learn
    • Build and organize it how you want
    • Check it into Git and version control
    • Share code between projects
    Config docs

    payload.config.ts

    import { buildConfig } from 'payload/config'
    import { postgresAdapter } from '@payloadcms/db-postgres'
    import { viteBundler } from '@payloadcms/bundler-vite'
    import { lexicalEditor } from '@payloadcms/richtext-lexical'
    export default buildConfig({
    bundler: viteBundler(),
    db: postgresAdapter({}),
    editor: lexicalEditor({}),
    collections: [
    Admins,
    Media,
    Products,
    Orders,
    ],
    globals: [
    MainMenu,
    Footer,
    SocialMedia
    ],
    })
  • Step 02

    Boom—you've got a CMS

    Everything is dynamic and based on your config. No code generation, so no breaking changes when we update. Extend anything.

    01

    Database

    Get a perfectly clean, reusable schema that scales with you. Fully portable and not Payload-specific.

    Database representationDatabase representation
    02

    API

    Powerful and reusable REST, GraphQL and Local Node APIs to power the backend of any project.

    API representationAPI representation
    03

    Admin UI

    A CMS-grade editor generated for you, but still completely extensible in React. White-label, swap in your own components, and more.

    Admin UIAdmin UI

  • Step 03

    Now build whatever you dream up

    Every single part of Payload is meant to be extensible. Out of the box, it delivers incredible power with minimal effort, but its code-based nature means that you can build on top of it to power anything you can imagine.

    Self-hosted

    Keep full control over your Express app

    Nothing is imposed on the structure of your app. Just initialize Payload and pass it your Express app. Maintain your own functionality outside of Payload.

    Learn how
    const payload = require('payload');
    const express = require('express');
    const app = express();
    // Do whatever you want with your app.
    // Just pass it to Payload and everything
    // will be scoped to Payload routers.
    payload.init({
    secret: 'XXXXXXXXXXXXXXXXXXXXXXXXX',
    express: app,
    });
    app.listen(process.env.PORT, () => {
    console.log(`Application listening on ${3000}...`);
    });

    Access Control

    Extremely powerful access control

    Secure your data by writing access control functions based on either a document or field level. Build out your own RBAC or any access control pattern you need.

    More on access control
    const Orders = {
    // ...
    access: {
    create: () => true, // Everyone can create
    read: ({ req: { user } }) => {
    if (user) {
    return { // Users can only read their own
    owner: { equals: user.id, },
    };
    }
    return false; // Not logged in? Can't read any
    },
    update: ({ req: { user } }) => {
    // Only Admins can update Orders
    if (user.roles.includes('admin')) return true;
    return false;
    },
    delete: () => false, // No one can delete
    },
    };

    20+ Field Components

    Over 20 built-in field types

    Payload’s field types are far and away more robust than any other headless CMS out there. Dynamic fields like Arrays and Blocks unlock incredible potential while purpose-built fields like Relationship and GeoJSON allow for incredibly flexible data modeling.

    See all fields
    Blocks and Tabs fieldsBlocks and Tabs fields

    Extend with Hooks

    Extend everything Payload does with Hooks

    Both document and field-level hooks expose a ton of potential. Customize output, sanitize incoming data, or easily integrate with third-party platforms. The pattern is extremely powerful.

    Learn about Hooks
    const Customers = {
    // ...
    hooks: {
    beforeChange: [
    // Before the Customer is created or updated,
    // sync it to Hubspot
    syncCustomerToHubspot,
    ],
    afterChange: [
    // Send the new Customer a welcome email
    // after it's successfully created
    sendWelcomeEmail,
    ],
    afterRead: [
    // Dynamically append user's active subscriptions
    // straight from Stripe
    addStripeSubscriptions,
    ],
    },
    };

    Custom React Components

    Swap in your own React components

    Want to add a view to the Admin UI? Simple. How about building a custom field type? Or maybe swap in your client’s branding? Every high-level component in the Admin dashboard is easily swappable with your own React component. Customize existing views or field types—or even add your own routes—with an extremely intuitive API.

    Learn how
    Custom Components showing a custom SEO fieldCustom Components showing a custom SEO field