DEV Community

Arseniy
Arseniy

Posted on

After 5 Years of Coding, I Switched to a CMS – Here's Why

My Journey in the Node.js and React/Next.js Stack

For the past five years, I have been deeply involved in full-stack development using Node.js, React, and Next.js. I built various applications, from simple Saas applications to complex eCommerce platforms. While working with these technologies, I realized that a significant amount of my time was being spent on repetitive tasks—writing boilerplate code, setting up CRUD operations, and defining schemas and types over and over again.

The Problem: Wasting Time on Boilerplate Code

When I analyzed my workflow, I found that 80-90% of my development time was spent on things that didn’t add direct value to the product itself. Setting up authentication, structuring API routes, and defining database schemas became a tedious and time-consuming process. This inefficiency was not just slowing down development but also affecting productivity and innovation.

Discovering Payload CMS

While searching for ways to optimize my workflow, I came across Payload CMS. It’s a modern headless CMS built on Node.js and TypeScript that allows developers to focus on building products rather than reinventing the wheel. What caught my attention was its flexibility—Payload provides full control over the database, authentication, and APIs without unnecessary complexity.

How Payload CMS Reduces Boilerplate

Payload simplifies CRUD operations, authentication, and API handling with minimal setup. Instead of manually defining schemas and API endpoints, Payload allows you to define collections, relationships, and access control in a structured way. This eliminates a large chunk of repetitive work and lets developers focus on building the actual business logic.

Example: Traditional API vs. Payload CMS

Without Payload CMS (Manual Approach):

  1. Define database schemas in PostgreSQL or MongoDB.
  2. Write models using an ORM like Drizzle or Prisma.
  3. Create API routes for CRUD operations.
  4. Implement authentication and permissions manually.

With Payload CMS:

  1. Define a collection in a simple configuration file.
  2. Authentication and access control are built-in.
  3. API endpoints are automatically generated.
  4. Hooks allow for custom business logic without unnecessary complexity.

Using Payload CMS for eCommerce – ShopNex Example

To put Payload CMS to the test, I decided to use it for an eCommerce project. I'm using ShopNex, an open-source eCommerce template built on Payload CMS. Here’s how you can set it up:

Step 1: Clone the Repository and install dependencies.

git clone git@github.com:shopnex-ai/shopnex.git
cd shopnex
pnpm i
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure Environment Variables

Rename .env.example to .env and update the necessary configurations such as the database URL, authentication settings, and API keys.

CJ_CONFIGURATIONS is optional.

PAYLOAD_SECRET should be a random string used for encryption.

DATABASE_URI is the database connection string. You can use SQLite or PostgreSQL (you will need to use postgresAdapter for postgres).

You can find these configurations in payload.config.ts:

db: sqliteAdapter({
        client: {
            url: process.env.DATABASE_URI || "",
        },
    }),
Enter fullscreen mode Exit fullscreen mode

Step 3: Run the code

pnpm run dev
Enter fullscreen mode Exit fullscreen mode

When your app is up and running, you can explore it using the following links:

Storefront: http://localhost:3000/ – This is the main store interface. We'll return to it later.

Admin Panel: http://localhost:3000/admin – This is where you can configure your storefront.

Start by visiting http://localhost:3000/admin. The first time you access it, you'll be prompted to create a user account. Once that's done, you'll be taken to the dashboard, where you can manage all configurations.

The first step is to ensure everything is working correctly. Let's navigate to the Hero section and add some content.
Image description
Once you're done, save your changes and visit http://localhost:3000/ to see the updates.
Image description
To illustrate power of Payload CMS you can go to the Products.tsx and notice every field has own purpose:

export const Products: CollectionConfig = {
    // Unique identifier for the collection
    slug: "products",

    // Access control: Only admins can create, update, and delete; anyone can read
    access: {
        create: admins,
        delete: admins,
        read: anyone,
        update: admins,
    },

    admin: {
        // Field to use as the title in the admin panel
        useAsTitle: "title",

        // Organizing the collection under a specific group
        group: groups.catalog,

        // Default columns shown in the admin panel
        defaultColumns: ["title", "variants", "collections"],
    },

    hooks: {
        beforeRead: [
            async ({ doc, req }) => {
                // Fetch global store settings to retrieve the currency
                const storeSettings = await req.payload.findGlobal({
                    slug: "store-settings",
                });

                // Assign the currency from store settings to the product document
                doc.currency = storeSettings.currency;
            },
        ],
    },

    fields: [
        {
            // Product ID from supplier side, disabled in the admin
            name: "pid",
            type: "text",
            admin: {
                disabled: true,
            },
        },
        {
            // Product title, required field
            name: "title",
            type: "text",
            required: true,
        },
        {
            // Currency field, auto-filled from store settings and disabled in admin
            name: "currency",
            type: "text",
            admin: {
                disabled: true,
            },
        },
        {
            // Checkbox to control product visibility in the store
            label: "Visibility",
            name: "visible",
            type: "checkbox",
            admin: {
                position: "sidebar", // Displayed in the sidebar
            },
            defaultValue: true, // Default visibility is enabled
        },
}
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

Payload CMS has significantly improved my development workflow, allowing me to focus on building features instead of writing boilerplate code. Whether you’re working on an eCommerce site, a SaaS product, or any other web application, Payload can help streamline your development process.

Have any questions or thoughts? Drop a comment below, and let’s discuss!

Top comments (0)