Standalone Project Creation & Core Syncing

1. High-Level Architectural Summary

When starting a new project from Zero CMS, developers often want to create a standalone, separate project that has its own custom modules, layouts, and public styles in addition to the core bundles. However, you still want to benefit from ongoing performance optimizations, security patches, and core kernel updates to Zero CMS in the future.

Because Zero CMS strictly follows the Loose Coupling & Modular Registration (Rule 2), all custom features, modules, themes, and views are designed to be completely hot-swappable and separated from the system Core. Zero CMS Core itself is installed as a versioned Composer package (markoliverbrawn/zero-cms-core) rather than copied or cloned into your project, cleanly separating your custom code from the platform kernel and enabling conflict-free core updates.

2. Scaffolding a New Sub-Project via bin/create-project

To establish a standalone project, use the bin/create-project bootstrapper -- a single, self-contained PHP script (not bash, so it runs anywhere composer and php are available, with no bash/ash/dash shell-portability gap) that needs no existing Zero CMS checkout. Save it anywhere and run it directly: it writes a composer.json requiring Zero CMS Core from its public VCS repository, runs composer install to pull Core into vendor/markoliverbrawn/zero-cms-core/, scaffolds your project's own public/, src/, tests/, and storage/ folders, and then deletes itself once finished.

Scaffolding a New Sub-Project

Scaffolding a New Sub-Project bash
# 1. Fetch the standalone bootstrapper script (no existing checkout required)
curl -O https://raw.githubusercontent.com/markoliverbrawn/zero-cms/dev/bin/create-project
chmod +x create-project

# 2. Scaffold a new sub-project -- writes composer.json, runs composer install (pulling
#    Zero CMS Core into vendor/markoliverbrawn/zero-cms-core/), and self-deletes when done
./create-project ../my-website --branch dev

# 3. Finish setup inside the new project
cd ../my-website
$EDITOR .env
bin/seed
bin/test

3. Standalone Development Best Practices (Preventing Conflicts)

To ensure that composer update never produces conflicts, standalone developers MUST strictly adhere to the following decoupling mandates:

  • Never Modify Core (vendor/markoliverbrawn/zero-cms-core/src/Core/): This entire package is Composer-managed and gets overwritten on every composer update -- treat it as read-only.
  • Custom Modules in your own `src/Modules/`: Store your project-specific modules inside their own, decoupled folders (e.g. src/Modules/CustomFeature/) and register their custom routing, blocks, and listeners dynamically inside their init() hooks -- your project's public/index.php registers this path via App::registerModulePath().
  • Custom Layouts in your own `src/Views/`: Place all project-specific visual styles, cascading grids, and layout templates inside your own src/Views/ (registered via App::registerViewDir('app', ...)) rather than editing the vendor package's templates.
  • Dynamic Theme Fallbacks: Inherit core templates dynamically. If your custom theme only needs to override layout.php, register your theme and the core will automatically fall back to default templates for all missing view templates, keeping your theme directory clean and lightweight!

4. Updating Core via Composer

Whenever a core framework optimization or security hardening patch is committed to the main Zero CMS repository, pulling those updates into your standalone project is a single command -- no manual merges, no conflicts:

Composer Update and Test Runner Verification

Composer Update and Test Runner Verification bash
# 1. Pull the latest commit on the tracked branch and re-lock the installed version
composer update markoliverbrawn/zero-cms-core

# 2. Always execute the isolated subprocess test runner to verify 100% regression-free stability
bin/test

# composer.lock pins the installed Core version -- commit it alongside composer.json so
# teammates and deploys reproduce the exact same vendor/ checkout via `composer install`.