• For developers

Don’t spend your time and tokens rebuilding a CMS.

Start with a complete open source Node.js CMS foundation, then focus on the schemas, frontend, and product-specific work that sets your product apart.

npm create apostrophe@latest

Build on years of CMS research and decisions you don't have to make

ApostropheCMS already handles the editorial UX, workflow, permissions, localization, media, and platform behavior you’d otherwise have to design, build, and maintain yourself. All open source unless marked otherwise.

Everything you need, nothing you don't

  • In-context visual editing

    • Edit on the real page

    • Add and arrange widgets

    • Preview by breakpoint

  • Layout and styling tools

    • Global and per-widget styles, limited to the controls you define

    • Layout widget allows editors to add, remove, and resize columns per section

  • Editorial workflow

    • A flow that covers drafts, preview, and publishing

    • Submission workflow for lightweight editorial governance

  • Version control

    • See who changed what and when

    • Support for draft versions

    • Restore versions

  • SEO support

    • Built-in meta fields, robots.txt, and sitemaps, redirects

    • JSON-LD structured data

    • AI-powered SEO Assistant (Pro, Assembly)

  • SSO

    • Sign in with Google Workspace, Okta, Azure AD and other identity providers

    • Uses your existing accounts, so there are no separate CMS passwords to manage

  • Media management

    • Shared image and file library

    • Crops and focal points

    • Video and image widgets as part of the open source core

Choose the Node.js stack that fits your needs

ApostropheCMS runs on Node.js 22+. Use SQLite for local development and small single-server sites, and PostgreSQL 14+ or MongoDB in production. Self-host anywhere Node runs, or use managed hosting from Apostrophe. Backends are written in JavaScript. The Astro starter kits use TypeScript on the frontend, and the Astro integration ships its own type definitions.

ApostropheCMS stack diagram

Learn the simple set of concepts that powers the whole system

Once you have the core concepts down, planning an architecture and extending the CMS in a way that works for your whole team is easy. And, of course, working with your AI greatly reduces learning time.

Pages: Content with its own URL, like home, landing and about pages.

Pieces: Reusable structured content, like articles, people, events and products.

Widgets: The components editors add to a page, like testimonials, image blocks and feature cards.

Areas: The places on a page where you decide which widgets editors can use.

Apostrophe CMS content model
  • Define your content model in code

Define a content model that gives editors freedom within the boundaries you set

AI makes it easier than ever to produce content and visuals, but the challenge is keeping the content and design consistent, useful, secure, and true to your standards.

Example: How to build a custom widget

  1. You write the schema

    More realistically, you take your team's detailed requirements to an agent, and let that agent write the schema using ApostropheCMS docs for context.

    modules/testimonial-widget/index.js
    export default { extend: '@apostrophecms/widget-type', options: { label: 'Testimonial' }, fields: { add: { quote: { type: 'string', label: 'Quote', textarea: true, required: true, max: 280 }, name: { type: 'string', label: 'Name', required: true }, role: { type: 'string', label: 'Role and company' }, _photo: { type: 'relationship', label: 'Photo', withType: '@apostrophecms/image', max: 1 }, style: { type: 'select', label: 'Style', choices: [ { label: 'Light', value: 'light' }, { label: 'Dark', value: 'dark' } ], def: 'light' } } } };
  2. Editors open the widget editor

    Apostrophe turns the schema into editing fields automatically—a textarea for the quote, text inputs for name and role, an image picker for the photo, and a select for style—with no extra UI code required. When in-line editing is a good fit for the specific content, the path to build a widget editable on the page is simple.

    Editor modal in ApostropheCMS showing a testimonial form
  3. Visitors see the result

    Define the model once. Editors get exactly the controls you allow, and your frontend gets predictable, structured content.

    Example of a testimonial widget
  • Developer freedom

Build your frontend in Astro or opt for Standalone Apostrophe

With Astro, you choose the UI framework that fits the project, and editors still get the advantage of in-context visual editing (right on the page). Don't want or need a separate frontend? Apostrophe's native templates use JSX by default.

frontend/src/widgets/TestimonialWidget.astro --- import { getAttachmentUrl } from '@apostrophecms/apostrophe-astro/lib/attachment.js'; const { widget } = Astro.props; const photo = widget._photo?.[0]; // just use Astro component syntax directly, or import React, Vue, Svelte, etc. --- <figure class={`testimonial testimonial--${widget.style}`}> <blockquote>{widget.quote}</blockquote> <figcaption> {photo && <img src={getAttachmentUrl(photo, { size: 'one-sixth' })} alt="" />} <span>{widget.name}</span> {widget.role && <span>{widget.role}</span>} </figcaption> </figure>

