Launching March 24st, 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.

admin.yoursite.com/content/edit/my-first-post
Content
Media
Users
Settings
H1 B I 🔗 📷 </>
Getting Started with VelvetCMS
VelvetCMS takes a different approach to content management. Every feature is a standalone service...
Code Block $ php velvet content:create "My First Post"
Image Block

The admin panel. Dark mode by default. Every feature is a service — the panel is just one way to access them.

Three Interfaces. One Codebase.

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

⌨️
CLI
Cron, CI/CD, scripts
Always available. php velvet content:list
🔌
REST API
SPAs, mobile, headless
Disable: consumers.api = false
🖥️
Web Admin
Content editing, settings
Disable: consumers.web = false
Services Layer
ContentService MediaService UserService AuthService SearchService TaxonomyService WorkflowService MenuService AnalyticsService SettingsService RedirectService RevisionService SEOService HealthService SnapshotService FeedService TrashService InsightService SchedulingService
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.
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 URL — it resolves to a rich embed automatically.

  • Custom block types — define schema, template, CSS
  • Multiple editing modes: visual blocks, Markdown, code
  • Content locking for concurrent editing
  • Reusable content templates across pages
PHP
$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, 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
PHP
$changeset = $staging->createChangeset('Homepage redesign');
$staging->stage($homepage, $changeset);
$staging->stage($aboutPage, $changeset);

// Preview before going live
$staging->preview($changeset);  // → staging URL

// Ship it
$staging->deploy($changeset);   // → goes live atomically
Workflows

From Draft to Published — Your Rules

Define review pipelines with approvals, role gates, and automatic transitions. A blog might need just draft → published. An enterprise site might go through legal review, editor approval, and scheduled publication. Shareable draft links let external reviewers see unpublished content without 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
Draft
submit
Review
approve
Approved
publish
Published
reject → back 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. Actions trigger side effects. WordPress-style patterns, but typed, testable, and without the global soup.

PHP
// 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');
});

Extension Registry

Typed registry for UI extension points — sidebar items, settings tabs, dashboard widgets, block types. Register once, render everywhere.

Module System

Self-contained packages with routes, views, migrations, and commands. Version constraints, dependency resolution, conflict detection.

Queue System

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

Everything You Need, Built In

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

📷

Media Library

Auto image processing, WebP conversion, focal point cropping, folder organization, usage tracking.

🏷️

Taxonomies

Categories, tags, custom taxonomies. Hierarchical or flat. Attach to any content type.

👥

Users & Roles

Granular permissions, registration modes, password policies, user metadata.

🔐

Dual Auth

Session-based for web, token-based for API with scoped permissions. Optional TOTP 2FA.

🧭

Menu Builder

Drag-and-drop navigation with unlimited nesting. Define menus, assign to locations.

🔎

SEO & Structured Data

Auto meta tags, OpenGraph, JSON-LD, sitemap.xml, readability scoring.

📊

Privacy-First Analytics

Page views and referrers without cookies or third-party scripts. GDPR-compliant by design.

📅

Scheduling

Future publishing with calendar view. Expiration dates and auto-unpublish.

🔗

Content Relationships

Bidirectional links, series, translation connections between any content types.

↪️

Redirects

301, 302, 307, 308 with exact, wildcard, regex matching. CSV bulk import.

📋

Activity & Audit Log

Field-level diffs showing what changed, not just that something changed.

🗑️

Trash & Recovery

Centralized soft-delete with full snapshots. Configurable auto-expiry.

Operations & Monitoring

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

Health Checks

Database, cache, storage, disk, queue, scheduler. Reports healthy/degraded/unhealthy. Kubernetes-compatible probes.

VelvetCMS Insight

Local-only metrics: response times, cache hit rates, query counts. Bottleneck detection. Nothing sent externally.

Snapshots

Full site backups on schedule. Content, media metadata, menus, settings. Export production, import to staging.

RSS & Atom Feeds

Auto-generated feeds per site, content type, taxonomy, author. Autodiscovery tags included.

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.
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
Explore Core
PHP
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]);
    }
}

Licensing

Core

Apache 2.0

Free forever. Commercial use included. No strings.

VelvetCMS

Dual License

Free for non-commercial. License for business use.

Fleet

Commercial

For agencies & scale. Priced for the value delivered.

Ready to Build?

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