Launching March 1st, 2026

Services First.
Interface Second.

VelvetCMS is a service-oriented CMS. All logic lives in frontend-agnostic services. Three consumers — CLI, REST API, and Web admin — expose them independently. Use all three, two, one, or none.

$ composer create-project velvetcms/velvetcms
$ cd velvetcms && php velvet serve

Three Interfaces. One Codebase.

Business logic lives in services. Consumers are thin, optional wrappers. Disable any interface with a single config toggle.

Services
ContentService MediaService UserService AuthService SearchService +14 more

CLI

Automation, cron, CI/CD pipelines

REST API

SPAs, mobile apps, headless frontends

Web Admin

Content editing, media, settings

Headless? Enable only the API. Feed React, Vue, Next.js, whatever.
Traditional? Use the web admin and server-rendered templates.
Hybrid? All three at once. CLI for deploys, API for the app, admin for editors.

Content Without Compromise

Not a feature checklist — a coherent content workflow.

Block Editor

Compose with Blocks, Not HTML

Drag-and-drop content blocks with real-time preview. Text, images, code, embeds, custom types. Every block is self-contained with its own schema and rendering. Paste a YouTube or Twitter URL and it resolves to a rich embed automatically via oEmbed.

  • Custom block types — define schema, template, CSS
  • Multiple editing modes: visual blocks, Markdown, code
  • Content locking for concurrent editing
  • Reusable content templates across pages
// Register a custom block type
$blocks->register('callout', [
    'label' => 'Callout Box',
    'icon'  => 'megaphone',
    'fields' => [
        'style'   => ['type' => 'select', 'options' => ['info', 'warning', 'tip']],
        'title'   => ['type' => 'text'],
        'content' => ['type' => 'rich-text'],
    ],
    'template' => 'blocks.callout',
]);
Revisions & Staging

Edit Without Fear

Every save creates an automatic revision. Diff any two versions side-by-side with field-level and block-level change highlighting. Restore with one click. For bigger changes, use per-content staging — edit multiple pages, preview the result, then deploy everything atomically.

  • Visual side-by-side diff viewer in the admin
  • Named snapshots for milestone backups
  • Per-content staging, not a full site clone
  • Atomic deployment with one-click rollback
// Restore a previous revision
$content->restoreRevision($revisionId);

// Create a staging changeset
$changeset = $staging->createChangeset('Homepage redesign');
$staging->stage($homepage, $changeset);
$staging->stage($aboutPage, $changeset);

// Preview, then deploy
$staging->preview($changeset);  // staging URL
$staging->deploy($changeset);   // goes live
Workflows

From Draft to Published — Your Rules

Define review pipelines with approvals, role gates, and automatic transitions. A blog might need just draft to published. An enterprise site could go through legal review, editor approval, and scheduled publication. Shareable draft links let external reviewers see unpublished content without needing a CMS account.

  • Custom states and transitions per content type
  • Role-based gates with transition comments
  • Automatic actions on state change (notify, index, cache)
  • Shareable draft links for external reviewers
// Define a workflow
$workflow->define('editorial', [
    'states' => ['draft', 'review', 'approved', 'published'],
    'transitions' => [
        'submit'  => ['from' => 'draft',    'to' => 'review'],
        'approve' => ['from' => 'review',   'to' => 'approved',
                       'gate' => 'role:editor'],
        'publish' => ['from' => 'approved', 'to' => 'published'],
        'reject'  => ['from' => 'review',   'to' => 'draft'],
    ],
]);

Extend Everything

Hooks, a typed extension registry, modular architecture, and a queue system. Built to be extended, not forked.

Hooks System

Filters mutate data as it flows through the system. Actions trigger side effects. If you've used WordPress hooks, you already know the pattern — but typed, testable, and without the global soup.

// Filter: modify content before saving
$hooks->filter('content.before_save', function (Content $content) {
    $content->slug = Str::slug($content->title);
    return $content;
});

// Action: trigger side effects after publishing
$hooks->action('content.published', function (Content $content) {
    $search->index($content);
    $cache->invalidate('sitemap');
    $webhook->notify('content.published', $content);
});

Extension Registry

Typed registry for UI extension points — sidebar items, settings tabs, dashboard widgets, block types. Validation at registration, duplicate rejection, full discoverability.

Module System

Self-contained packages with routes, views, migrations, and commands. Version constraints, dependency resolution, conflict detection. VelvetCMS itself is a module running on Core.

