← Back to JavaScript Development ← Back to Table of Contents

10.1 Frontend architecture reference

This page is the compact architecture companion to JavaScript development. It preserves the historical filename while keeping implementation detail in the source and the canonical guide.

Decisions

Decision Current contract
Build tool Vite, configured by app/vite.config.js
Module format ES modules ("type": "module" in app/package.json)
Behavior framework Stimulus controllers registered through window.Controllers
UI framework Bootstrap 5 imported by app/assets/js/index.js and bundled
Partial navigation Turbo Frames and Streams
Full navigation Normal browser navigation; Turbo Drive is disabled
Shared assets in templates Logical names resolved by App\View\Helper\ViteHelper
Core controller discovery assets/js/controllers/**/*-controller.js
Plugin controller discovery plugin assets/js/controllers; uppercase Assets remains supported for established code
Frontend tests Jest/jsdom under app/tests/js; Playwright for browser flows

Boot sequence

Vite controllers entry
  ├─ import core/plugin controller modules
  ├─ import shared *-service.js modules
  └─ controller modules populate window.Controllers

Vite index entry
  ├─ import Stimulus, Turbo, Bootstrap, utilities, accessibility, timezone
  ├─ set Turbo.session.drive = false
  ├─ Application.start()
  ├─ register window.Controllers
  ├─ reconnect missed scopes after Turbo renders
  └─ initialize Bootstrap tooltips

The default CakePHP layout emits the controllers entry before index. Controller registration is a module side effect, so every controller must assign its public identifier before the application entry enumerates the registry.

Shared global surface

The app intentionally exposes a small compatibility surface:

Global Purpose
window.Stimulus Started Stimulus application
window.Controllers Controller classes awaiting registration
window.bootstrap Imported Bootstrap module
window.KMP_utils URL parameter and small escaping helpers
window.KMP_accessibility Accessible dialogs and announcements
window.KMP_Timezone Client timezone formatting/input helpers
window.urlRoot CakePHP-generated application root

Do not grow this list for feature-local state. Prefer imports, Stimulus values, outlets, or namespaced DOM events.

Server/client boundary

CakePHP remains authoritative for:

Stimulus owns transient interaction state and enhancement. Never use a hidden button, missing controller, disabled client flag, or tenant ID in JavaScript as a security boundary.

Entry points versus modules

Add normal controllers and *-service.js modules under the existing discovered paths. Add a Vite entry only when a layout needs an independently loadable asset. Every entry increases manifest and delivery complexity.

Current JavaScript entries are:

CSS entries are listed in app/vite.config.js, including core layouts, workflow designer, Gatherings public UI, Waivers plugin styles, and Drawflow. The current list is maintained in Asset management.

Compatibility cautions