npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

nextjs-cms

v0.5.65

Published

A headless and comprehensive type-safe content management system built with Nextjs. This package provides all the core functionality for building dynamic CMS-powered websites with authentication, database integration, and extensible content sections.

Readme

nextjs-cms

A headless and comprehensive type-safe content management system built with Nextjs. This package provides all the core functionality for building dynamic CMS-powered websites with authentication, database integration, and extensible content sections.

Features

  • Type-Safe API: Built with tRPC for end-to-end type safety
  • Authentication System: JWT-based authentication with React hooks
  • Database Integration: Drizzle ORM with MySQL support
  • Extensible Content Sections: Modular section system with custom fields
  • File Management: Built-in file upload and management capabilities
  • Internationalization: Multi-language support with i18next
  • Validation: Zod schema validation throughout
  • Testing: Comprehensive unit and integration tests

Installation

Please install using the create-nextjs-cms package:

npx create-nextjs-cms
# or
yarn create nextjs-cms
# or
pnpm create nextjs-cms
# or
bun create nextjs-cms

Quick Start

1. Configure Your CMS

Create a cms.config.ts file in your project root:

import { CMSConfig } from 'nextjs-cms/core/config'

export default {
  ui: {
    title: 'My CMS Site',
    defaultTheme: 'dark',
    logo: '/logo.svg'
  },
  sections: {
    path: './sections',
    strict: false,
    category: { allowRecursiveDelete: false }
  },
  media: {
    upload: {
      path: './public/uploads',
      preserveExtension: true
    }
  }
} satisfies CMSConfig

2. Create Content Sections

Create a section file in your sections folder. Sections are created using helper functions (simpleSection, hasItemsSection, or categorySection), and fields are created using field helper functions.

Simple Section Example

// sections/about.section.ts
import { richTextField } from 'nextjs-cms/core/fields'
import { simpleSection } from 'nextjs-cms/core/sections'

const about = richTextField({
  name: 'about',
  label: 'About',
  required: true,
  order: 1,
})

export default simpleSection({
  name: 'about',
  order: 1,
  title: 'About Page',
  db: {
    table: 'about',
  },
  fields: [about],
})

Has Items Section Example

// sections/blog.section.ts
import { textField, richTextField, dateField, photoField } from 'nextjs-cms/core/fields'
import { hasItemsSection } from 'nextjs-cms/core/sections'

const title = textField({
  name: 'title',
  label: 'Title',
  required: true,
  order: 1,
})

const content = richTextField({
  name: 'content',
  label: 'Content',
  required: true,
  order: 2,
})

const publishDate = dateField({
  name: 'publish_date',
  label: 'Publish Date',
  required: false,
  order: 3,
})

const coverPhoto = photoField({
  name: 'coverphoto',
  label: 'Cover Photo',
  required: false,
  order: 4,
})

export default hasItemsSection({
  name: 'blog',
  order: 1,
  headingField: title,
  title: {
    section: 'Blog',
    singular: 'Post',
    plural: 'Posts',
  },
  db: {
    table: 'blog',
  },
  fields: [title, content, publishDate, coverPhoto],
})

Category Section Example

// sections/categories.section.ts
import { textField, photoField } from 'nextjs-cms/core/fields'
import { categorySection } from 'nextjs-cms/core/sections'

const title = textField({
  name: 'title',
  label: 'Title',
  required: true,
  order: 1,
})

const image = photoField({
  name: 'image',
  label: 'Image',
  required: false,
  order: 2,
})

export default categorySection({
  name: 'categories',
  order: 1,
  headingField: title,
  title: {
    section: 'Categories',
    singular: 'Category',
    plural: 'Categories',
  },
  db: {
    table: 'categories',
  },
  fields: [title, image],
  depth: 2, // Allow nested categories
})

API Reference

Core Modules

API (nextjs-cms/api)

  • appRouter: Main tRPC router with all CMS endpoints
  • createCaller: Server-side API caller factory
  • createTRPCContext: Context factory for tRPC requests