Queue System

Offload heavy work — media processing, imports, search indexing, webhook delivery. Database-backed with retry logic, failure tracking, and priority lanes.

The Foundation

Built on a Purpose-Built Framework

VelvetCMS runs on Core — a lightweight, explicit PHP framework with no facades, no service locators, no magic. Every dependency is injected. Every call is traceable.

4 Runtime dependencies
~1ms Cold boot time
0 Facades or proxies
// Explicit. No magic. No surprises.
class PostController
{
    public function __construct(
        private ContentService $content,
        private CacheInterface $cache
    ) {}

    public function show(Request $req, string $slug): Response
    {
        $post = $this->cache->remember(
            "post:{$slug}",
            600,
            fn() => $this->content->findBySlug($slug)
        );

        return view('posts.show', ['post' => $post]);
    }
}

The Stack

Three layers. Use what you need.

🚀

Fleet

Multi-site orchestration, VelvetScore auto-scaling, white-label management.

VelvetCMS

Admin panel, block editor, media library, workflows, SEO, analytics.

Core

Routing, DI, query builder, caching, events, modules, multi-tenancy.

Just need a framework? Use Core alone. Apache 2.0, free forever.
Need a CMS? Add VelvetCMS. Installs as a module.
Managing many sites? Fleet handles orchestration at scale.

Everything You Need, Built In

19 submodules covering content, media, users, SEO, operations, and more. No plugins required for the basics.

🖼️
Media Library Auto image processing, WebP conversion, focal point cropping, folder organization, and usage tracking across all content.
🏷️
Taxonomies Categories, tags, and custom taxonomies. Hierarchical or flat. Attach to any content type.
👥
Users & Roles Granular permissions, registration modes (open or invite-only), password policies, and user metadata.
🔐
Dual Auth Session-based for the web admin, token-based for the API with scoped permissions. Optional two-factor via TOTP.
🧭
Menu Builder Drag-and-drop navigation with unlimited nesting. Content links, taxonomy links, external URLs.
🔍
SEO & Structured Data Auto meta tags, OpenGraph, JSON-LD per content type, sitemap.xml generation, readability scoring.
📈
Privacy-First Analytics Page views and referrers without cookies or third-party scripts. GDPR-compliant out of the box.
📅
Scheduling Future publishing with a visual calendar view. Expiration dates and auto-unpublish.
🔗
Content Relationships Bidirectional links, series, translation connections. "What links to this?" queries built in.
🔄
Redirects 301, 302, 307, 308 with exact, wildcard, and regex matching. Bulk import via CSV.
📋
Activity & Audit Log Field-level diffs showing what changed, not just that something changed. Full blame view.
🗑️
Trash & Recovery Centralized soft-delete with full snapshots for exact restoration. Configurable auto-expiry.

Operations & Monitoring

Know what's happening. Fix it before your users notice.

Health Checks

Database, cache, storage, disk space, queue, scheduler. Reports healthy, degraded, or unhealthy.

Kubernetes-compatible liveness & readiness probes

VelvetCMS Insight

Local-only metrics: response times, cache hit rates, query counts. Bottleneck detection and actionable configuration recommendations.

Nothing sent externally

Snapshots

Full site backups — content, media metadata, menus, settings, redirects, taxonomies. Scheduled daily or weekly. Restore to any point.

Export production, import to staging

RSS & Atom Feeds

Auto-generated feeds for the main site, per content type, per taxonomy term, and per author. Autodiscovery tags included.

Full or excerpt content

Coming from WordPress?

Built-in WXR importer handles posts, pages, media, authors, categories, tags, custom fields, and featured images. Everything gets mapped to VelvetCMS equivalents automatically.

  • CSV and JSON import formats also supported
  • Chunked processing for large sites
  • Dry-run mode to preview before committing
  • Author mapping via CSV
$ php velvet import:wordpress export.xml \
    --author-map=authors.csv \
    --dry-run

Parsed 847 posts, 42 pages, 1203 media items.
Mapped 3 authors. 0 conflicts found.

Run without --dry-run to import.

Fair Code. Fair Price.

Core is open source. VelvetCMS is free for non-commercial. Simple.

Apache 2.0

Core

  • Free forever
  • Commercial use included
Dual License

VelvetCMS

  • Free for non-commercial
  • License for business use
Commercial

Fleet

  • For agencies & scale
  • Professional support

Full License Details

Ready to Build?

Install in under a minute. Read the docs. Ship something.