Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Base Laravel Package

winter/base

Winter/base is the core foundation package of Winter CMS, a free, open-source Laravel-based content management system. It provides the essential modules, helpers, and framework glue that power the platform, giving developers a solid base for building fast, extensible websites and applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. winter/base is not a library you composer require into an existing application — it is the application skeleton for Winter CMS, a full self-hosted CMS built on Laravel. That distinction drives the whole evaluation. The package decomposes into three layers: Winter core (modules/backend, modules/cms, modules/system), Winter Storm (vendor/winter/storm, the genuinely reusable primitives — filesystem, path resolution, class loading, Halcyon file-based config, asset pipeline), and Laravel/Symfony underneath. Only Storm is realistically consumable à la carte. Core is a monolith that owns routing, the admin backend, the Twig theme engine, media management, plugin lifecycle, and the asset pipeline. If the requirement is "a Laravel app with a content model," Winter is heavier than needed; if the requirement is "a self-hosted CMS our team can extend in PHP," it is a coherent fit.

Integration feasibility. Three viable modes, in ascending risk:

  1. Standalone deployment — composer create-project wintercms/winter, run alongside existing systems, integrate via HTTP/API or a shared database view. Lowest risk, cleanest boundary.
  2. Plugin development — build Author\Plugin packages against the documented extension points (backend form widgets, CMS components, Twig tags, console commands). This is the supported extension path and the one most integrations should take.
  3. Embedding core into a host Laravel app — not supported and should be treated as a non-starter. Storm registers global helper functions (themes_path(), plugins_path(), media_path(), temp_path()) and its own ClassLoader, which will collide with or shadow a host application's assumptions. Two Laravel boots in one process is a debugging tax with no upside.

The Dependents: 0 figure should not be read as an adoption signal — the package is a project template, so Composer's dependent graph is structurally near-empty. Judge adoption by the plugin ecosystem and community size instead, and note that 1.5k stars is modest relative to October CMS, Drupal, or WordPress; this is a smaller ecosystem with correspondingly thinner third-party coverage.

Technical risk. Ranked:

  • Bus factor and lineage. Winter is a community fork in the October CMS lineage, with a small core team. The MIT license means you can fork, but "can fork" is not a maintenance strategy for a CMS.
  • Framework lockstep. Winter pins to specific Laravel/PHP versions. Upgrading the host runtime, or adopting a Laravel major, becomes gated on Winter's release cadence rather than your own roadmap. Budget for this explicitly.
  • Non-standard autoloading. Storm's ClassLoader lowercases directory segments to derive paths (System\Twig\Node → modules/system/twig/node/). This breaks PSR-4 mental models, trips static analysis and IDE indexing, and manifests as case-sensitivity failures that pass on macOS/Windows and fail only on Linux CI. Any team onboarding cost estimate should include this.
  • Asset pipeline fragility. Module and plugin assets must be mirrored into public/ via winter:mirror public --relative. Skipping it produces 404s that browsers ORB-block into text/html, so JavaScript-driven backend UIs render blank with no console error. This is a genuinely expensive failure mode to diagnose cold.
  • Documentation asymmetry. The supplied agents/AGENTS.md is contributor-grade and excellent; it also reveals that a meaningful portion of operational knowledge (mirroring, Vite workspace resolution, symlink handling) lives in contributor docs rather than consumer docs.

Key questions for the team.

  1. Do we need a CMS, or a content API on top of Laravel? If the latter, this is the wrong shape.
  2. Which exact Winter/PHP/Laravel version pair are we standardizing on, and what is the supported upgrade window?
  3. Who owns the fork if upstream stalls — do we have PHP depth to maintain core, not just plugins?
  4. What is the plugin-ecosystem gap list versus our requirements, and what is the build-in-house cost for each gap?
  5. Does our deployment target support writable local storage (Halcyon config, media, compiled assets), or are we containerized/immutable?
  6. What is the content migration source, and is the schema mapping tractable?

Verdict. Conditional go. Viable as a standalone, plugin-extended CMS for a team already fluent in Laravel. Not viable as an embedded dependency or as a "just add content" layer. The score of ~51/100 is consistent with that reading: decent architecture, real integration friction, materially underweight ecosystem.

Integration Approach

Stack fit. PHP 8.x, Laravel, MySQL/Postgres/SQLite, Twig for front-end themes, a Vue-based admin backend, and three supported asset pipelines (Laravel Mix, Vite, and a legacy path). Composer for dependency management, php artisan for operations (winter:up, winter:mirror, winter:version). Fit is good for shops already on Laravel + Twig; poor for shops standardized on Node/Next or on a different PHP framework. If the broader platform is Python or Node, Winter becomes an isolated subsystem that must be operated by someone — account for that as a permanent, non-trivial ownership line.

