DEV Community

Cover image for I Tried Building a CMS on Filament — Here's What I'd Do Instead
hamed pakdaman
hamed pakdaman

Posted on • Originally published at unfoldcms.com

I Tried Building a CMS on Filament — Here's What I'd Do Instead

I spent two months last year trying to build a content-management system on top of FilamentPHP. I had reasons. Filament was the most polished thing in the Laravel ecosystem. Every Laravel dev I respected was using it. I'd already shipped two admin panels with it for client work and they came together fast.

The third project was different — a marketing site with a blog, pages, a menu, redirects, SEO meta, scheduled posts, and a real public-facing theme. I figured: same stack, same DSL, same speed. I was wrong, and the lesson took me longer to learn than I'd like to admit.

This is what I learned, what I'd do differently, and why I eventually built something else.

TL;DR: Filament is excellent at being Filament — a builder DSL for admin panels around your own data model. It's not a CMS, and trying to use it as a CMS by scaffolding PostResource, PageResource, MediaResource, etc., is a quietly expensive way to ship a website. Pick Filament when the data model is yours to design. Pick a CMS when the data model is "post, page, media, menu, SEO, redirect" — that problem has been solved for 20 years and you shouldn't rebuild it.


What I Built On Filament

The project was a marketing site for a small SaaS — homepage, ~6 marketing pages, a blog, a docs section, a category-filtered case-studies index. Standard small-business CMS work.

My initial Filament scaffold was about what you'd expect:

  • PostResource with title, slug, body (Tiptap field), featured image (Filament media plugin), status enum, scheduled-at, SEO title, meta description, category relation manager
  • PageResource — almost identical, plus a layout enum and section blocks
  • CategoryResource — title, slug, parent, sort order
  • MenuResource — name + a repeater of menu items
  • MediaResource — wrapping Spatie Media Library so the team could browse uploads
  • RedirectResource — from URL, to URL, status code, is_active

I wrote those in two days. Filament's form DSL is genuinely good — TextInput::make(), Select::make(), conditional fields, relation managers. Two days of resource definitions and I had an admin that looked like a CMS admin.

Then I spent the next eight weeks building everything that wasn't an admin form.


What Filament Doesn't Ship

This is the part nobody tells you when they recommend Filament for a CMS. You scaffold the resources in a weekend, and then you realize Filament has no concept of:

  1. A public-facing site. Filament is admin-only. The site that the content gets published to — the actual website your readers visit — doesn't exist. You build it yourself in Blade or Inertia, from scratch, every project.
  2. Themes. No theme system, no template switcher, no place for non-developer users to change the look. If marketing wants a new homepage layout, you edit Blade files and deploy.
  3. Sections / page builder. No block-based section system. If the marketing team wants a "stats" section above "testimonials," that's a developer task. I tried wiring up Filament's repeater field as a section builder — it kind of worked, and it took a week, and the editing UX was still worse than any real CMS.
  4. A media library outside the resource. Filament's media is per-field. You can browse it from the form. There's no global media library where editors hunt for "that photo we used three months ago." The Curator plugin gets you partway there — it's $49 and still doesn't feel like WordPress's media library, which set the bar 15 years ago.
  5. Slug history. When you rename a post slug, the old URL 404s. Filament doesn't track slug history. You build that yourself with a model + middleware. I did. It took half a day and I had to debug edge cases for two more.
  6. Real SEO records. I shoved seo_title, meta_desc, og_image_url columns onto every resource. Then I needed sitemap.xml. Then robots.txt. Then JSON-LD schema for posts and pages. Then per-page Open Graph fallback. Every one of these is its own afternoon of code that every CMS already ships.
  7. Redirects with hit tracking. Built that one. A model, an admin resource, middleware that runs early in the request lifecycle and respects is_active. CSV import? Built that too.
  8. A sitemap generator. A service that walks every resource type, queries published rows, outputs XML, caches it sensibly. Two days.
  9. A comments system. I needed it for the blog. I evaluated beyondcode/laravel-comments (good package), wired it in, built a moderation queue, built a "reply to reply" UI in Livewire. Another week.

I'll stop the list. You get the picture. By week eight I had reinvented half of a CMS in Filament's idiom, and the half I had wasn't as good as the half a real CMS would have given me on day one.


The DX Pattern That Quietly Burns Time

Filament's developer experience inside the admin is genuinely great. The DSL is tight, the docs are clear, the components are polished. Inside the admin. The DX outside the admin — the public-facing site, the editor's workflow, the deploy story — is whatever you build.

Here's the trap. Each individual "I'll just build this on Filament" decision feels small:

  • "I'll just wire up a Blade template for the public post page." — 2 hours
  • "I'll just add a sitemap.xml route." — 3 hours including the cache layer
  • "I'll just build a tiny section system with Filament's repeater." — 2 days
  • "I'll just write a slug-history middleware." — half a day
  • "I'll just add a comments table and a moderation UI." — 4 days
  • "I'll just build a media library page outside the resource." — 3 days
  • "I'll just add a homepage editor with reorderable sections." — week and a half

Add them up. Eight weeks of CMS rebuild work, on top of the actual marketing site I was supposed to be delivering. None of that work was bad — it's just work that someone else already did, packaged, and shipped.

The pattern I had to learn the hard way: when you find yourself building admin resources for "Post," "Page," "Category," "Media," "Menu," "Redirect," and "SeoMeta," you're not building an admin for your app. You're building a CMS. And there are already CMSes.

Filament gives you the form library for that CMS. It doesn't give you the CMS.


What I'd Do Differently

If I started that same project today, I'd ask a different question first.

The question I asked then: "What's the best Laravel admin framework?" That question always answers Filament. It's a great answer to that question.

