HomeStart Here › The AEM-to-React mental model

The AEM-to-React mental model

Purpose: Give React engineers a durable mapping from every major AEM concept to a React-world equivalent, so nothing in AEM feels alien.

Who this page is for

AudienceWhy it matters to you
React/UI engineersThe core translation layer for everything else in the academy
Full-stack JS engineersMaps server concepts to familiar territory too

The big picture

A React SPA renders in the browser from API state. AEM renders on the server from repository content, then caches aggressively. Same inputs→outputs thinking, different place and time of rendering.

React world                            AEM world
-----------                            ---------
   Redux store  ──selector──▶ hook        JCR repo ──adaptTo──▶ Sling Model
        │                      │              │                     │
        ▼                      ▼              ▼                     ▼
      state  ────────▶   JSX render        content ─────▶     HTL render
        │                      │              │                     │
        ▼                      ▼              ▼                     ▼
   virtual DOM            browser DOM      HTML page         Dispatcher/CDN cache

Concept-by-concept mapping

AEMReact equivalentWhere the analogy holdsWhere it breaks
JCR / Oak repositoryPersistent Redux storeSingle tree of state, path-addressable, observableIt is a database — it survives restarts and holds ACLs
Resource / sling:resourceTypeComponent instance + its typeContent node "is rendered by" a component, like props → componentResolution is by path convention, not import
Sling ModelCustom hook (usePlanDetails())Adapts raw state into a clean view-facing APIRuns once server-side per request, not reactively
HTL templateServer-side JSXDeclarative, expressions, auto-escaping (like JSX's default escaping)No event handlers — it emits static HTML
Editable templateLayout component + allowed childrenDefines page structure and which components may appearGoverned by policies, editable by authors, not code
Component dialogProps form / Storybook controlsAuthors set "props" through a UIValues persist into the JCR, not component state
ClientLibsWebpack bundlesNamed, dependency-ordered JS/CSS bundlesDependency graph declared in the repo, not package.json
DispatcherNginx + CDNCache-first reverse proxy, invalidation on publishAlso a security filter layer
Author / PublishCMS admin / production buildEditing tier vs serving tierContent moves by replication, not redeploys
WorkflowCI pipeline for contentMulti-step, approvals, automation on contentRuns inside AEM, modelled visually

Request lifecycle, side by side

React SPA request                    AEM page request
-----------------                    ----------------
GET /plans/gold-hospital             GET /content/phi/plans/gold-hospital.html
  → CDN serves index.html              → CDN / Dispatcher cache HIT? serve file, done
  → JS boots, fetches /api/plan        → MISS: Publish resolves path to resource
  → Redux hydrates                     → resourceType picks the component
  → components render                  → Sling Model adapts content nodes
  → DOM updated                        → HTL renders HTML, response cached on the way out

The key inversion: in AEM, rendering cost is paid once per content change, not once per user, because the Dispatcher caches the finished HTML until the content is republished.

What has no React equivalent (learn fresh)

Quick navigation