yajra/cms-core
yajra/cms-core is a lightweight CMS foundation for Laravel from Yajra, offering reusable contracts, repositories, and helpers for pages, menus, settings, and content management. It gives developers clean scaffolding to build custom CMS features and admin panels quickly.
Build vs. buy for the "boring core" of a back-office. The decision this package forces is whether we hand-roll content primitives — pages, posts, slugs, publish states, settings, repository seams — or inherit someone else's. Benchmark it against the three real alternatives: building on Filament, licensing Statamic/Craft, or writing our own schema. Frame the answer as "how many PM-sprints does this remove from the roadmap," not as "is this a good package."
Roadmap de-risking for internal tooling. If the next two quarters include an admin panel, editorial workflow, or a lightweight marketing/blog backend, this can compress weeks of scaffolding into days — provided the stack matches its assumptions: Laravel, modular monolith, single-tenant, no headless API requirement. It does not belong on a customer-facing, multi-year roadmap.
Scope discipline: what is "core" vs. what is our product. Evaluating this is a forcing function. If two-thirds of what it offers we'd rewrite for our domain anyway, our differentiation lives above the CMS layer and we should borrow or buy this layer rather than own it. If it covers exactly the primitives we'd otherwise rebuild, that's a cheap win.
Architecture-as-a-decision ("reference, don't depend"). With 19 stars, zero dependents, and a single-maintainer lineage, the highest-value outcome may be studying how an experienced Laravel author decomposes a CMS into contracts, models, repositories, and traits — then porting the patterns, not the code. That is a one-engineer-day decision with an architecture write-up as the deliverable, and it is a legitimate one.
Feature-level call on bounded content types only. The realistic use case is one or two well-understood content types (Article, Page, Menu) behind an internal admin. This is not a decision that unlocks customer-facing content infrastructure, merchandising, or anything requiring a proven upgrade path.
Risk posture, made explicit. Scoring this at ~0.48 with an opportunity signal of ~0.57 is PM language for "interesting, unproven, cheap to trial, expensive to depend on." The decision to fund a spike is separate from — and much easier than — the decision to adopt.
Consider it when:
cms-page, cms-menu, cms-media), so adopting core alone renders nothing useful.Look elsewhere when:
To executives: This is a small, free (MIT), open-source scaffolding library for the unglamorous core of an internal admin tool — page and post management, publishing states, settings. It compresses the first weeks of a back-office build into days. The strategic value is not the code; it is that adopting it forces a clean one-page answer to "do we build or buy our content layer," and it lets us spend our differentiation budget on the product rather than on CRUD plumbing. It is also a low-commitment trial: one engineer, roughly a week, ending in a go/no-go written recommendation. The risk is maintenance lineage — one maintainer, minimal adoption — which is why adoption requires version pinning, a private fork, and an exit plan scoped to a single directory. We are not betting the roadmap on it; we are buying an option.
To engineering: Treat this as a reference architecture first and a dependency second. Read src/Contracts (the seams), the config file (the swap points), and the published migrations (the schema debt) before writing anything. Bind contracts in one provider driven by one config key — that file is our deletion list. Never consume package models directly in controllers; extend them in App\Cms and restate traits explicitly. Use the traits (slug, publish state, meta) on our own models wherever possible — highest value, lowest risk, no migration ownership. Watch for global scopes leaking into unrelated queries, N+1s in default repository listings, slug collisions across soft-deleted rows, and the fact that published migrations cannot be safely un-published. Verify auto-discovery is declared in composer.json before debugging anything else, and add config:clear to the deploy script. Pin the version exactly, mirror the fork, and keep a short docs/cms-core-notes.md — contract map, model map, scope list, migration list, exit plan. That file is worth more than the package.
How can I help you explore Laravel packages today?