Building Rush CMS: How is my Headless CMS Design System?
Developing a Headless CMS from scratch isn't just about CRUDs; it's about managing complexity, ensuring visual consistency at scale, and making technical decisions based on ROI. Rush CMS was born from my own needs and market demand. But its foundation was built under the principles of Design Systems and Clean Architecture.
In this post, I am opening the hood on the design and infrastructure decisions that support the project currently in production. Get ready to see the reasoning behind why every part of the engine was designed this way. I should mention that Rush CMS - for now - is a private project, for internal use.
Discover the anatomy of Rush CMS
Before talking about the decisions, let's dive deeper into the design system in a pure and clear way. If you want to learn more about what Rush does, visit the official website:
What is being used?
Gateway
- Interface in Filament
- Agnostic API with protected endpoints, delivering pure JSON to the front-end
Engine
- App with Laravel 12 + PHP 8.4 (Strict Typing + PHPStan lvl5)
- Performance with Laravel Octane (Swoole)
Data Persistence
- PostgreSQL (JSONB for Collections flexibility)
- Redis for queues and cache
DevOps
- Docker
- Coolify
- Hetzner
CI/CD
- GitHub Actions running 600+ tests (Pest)
- Pint
- PHPStan
- Frontend Build
Background and Workers
Image Job: S3 Upload → Resize Worker → WebP converter → CDN
i18n Engine: The CMS is i18n-first; it natively supports multiple languages in the content, using Spatie integrated with Models for on-the-fly translation
Integrations:
Internal consumption API for websites
Google Analytics OAuth2
Observability & Reliability:
Google Analytics
Deploy webhooks (for static sites)
Triple backup layer (Spatie, Hetzner, Coolify)
Now that you know what it has, let's understand some of the reasons why it was built this way.
The Design System as a Pillar of Scalability
In the past, it was common to start with the database. I started with consistency. For a multi-tenant CMS, the Design System isn't about "aesthetics"; it's about operational efficiency. First, I have to document everything I need before writing a single line of code.
About Filament and Tailwind
I used the Filament ecosystem to inherit a robust component system for the control panel. This allowed me to focus on what is core to the business: creating Custom Blocks, Collections, and Databases.
Here I make a confession: I would REALLY like to completely decouple the frontend and use pure React, but it would be a terrible decision for what the project required. So—with a tear in my eyes, but feet on the ground—I followed through with Filament, a technical decision based on ROI, ensuring native accessibility and usability without reinventing stable UI patterns.

Contract-Driven Design
The intelligence of the Design System lies in the API Schema. The user can create dozens of customized blocks, but the responsibility to "understand" and render these blocks lies with the decoupled front-end.
The CMS dictates the data structure, and the API consumer implements the visualization. This rigorous contract is what ensures that new types of content can be created without breaking the visual integrity of the final product. It is an excellent way for the front-end developer to have an extremely dynamic site through the control panel while building the front-end with all their personal preferences.
Technical Decisions and Trade-offs
Here, my focus was to minimize Time-to-Market without compromising quality.
Multi-tenancy and Zero Trust Isolation
The multi-tenancy architecture was implemented with a total focus on decoupling between tenants via the Filament Shield package. There is no "Super User" with unrestricted access to all clients' data by default.
If my access is revoked by a site administrator, the isolation is total. It is a design choice that prioritizes client data sovereignty over developer technical convenience. For contractual monitoring, the only access points I have are: S3 space occupied and API requests.
Performance with Laravel Octane
This decision can be interpreted in several ways, as either premature or correct. Why is it correct? Rush CMS was designed to serve various sites in real-time, whether SSR, ISR, or SSG. A platform refactor with 100+ sites running simultaneously would bring more work than having it ready now. Even if I wasn't going to use Octane immediately, I would already have to write the system ready for it, with all the necessary data precautions, which makes even more sense to bring speed as soon as possible.
Therefore, the transition to an in-memory server with Octane in commit #247 was strategic; it paves the way for larger scales, ensuring that the CMS engine responds with minimum latency as the volume of requests increases.
Postgres and JSONB
The flexibility required by a dynamic collection CMS demands mutable schemas. Using JSONB in Postgres allowed combining the power of NoSQL tools with the security and integrity of the Eloquent ORM relational ecosystem.

Software Quality and Feedback Loops
A system in production with real clients cannot be fragile.
Testing Strategy
Rush CMS currently has 600+ automated tests (Pest PHP). It is still far from full coverage, but it covers the entire "core system." The current focus is not vanity coverage, but protecting the pricing logic, permissions, and multi-tenancy integrity.
Code Integrity
Currently at PHPStan Level 5, with a roadmap to Level 8/9 (I'm itching to do this soon hahaha). Keeping the code typed and analyzed is what allows me to perform daily deploys with greater confidence (I've used CI/CD since day 1).
Image Pipeline
I implemented a WebP optimization system via S3 right at the beginning. Refactoring media pipelines after having thousands of files is a nightmare in terms of costs and migration; I solved this as a core feature from the start, ensuring a lean S3 and avoiding the inevitable future refactoring.
ROI Lessons
What would I do differently? It is important to learn from your own mistakes so you don't repeat them later! The two mistakes I will mention are identical but in different applications; I tried to reinvent the wheel:
- i18n: I tried to create a proprietary translation system before migrating to Spatie Translatable. Lesson: Use battle-tested solutions for common problems.
- Analytics: I built a complete internal analytics engine before realizing that the product's focus should be the CMS, not monitoring. I replaced it with native integrations (Google Analytics/OAuth2), saving hours of maintenance.
What do I think of Rush so far?
Rush CMS is a testament that velocity and quality are not mutually exclusive, provided you have a solid Design System and a rigorous testing strategy. Currently, the project continues to evolve, with medium, long, and very long-term plans.
Feedback from the clients testing the platform is positive; there is a lot of work ahead!