Authentication (nextjs-cms/auth)

  • JWT Management: Token creation, verification, and refresh
  • React Hooks: useAxiosPrivate, useRefreshToken
  • Server Actions: Authentication utilities for server components

Core (nextjs-cms/core)

  • Config: CMS configuration management (CMSConfig)
  • Fields: Content field helper functions (textField, richTextField, dateField, photoField, etc.)
  • Sections: Section helper functions (simpleSection, hasItemsSection, categorySection)
  • Submit: Form submission handlers (SimpleSectionSubmit)
  • Factories: Section factory for loading sections (SectionFactory)

Database (nextjs-cms/db)

  • Client: Database connection and query utilities
  • Schema: Database schema definitions
  • Migrations: Drizzle migration helpers

Validators (nextjs-cms/validators)

Zod validators for all field types:

  • Text fields, numbers, dates
  • File uploads (images, documents, videos)
  • Rich text content
  • Select fields and checkboxes

Translations (nextjs-cms/translations)

  • Multi-language support
  • Dictionary management
  • i18next integration

Field Types

The CMS supports various field types out of the box. Each field is created using a helper function that accepts a configuration object:

  • Text: textField({ name, label, required, order, ... }) - Single-line text input
  • TextArea: textAreaField({ name, label, required, order, ... }) - Multi-line text input
  • RichText: richTextField({ name, label, required, order, ... }) - Rich text editor (TinyMCE)
  • Number: numberField({ name, label, required, order, ... }) - Numeric input
  • Date: dateField({ name, label, required, order, ... }) - Date picker
  • Select: selectField({ name, label, required, order, options, ... }) - Dropdown selection
  • SelectMultiple: selectMultipleField({ name, label, required, order, ... }) - Multi-select field
  • Checkbox: checkboxField({ name, label, required, order, ... }) - Boolean checkbox
  • Photo: photoField({ name, label, required, order, size, thumbnail, ... }) - Image upload
  • Video: videoField({ name, label, required, order, ... }) - Video file upload
  • Document: documentField({ name, label, required, order, type, ... }) - Document file upload
  • Color: colorField({ name, label, required, order, ... }) - Color picker
  • Map: mapField({ name, label, required, order, ... }) - Location/map field
  • Tags: tagsField({ name, label, required, order, ... }) - Tag input field
  • Password: passwordField({ name, label, required, order, ... }) - Password input
  • FieldGroup: fieldGroup({ title, order, fields }) - Group multiple fields together

Field Configuration

All fields require at minimum:

  • name: string - Unique field identifier (used in database)
  • label: string - Display label for the field
  • required: boolean - Whether the field is required
  • order: number - Display order of the field

Additional options vary by field type. See the API documentation for each field type for complete configuration options.

Section Types

Simple Section

Basic content sections with a single record. Use simpleSection() for pages like "About", "Contact", or "Settings" that have only one instance.

Key characteristics:

  • Single record (always has ID = 1)
  • No listing/browse page
  • Direct edit page
  • Requires title property

Example use cases: About page, Privacy Policy, Site Settings

Has Items Section

Sections that can contain multiple items. Use hasItemsSection() for collections like blog posts, products, or articles.

Key characteristics:

  • Multiple records
  • Browse/listing page with pagination
  • Individual item pages
  • Requires headingField and title object with section, singular, and plural properties
  • Optional coverPhotoField, search, and gallery configuration

Example use cases: Blog posts, Products, News articles, Events

Category Section

Sections organized by categories with hierarchical structure. Use categorySection() for nested category systems.

Key characteristics:

  • Hierarchical structure (configurable depth)
  • Parent-child relationships
  • Requires headingField and title object
  • Optional depth property (default: 1, no nesting)
  • Automatically adds parent_id and level fields when depth > 1

Example use cases: Product categories, Content categories, Navigation menus

Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to the main repository.

License

MIT License - see LICENSE file for details.