The question I should have asked: "Do I have a CMS data model, or a custom data model?"

If the data model is Order, Shipment, Invoice, Customer, SupportTicket, Subscription, LabSample — that's a custom data model. Filament is the right tool. The flexibility you pay for in Filament (you describe the admin, Filament renders it) is exactly what you need because nobody else has shipped your admin for your data.

If the data model is Post, Page, Category, Media, Menu, Redirect, SeoMeta — that's a CMS data model. It's been solved. The right tool is a CMS, and what you pay for is not the freedom to design the admin — it's the freedom to skip designing the admin. The CMS does the admin part the same way every CMS has done it since 2003, and that's fine, because users already know how it works.

I spent two months learning that distinction. I'm writing this so you don't have to.


What Filament Is Genuinely Best At

I want to be careful here, because "Filament is great but not for X" reads cynical and the Laravel community gets enough of that. Filament is genuinely best at things I needed to not build, by building something else.

Custom internal admins. A back-office tool for a logistics company managing routes, drivers, vehicles, deliveries. A moderation queue for a marketplace. An ops dashboard for a SaaS support team. These have custom data models. Filament wins.

SaaS product dashboards. Customer-facing dashboards inside a product where the user manages their own resources (projects, API keys, billing settings). Filament's multi-panel support in v3+ makes this clean.

Form-heavy apps. If your app is fundamentally forms — survey builders, application processing, lab data entry — Filament's form DSL is best-in-class in the Laravel ecosystem. Nothing else comes close.

Teams that prefer config-as-code. Some teams genuinely want the admin's shape to live in PHP files, reviewable in PRs, deployable like any other code change. Filament fits that workflow perfectly. A CMS where editors change the homepage layout in production through an admin UI is the opposite of that workflow. Both are valid; they fit different teams.

When I see someone shipping a moderation tool, an internal admin, a SaaS dashboard, a custom data model — I tell them Filament. And mean it.


What I Built Instead

I'll keep this short because the post isn't about me. After the Filament-as-CMS experience, I built UnfoldCMS — a Laravel 12 + React 19 + shadcn/ui CMS. The content model is fixed: Post with four content_type values (post, page, landing, block), media via Spatie, categories, comments, menus, redirects, SEO meta, themed public site, public REST API. One-time license, $39 to $799 depending on tier.

I did not build it because Filament is bad. Filament isn't bad. I built it because the shape I needed for marketing sites — fixed content model, themed frontend included, non-developer editor workflow — was the wrong shape for an admin-panel builder. So instead of bending Filament into that shape, I built a different tool for that shape.

If you're picking between them, the UnfoldCMS vs FilamentPHP comparison lays out which tool fits which job in more detail.


The Honest Decision Tree

If you're a Laravel developer right now, picking what to use for your next admin or CMS project, the question is one of these two:

Are you designing the data model?

  • Yes → Filament. Your domain is unique, the admin has to be shaped to it, and Filament's DSL is the best in the ecosystem for that work.
  • No, it's a CMS data model → CMS. UnfoldCMS, Statamic, Kirby, or even WordPress if your team is WordPress-shaped. Don't rebuild what's already shipped.

Does your project need a public-facing themed frontend out of the box?

  • Yes → CMS. Filament has no concept of one.
  • No, the frontend is a separate Next.js / Astro / SvelteKit app that consumes an API → either tool can work, but Filament still doesn't ship the content model.

Are non-developers editing the site day-to-day?

  • Yes → CMS. The kinds of changes editors make (rearrange sections, change menus, add redirects, edit SEO) all need admin UI that doesn't exist in Filament unless you build it.
  • No, only devs touch the admin → Filament is fine.

That's the whole framework. Three questions. If the answers come back "CMS, CMS, CMS," reach for a CMS. If they come back "Filament, either, Filament," reach for Filament. If they come back mixed, the bigger question is what your team actually needs to ship, not which framework is cooler this week.


What I'd Tell My Past Self

Two months ago me, listening:

  1. Filament's not a CMS. The fact that it looks like one when you scaffold a PostResource is a trick of the eye. Pull on that thread for ten minutes and you'll find sitemap.xml, robots.txt, JSON-LD schema, theme system, public frontend, slug history, comments — none of which exist in Filament because that's not Filament's job.
  2. "Building it on Filament" feels productive because every individual piece is small. The cost is the integral of those small pieces, and you can't see the integral from inside week one.
  3. Look at what already ships. Spend an hour evaluating WordPress, Statamic, Kirby, Ghost, UnfoldCMS, October CMS, Strapi (if you're open to Node) — before you scaffold the first resource. The hour saves you the eight weeks.
  4. The "Laravel CMS" question is not actually about Laravel. It's about whether you want to write a CMS or use a CMS. Either is fine. Just don't accidentally do the first one when you meant to do the second.

That's it. That's the post. If you're picking between Filament and a CMS for your next project and the data model is "post + page + media + menu + SEO" — that's a CMS-shaped project. Pick the tool shaped like the work.


Disclosure: I work on UnfoldCMS. This post is also published on the UnfoldCMS blog (canonical above). The Filament observations are from my own pre-UnfoldCMS work, not a vendor comparison piece — Filament is a tool I respect and still recommend for the jobs it fits. If you're shipping a custom admin, use Filament. If you're shipping a CMS, use a CMS.

Top comments (1)

Collapse
 
hamed_pakdaman_c724e294d9 profile image
hamed pakdaman

I built UnfoldCMS specifically because of the frustrations in this post. Curious about other Laravel devs — do you prefer building your own CMS scaffolding every time, or do you
reach for something pre-built when the data model is post/page/media/menu shaped? What's worked for you?