Use the REST API when not using the ApostropheCMS frontend

For native apps, integrations and other systems, your pages and pieces are available through the REST API. Requests need an API key by default. To make a page or piece type public, list the fields to share in its publicApiProjection option. Public access is read-only.

API key auth

javascript
const response = await fetch('https://example.net/api/v1/article?perPage=10', { headers: { Authorization: 'ApiKey your-api-key' } }); const { results } = await response.json();
  • Extend without forking

Make it yours without breaking the CMS

Add the fields, content types and features that are specific to your business in your own project modules. Apostrophe’s core stays a dependency you update, not code you maintain.

Bring in the data that makes your business unique

Connect the systems you already run, and turn them into widgets editors can place anywhere you allow. Each of the concepts below is a project module, which means it would be your code, your data source, and an editing experience Apostrophe builds from your schema.

Example of a jobs widget in our CMS
Recruiting Platform

Job listings widget

Openings from an applicant tracking system, placed by editors on any careers page.

Example of a flight booking widget in a CMS
Travel company

Flights widget

Live flight data from a booking or schedule system, added to any destination page.

Example of a local delivery widget with an address showing
Retail brand

Local delivery widget

Shoppers enter an address to see what’s available nearby and order from local stores.

Keep your code separate

You extend core for project-level customizations, you don’t edit it. So npm update doesn’t touch your work.

Extend a core widget with a custom field

This file lives in your project. Core stays untouched, so it upgrades normally.

modules/@apostrophecms/image-widget/index.js
export default { fields: { add: { displayStyle: { type: 'select', label: 'Display style', choices: [ { label: 'Default', value: 'default' }, { label: 'Rounded', value: 'rounded' } ] } } } };

Add a field to a core widget. This file lives in your project, so core upgrades normally.

Upgrades stay routine

Monthly maintenance releases carry fixes and security patches, with no new features. Feature releases come quarterly and are announced in advance.

Accelerate safely with conventions coding agents can follow

Modules follow a consistent structure in predictable places, so agents know where code goes. Schemas are code, so every change an agent makes to your content model is a diff you can review. Well-crafted AGENTS.md and CLAUDE.md files come in every starter project repository, ensuring your agent gets off to the right start.

Built for production

Michelin Logo (Just Text that says Michelin)

Enterprise multisite without rebuilding the platform

Michelin uses ApostropheCMS to support modern web experiences with a platform that gives developers flexibility while providing editors with an intuitive publishing experience.

Read the case study
color bw logo

An Astro CMS with true in-context editing

The team at Color paired Astro's static site generation with ApostropheCMS's in-context visual editing. Marketers get an exceptional editing experience, and the site stays fast and secure.

Learn more about Color
icims logo bw

Multitenant websites customers can manage themselves

iCIMS powers customer-managed career sites with ApostropheCMS, giving organizations control over their own content while managing a large-scale platform from a single application.

Read the case study

"What brought Michelin Group to this CMS framework is a blend of modern technology and smooth admin experience. Its robust full-JavaScript open source stack is quite flexible and extendable, as experienced by our in-house development team."

Etienne Coursimault

Platform Owner at Michelin Digital Factory

  • Assembly

Make it a multitenant CMS

Apostrophe Assembly includes a module for managing multiple sites from a single installation.

  • Shared codebase with separate databases per tenant site

  • Central dashboard for managing tenant sites

  • Advanced permission model

  • Community edition

Open source, no lock-in

ApostropheCMS core is open source because developers should have control over the software they build on.

  • MIT licensed

  • Self-host anywhere Node.js runs

  • No proprietary runtime dependency

Build a proof of concept

  1. Create a project

    Run the CLI and pick Astro or Standalone, demo starter, and SQLite for the fastest path to PoC.

    npm create apostrophe@latest
  2. Add a widget or content type

    Define its fields in a module, like the testimonial widget above.

  3. Create a template

    Write the component in Astro or JSX that displays it on your frontend.

  4. Edit it on the page

    Log in and use the form Apostrophe builds from your schema.

Questions while you build? Ask in the Discord community or the r/apostrophecms subreddit.