Migration path. Greenfield first. For a brownfield move (WordPress, October, Drupal), plan on a bespoke importer writing through Winter's models rather than a SQL-level migration; the schema is Winter-specific and Halcyon-backed configuration lives in files, so a database-only cutover will produce a subtly broken site. Sequence content migration after the theme and plugin work is proven, and run it against a staging copy at least twice.

Compatibility. Two hard constraints:

  • Namespacing. Plugins live under plugins/<author>/<name> with Author\Plugin namespaces resolved by Storm's ClassLoader, not PSR-4. New sub-namespace directories must be lowercase on disk. Enforce this in review and in CI, or you will ship Linux-only failures.
  • Docroot. Production must run the mirrored public/ docroot, and winter:mirror must be part of the deploy step, not a one-time setup task. Make it idempotent in the pipeline.

Sequencing.

  1. Week 0–1 — Spike. Standalone install, one backend page, one CMS component, one Twig theme partial. Confirm the mirror step and asset pipeline end to end in a Linux container.
  2. Week 1–2 — Topology decision. Subdomain vs. subdirectory vs. reverse-proxied path. Lock it before content exists.
  3. Week 2–4 — Vertical slice plugin. Build the one plugin the business actually needs (SSO, CRM sync, custom content type) rather than a toy. This is the real extendability test.
  4. Week 3 — CI. Wire phpcs against changed files (the upstream CI does exactly this and fails the whole PR on style), plus phpunit with System\Tests\Bootstrap\PluginTestCase. Add a guard that fails on capitalized namespace directories.
  5. Week 4–6 — Content and theme. Build the theme, then migrate content.
  6. Week 6+ — Hardening. Caching, queue workers, media storage strategy, backup/restore rehearsal.

Do not parallelize steps 1–3 with content migration. The most common way this integration fails is committing content before the plugin boundary is validated.

Operational Impact

Maintenance. Two repositories to track — Winter core and Winter Storm — with changes occasionally spanning both and the core's composer.json constraint waiting on a Storm tag. Pin exact versions; upgrade deliberately, not on composer update. Budget roughly 10–15% of one engineer's time for version tracking, security patches, and plugin upkeep, rising during Laravel major transitions. PHPCS is fast (~15s) and non-negotiable in CI; skipping it costs a round-trip per PR.

Support. Community channels (GitHub, Discord) with no commercial SLA behind winter/base itself. There is no equivalent of October's commercial backing to lean on. This must be internalized as an ownership cost, not a procurement line item: name a primary and a secondary maintainer, and treat the ability to read Winter core source as a hiring/assignment constraint.

Scaling. Inherits Laravel's story — horizontal app servers behind a load balancer, Redis for cache/session/queue, standard DB replication. Two Winter-specific caveats:

  • Halcyon writes. Plugin and theme configuration is file-backed. In a multi-node or immutable-container deployment, any runtime config write must go to shared storage or be promoted to environment variables, or nodes will drift.
  • Media and compiled assets. Local disk by default. Object storage requires a plugin or custom filesystem driver; plan it before traffic, not after. The asset combine/cache layer benefits substantially from a warm cache and a CDN in front.

Failure modes (each has a known signature — capture these in the runbook):

  • Missing winter:mirror → assets 404 → browser ORB-block → blank backend UI with a clean console. Check the network tab before suspecting code.
  • Capitalized namespace directory → Class not found on Linux only, green on Windows/macOS CI. Symptom: every Ubuntu job fails identically.
  • Stale local vendor/ (especially Storm) → a failing test that will not reproduce on a fresh clone. Fix by updating Storm before declaring an environment issue.
  • Symlinked plugins + Vite → node_modules resolves from the symlink's real path and misses the project install. Requires a gitignored symlink bridge.
  • vite:watch on an IPv6 host → writes an unreachable http://[::]:5173 hot file, backend serves unstyled. Fix with echo -n 'http://localhost:5173' > assets/dist/hot; verify the hot file is removed when the watcher stops.
  • Symlinked packages resolving outside base_path() → asset package registration silently skipped. Prefer PathResolver::within()/resolve() over hand-rolled prefix checks in any code you add here.
  • Fixtures outside base_path() → Assetic "source is not in the root directory" failures. Use storage/framework/cache/<unique> and clean up in tearDown().

Ramp-up. A competent Laravel developer reaches productivity in roughly two to four weeks: one week on the plugin/module conventions and Storm's helper surface (the substitution tables are a genuinely good accelerator — most "small utilities" already exist at the Storm/Laravel/Symfony layers), one week on the backend form/widget system, one week on theming and the asset pipelines, and one week absorbing the sharp edges above. Full independent ownership — able to upgrade a Laravel major or debug a classloader failure unaided — is closer to two to three months. The AGENTS.md contributor guide materially compresses this, and should be required reading on day one rather than treated as internal upstream documentation.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource