EDS vs AEM Feature Comparison
Feature comparison between EDS and traditional AEM. Covers Sling Models, editable templates, parsys, multifield, workflow, component inheritance, ClientLibs, OSGi, JCR, and the matching EDS patterns or gaps.
Content Objective
This chapter covers:
- A feature-by-feature mapping of every major AEM capability to EDS
- Where EDS has a direct equivalent, a workaround, or no equivalent
- Why EDS made the architectural decisions it did (not just what changed)
- Which AEM patterns translate well to EDS and which ones don't
- How to think about EDS as an architect, not just a developer
- Honest gaps and when those gaps matter
This is the chapter I wish existed when I first encountered EDS after years of AEM development.
The most dangerous mistake an AEM developer makes in EDS is trying to replicate AEM patterns. EDS is not a simplified AEM. It is a different paradigm. Some AEM concepts map cleanly. Others have no mapping. A few things EDS does better.
Understanding the difference at an architectural level — not just syntactically — is what this chapter provides.
The Philosophical Difference
Before the feature comparison, the mindset:
AEM is server-centric. The CMS assembles the page on the server. Sling resolution, component rendering, template policies, workflow — all happen on the server. The browser receives a finished HTML page.
EDS is edge-client-centric. The edge delivers raw content HTML. The browser executes JavaScript that assembles the final UI. The CMS provides content structure; the browser provides rendering.
AEM: Browser → Server (Sling renders component, applies policy, returns HTML) → Browser renders
EDS: Browser → Edge (returns pre-built HTML) → Browser JS (decorates blocks) → Browser renders
This is not a simplification. It is a fundamentally different architecture. Every "missing feature" in EDS comes from this architectural choice.
1. Component Development
In AEM
A component consists of:
- HTL template (
.html) for markup - Sling Model (
.java) for business logic - Dialog (
.xml) for author UI - ClientLib (JS/CSS) for frontend behavior
cq:Componentnode definition for metadata
The component is a server-side unit. The Sling Model runs on the server, queries JCR, applies business logic, and exposes data to HTL.
@Model(adaptables = SlingHttpServletRequest.class)
public class HeroModel {
@ValueMapValue
private String size;
@ValueMapValue
private String title;
@ChildResource
private Resource desktopImage;
public String getSize() {
return StringUtils.defaultIfBlank(size, "tall");
}
}
<!-- hero.html (HTL) -->
<div class="hero hero-${model.size}">
<div class="hero-section">
<h1 class="hero-header">${model.title}</h1>
</div>
</div>
In EDS
A block (component) consists of:
block.js— JavaScript that transforms DOM (replaces Sling Model + HTL combined)block.css— Scoped styles_block.json— Field definitions for Universal Editor (replaces dialog XML)
There is no server-side rendering. The decorate(block) function receives the raw content HTML and transforms it into the final UI entirely in the browser.
// hero.js (replaces both Sling Model and HTL)
export default function decorate(block) {
const props = parseKeyValue(block);
const size = props.size?.textContent.trim().toLowerCase() || 'tall';
block.classList.add(`hero-${size}`);
block.innerHTML = '';
const section = document.createElement('section');
section.className = 'hero-section';
const header = document.createElement('h1');
header.className = 'hero-header';
header.innerHTML = props.title?.innerHTML || '';
section.append(header);
block.append(section);
}
Key Differences
| Aspect | AEM | EDS |
|---|---|---|
| Where logic runs | Server (Java) | Browser (JavaScript) |
| Language | Java | JavaScript |
| Markup | HTL template | DOM API in JS |
| Business logic | Sling Model | Block JS function |
| Data access | JCR via ResourceResolver | DOM parsing (authored content) |
| External API calls | Java HTTP client in Sling Model | fetch() in decorate() |
| Error handling | Server-side exception | try/catch in decorate() |
| Testing | JUnit + AEM Mocks | Browser testing + unit tests |
Architect takeaway: In EDS, the "component" concept splits into two concerns — content structure (authored in UE/DA) and rendering (block JS). There is no server-side processing step between content and rendering.
2. Sling Models
In AEM
Sling Models provide a typed, testable layer between JCR content and the presentation layer. They handle:
- Property injection from ValueMap
- Child resource injection
- Adaptation from request/resource
- Business logic (null checks, defaults, transformations)
- External service injection via @OSGiService
@Model(adaptables = SlingHttpServletRequest.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class CardListModel {
@OSGiService
private QueryBuilder queryBuilder;
@ValueMapValue
private String path;
public List<CardItem> getCards() {
// Query JCR, return typed list
Map<String, String> queryMap = new HashMap<>();
queryMap.put("path", path);
queryMap.put("type", "nt:unstructured");
// ... complex query logic
}
}
In EDS
There is no equivalent to Sling Models. All data logic lives in the block's decorate() function.
For simple content rendering, this is fine — the authored content IS the data.
For complex data aggregation (query multiple paths, apply business rules), you have three options:
Option 1: Query API (for page metadata lists)
// Instead of JCR query, fetch pre-built JSON index
const response = await fetch('/content/query-index.json');
const { data } = await response.json();
const filtered = data.filter(item => item.category === 'news');
Option 2: External API (for non-content data)
// In AEM: Sling Model calls internal service
// In EDS: decorate() calls external REST API
const response = await fetch('https://api.company.com/products');
const products = await response.json();
Option 3: JSON spreadsheet (for configuration data)
EDS supports Google Sheets or SharePoint spreadsheets as JSON data sources. A spreadsheet at /data/config.xlsx becomes available at /data/config.json. This replaces some use cases for Sling Models that read configuration from JCR.
Key Differences
| Aspect | AEM | EDS |
|---|---|---|
| Business logic location | Java Sling Model | Block JS function |
| Type safety | Java strong typing | JavaScript (use JSDoc for hints) |
| JCR access | ResourceResolver API | Not available |
| OSGi service injection | @OSGiService annotation | Not applicable |
| External API calls | Via injected service | fetch() in block JS |
| Testability | JUnit with AEM Mocks | Browser/unit tests |
| Reusability | Shared Sling Models across components | Import utility functions |
Architect takeaway: If your component has complex server-side logic (JCR queries, OSGi service calls, data transformation), that logic must move to an external API that EDS blocks can call via fetch(). EDS cannot execute Java code.
3. Editable Templates and Template Policies
In AEM
Editable templates provide:
- Structure: Fixed components that authors cannot remove (header, footer, breadcrumb)
- Initial content: Default components pre-populated in the template
- Policies: Per-component configurations that lock down allowed behaviors (which heading styles are available, which colors, which layout options)
- Layout container: Which components are allowed to be added (allowedComponents)
- Template inheritance: Templates can extend other templates
/conf/mysite/settings/wcm/templates/
├── article-template/
│ ├── structure/
│ │ ├── jcr:content/
│ │ │ ├── root (locked)
│ │ │ │ ├── header (locked, structure)
│ │ │ │ ├── responsivegrid (editable)
│ │ │ │ └── footer (locked, structure)
│ ├── policies/
│ │ ├── headline-styles (h1,h2 only)
│ │ └── text-colors (brand palette only)
In EDS
There are no editable templates in the AEM sense. The "template" concept in EDS is much simpler.
EDS page structure is fixed by convention:
<header></header>
<main>
<div><!-- section 1 --></div>
<div><!-- section 2 --></div>
</main>
<footer></footer>
The header and footer are always present and always in the same position. This is structurally locked — but not configurable per page type.
Per-page-type behavior is achieved via the template metadata:
| Metadata |
|-------------------|
| Template | article |
In scripts.js, different templates can load different CSS:
const template = getMetadata('template');
if (template) {
document.body.classList.add(`page-${template}`);
loadCSS(`/styles/templates/${template}.css`);
}
Template-level restrictions (what an author can add): In UE, component-filters.json controls which blocks can be added to sections — but this is global, not per template type.
Policies (restricting component options): There is no equivalent to AEM policies in EDS. A block's options (size, color, layout) are all always available to any author on any page. You cannot lock down "only certain themes are allowed on article pages" the way you can with AEM template policies.
Key Differences
| Aspect | AEM | EDS |
|---|---|---|
| Template structure locking | Yes (structure components) | No |
| Per-template allowed components | Yes (policies) | No — global only |
| Design policies (color/font restrictions) | Yes | No |
| Template inheritance | Yes | No |
| Initial content (pre-populated) | Yes | No |
| Page type differentiation | Templates | Metadata template field |
| Author freedom control | High (per template/policy) | Low (global filters only) |
Architect takeaway: EDS gives authors more freedom and developers less control over author behavior. If your project requires strict brand governance with enforcement (not just guidelines), EDS requires supplementary governance tooling. If your authors are trusted and brand-mature, EDS works well.
4. Component Inheritance (Sling Resource Merger)
In AEM
AEM's Sling Resource Merger provides a powerful inheritance system:
- A component can extend another via
sling:resourceSuperType - You override only the parts you need (specific dialog fields, specific HTL sections)
- The parent's untouched properties merge automatically
- This enables creating a library of base components (Core Components) and extending them for project-specific needs
wcm/foundation/components/text (parent)
└─ mysite/components/text (child - overrides only the dialog)
└─ mysite/components/article-text (grandchild - overrides only the style)
Overlaying is done via /apps/ — placing a file at the same path in /apps/ as an existing /libs/ file overrides that file without modifying the original.
In EDS
There is no inheritance system. There is no overlay mechanism.
Each block is a standalone unit. If two blocks share 80% of their code, you have two choices:
Option 1: Shared utility module
// blocks/shared/block-utils.js
export function parseKeyValue(block, knownFields) {
const props = {};
[...block.querySelectorAll(':scope > div')].forEach((row) => {
const [keyCell, valCell] = [...row.querySelectorAll(':scope > div')];
if (keyCell && valCell) {
const key = keyCell.textContent.trim().toLowerCase().replace(/[\s-]/g, '');
if (knownFields.has(key)) props[key] = valCell;
}
});
return props;
}
// blocks/hero/hero.js
import { parseKeyValue } from '../shared/block-utils.js';
export default function decorate(block) {
const props = parseKeyValue(block, new Set(['title', 'size', 'image']));
// ...
}
Option 2: Block variants instead of separate blocks
Instead of creating hero-article as a separate block extending hero, add an article variant to the existing hero block:
// hero.js handles all variants
const layout = props.layout?.textContent.trim().toLowerCase() || 'default';
block.classList.add(`hero-${layout}`);
/* hero.css handles all variants */
.hero.hero-article { /* article variant styles */ }
.hero.hero-landing { /* landing page variant styles */ }
Key Differences
| Aspect | AEM | EDS |
|---|---|---|
| Component extension | sling:resourceSuperType | Copy/paste + utility functions |
| Overlay | /apps/ overlay of /libs/ | No system — fork or shared module |
| Core Components extension | Standard pattern | No equivalent |
| Inheritance depth | Unlimited (A → B → C) | No inheritance |
| Override granularity | Field level, HTL section level | Full rewrite or utility extraction |
| Maintenance of shared logic | Single parent, N children updated automatically | N copies to update |
Architect takeaway: This is a genuine EDS limitation for large component libraries. Without inheritance, shared logic must be maintained in utility modules and consciously kept in sync across blocks. For a small block library (10-15 blocks), this is manageable. For a large enterprise library (50+ blocks), it requires discipline.
5. Parsys / Layout Container (Drag-and-Drop Component Authoring)
In AEM
The Layout Container (wcm/foundation/components/responsivegrid) is the core of AEM's WYSIWYG authoring model:
- Authors drag and drop components into containers
- Components stack, reorder, and configure without any developer involvement
- Multiple containers per page, each with different allowed component lists
- Nested containers (container inside container)
- Responsive grid (each component can have different column spans at different breakpoints)
This is the defining feature of AEM's page authoring model.
In EDS with Universal Editor
EDS with Universal Editor does support adding blocks to a page and reordering them. Authors can:
- Add any allowed block from the sidebar
- Reorder blocks by drag-and-drop within a section
- Configure block properties in the properties panel
What is different:
| AEM Layout Container | EDS UE Section |
|---|---|
| Nested containers (any depth) | Two levels: section > blocks |
| Per-container allowed components | Global allowed components (component-filters.json) |
| Responsive grid with column spans | No built-in grid — handled by block CSS |
| Multiple containers with independent configs | Multiple sections, same global config |
| Inline editing (click text to edit) | Properties panel (sidebar) editing |
| Real-time collaborative editing | Single-user editing |
The section concept in EDS:
The <main> element contains sections. Each section is a <div>. Blocks are placed within sections. You cannot place a block outside a section. You cannot nest sections.
<main>
<div> <!-- Section 1 -->
<div class="hero block">...</div>
</div>
<div> <!-- Section 2 -->
<div class="cards block">...</div>
<div class="cta block">...</div>
</div>
</main>
In EDS with Document Authoring
DA does not have drag-and-drop at all. Authors order content by position in the document (earlier in the document = earlier on the page).
Architect takeaway: If visual drag-and-drop authoring with per-container component restrictions is a hard requirement, EDS UE comes close but with less granularity than AEM. For DA-authored sites, the drag-and-drop authoring model does not exist.
6. Multifield (Repeatable Author Inputs)
In AEM
The Granite UI Multifield allows authors to add N instances of a field or field group:
<listItems
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
fieldLabel="List Items">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
name="./listItems" />
</listItems>
Authors can add as many items as they need. Each item is stored as a separate child node in JCR.
In EDS with Universal Editor
EDS UE implements the multifield concept via child items — the "+" button that allows adding multiple instances of a sub-block:
{
"title": "Cards",
"id": "cards",
"plugins": {
"xwalk": {
"page": {
"resourceType": "core/franklin/components/block/v1/block",
"template": {
"name": "cards",
"model": "cards",
"filter": "cards-item"
}
}
}
}
}
The filter reference tells UE: the "+" button inside this block adds a cards-item child block.
{
"id": "cards-item",
"components": ["cards-item"]
}
Authors click "+" to add new cards. Each card has its own fields defined in the cards-item model.
The constraint: filter (child items) cannot be combined with key-value: true. See Chapter 3 for the detailed explanation.
In EDS with Document Authoring
In DA, "multifield" is just multiple rows in the block table:
| Cards |
|-------------------------------------|
| Image 1 | Title 1 | Description 1 |
| Image 2 | Title 2 | Description 2 |
| Image 3 | Title 3 | Description 3 |
Each row is one item. Authors add as many rows as needed.
Key Differences
| Aspect | AEM | EDS UE | EDS DA |
|---|---|---|---|
| Dynamic add/remove | Multifield UI | "+" button (filter) | Add/remove table rows |
| Nested fields | NestedMultifield | Child block model | Nested table structure |
| Reordering | Drag handle in multifield | Drag in UE | Move rows in document |
| Max items enforcement | Via validation | Not supported | Not supported |
| Conditional fields per item | Via Granite showHide | Via JSONLogic conditions | Not supported |
7. Workflow
In AEM
AEM Workflow is a full workflow engine:
- Multi-step approval workflows (Author → Reviewer → Legal → Publisher)
- Custom process steps in Java
- Participant choosers (dynamic assignment based on content)
- Deadline-based escalation
- Email notifications
- Integration with Adobe Sign
- Workflow inbox (task management)
- Audit trail
- Workflow models stored in JCR (
/var/workflow/models/)
Workflows are triggered automatically (on content creation, activation) or manually.
In EDS
There is no workflow engine in EDS. The content lifecycle has two states: Draft (in AEM author/DA) and Published (on .aem.live).
The Sidekick provides:
- Preview — pushes content to
.aem.page(staging) - Publish — pushes content from preview to
.aem.live(live) - Delete/Unpublish — removes from live/preview
There is no multi-step approval workflow. If the business requires "Author submits → Manager approves → Legal reviews → Publishes", EDS cannot enforce this natively.
Workarounds:
-
AEM Workflow (for xwalk content): Since xwalk content lives in AEM JCR, standard AEM workflows can be used. The content goes through AEM workflow before being made available for preview. This is not a pure EDS workaround — it uses the AEM layer that xwalk shares with traditional AEM.
-
External review tools: Use a third-party review tool (e.g., Frame.io, external Jira-based review workflow) that integrates with a custom Sidekick plugin to trigger publish only after approval.
-
Sidekick custom plugins: Build a custom Sidekick plugin that intercepts the Preview action and requires approval through an external system before allowing preview/publish.
-
Branch-based workflow: Use GitHub branch strategy (feature branch → PR → review → merge to main triggers publish). This is a developer-centric workaround.
Architect takeaway: For organizations that require enforced multi-step content approval (legal, regulated industries), the absence of a native workflow engine in EDS is a significant gap. The xwalk path (via AEM JCR) partially addresses this by allowing AEM's workflow engine to be used.
8. ClientLibs and the Overlay System
In AEM
AEM's ClientLibrary system provides:
- Categorization: ClientLibs are tagged with categories, and templates include categories
- Dependency management:
dependenciesandembedproperties automatically load required libraries - Overlay: Place a file in
/apps/with the same path as/libs/to override it - Cross-repo sharing: Include another project's ClientLib via Maven dependency
- Build integration: Maven build concatenates, minifies, and version-hashes output
- LESS/SCSS compilation: Client-side preprocessors compiled at build time
<!-- .content.xml for a ClientLib -->
<jcr:root
jcr:primaryType="cq:ClientLibraryFolder"
categories="[mysite.base, mysite.hero]"
dependencies="[core.wcm.components.commons.react.base]"
embed="[mysite.vendor.jquery]" />
The embed property inlines another library's code. The dependencies property ensures another library loads first but remains separate.
In EDS
There is no ClientLib system, no overlay system, and no build-time CSS/JS concatenation.
Direct equivalents:
| AEM ClientLib Concept | EDS Equivalent |
|---|---|
categories (what the lib provides) | Block folder name / CSS class |
dependencies (requires this first) | ES Module import statement |
embed (inline this code) | Copy source, or NPM import and bundle |
Overlay /apps/ over /libs/ | No equivalent — fork or contribute upstream |
| Maven dependency for ClientLib | NPM package (if build step added) |
| LESS/SCSS compilation | CSS custom properties (no preprocessing) |
| Category-based inclusion per template | Template metadata + conditional CSS load |
Cross-repo sharing in EDS:
There is no built-in mechanism for one EDS project to include components from another EDS project the way AEM's ClientLib dependencies (across Maven artifacts) enables it.
Practical options:
- NPM + build step: Add a Webpack/Rollup build step to the project (breaking the "no build" philosophy but enabling NPM dependencies)
- JSPM or import maps: Use import maps to reference shared modules by URL without a build step
- Shared GitHub repository: A "shared" repo that both projects pull from via git submodules
- Copy and maintain: Duplicate the block in both repositories
Multi-theme in single repo:
AEM can handle multiple brands in a single repository via overlays (brand A overrides /apps/mysite/brand-a/ over /libs/base/).
EDS handles this via:
/themes/
├── brand-a/
│ ├── brand-a.css ← Brand-specific CSS variables
│ └── brand-a.js ← Brand-specific logic (rarely needed)
└── brand-b/
└── brand-b.css
In scripts.js, load the appropriate theme CSS based on metadata or URL path:
const brand = new URL(window.location).hostname.split('.')[0];
if (brand !== 'www') {
loadCSS(`/themes/${brand}/${brand}.css`);
}
Theme CSS files override the global CSS custom properties defined in styles.css:
/* themes/brand-b/brand-b.css */
:root {
--color-primary: #0052cc; /* Override brand-a's yellow */
--font-family-sans: 'Inter', sans-serif;
}
This is less powerful than AEM's overlay system (you cannot override JS logic per brand without copying block files), but sufficient for visual theming.
9. Dispatcher
In AEM
The AEM Dispatcher is a reverse proxy and cache layer:
- Caches HTML output from publish instances
- Applies URL rewriting rules
- Handles authentication filtering (prevent caching of personalized content)
- Load balancing between publish instances
- Security filtering (block direct access to AEM paths)
- Header-based cache invalidation
- Flush agents
Dispatcher configuration is complex (Apache httpd.conf, dispatcher.any files) and requires detailed knowledge of rewrite rules and cache invalidation strategies.
In EDS
There is no Dispatcher. The EDS Edge Network (Adobe's CDN infrastructure) handles:
- Content caching at edge nodes globally
- Cache invalidation (triggered by Preview/Publish actions)
- URL routing
- HTTPS termination
Cache invalidation in EDS: When an author clicks Publish, the EDS CDN automatically purges the cache for that page. No manual flush agent required.
No custom Apache rules. You cannot write arbitrary rewrite rules or add server-side logic at the Dispatcher layer. If you need URL rewriting or complex routing, that must happen at a higher-level CDN configuration (via Adobe Managed CDN rules, or a Fastly/Cloudflare layer in front of EDS).
Architect takeaway: Dispatcher is significantly simplified in EDS — mostly automatic. But this means you lose the ability to write custom cache-busting logic, complex rewrite rules, and fine-grained authentication filtering at the edge. These must be handled elsewhere in your architecture.
10. OSGi Services and Schedulers
In AEM
OSGi provides a modular service container:
- Services are registered with
@Componentand discovered via@Reference - Schedulers for background jobs (
@Scheduler,@Component + Runnable) - Configuration via OSGi configuration admin (
.cfg.jsonfiles) - Event-driven patterns (
@EventHandler,ResourceChangeListener) - Service rankings and multiple implementations
This enables background processing, integration services, and complex application logic running continuously on the server.
In EDS
There is no OSGi, no server-side services, no schedulers.
Workarounds:
| AEM OSGi Use Case | EDS Approach |
|---|---|
| Scheduled content sync | GitHub Actions workflow on schedule |
| External API polling | AWS Lambda / Azure Function (external microservice) |
| Event-driven cache invalidation | Webhook → GitHub Action → EDS publish API |
| Background image processing | AEM Assets pipeline (if using UE/xwalk) |
| Email sending on form submission | Form action to external service (Formspree, Adobe Forms) |
Architect takeaway: Any server-side background processing must be handled by external systems (cloud functions, GitHub Actions, third-party services). EDS is purely a delivery mechanism.
The Complete Feature Map
| AEM Feature | EDS Equivalent | Gap Level |
|---|---|---|
| HTL + Sling Model | Block JS + DOM API | Medium — different paradigm, same capability |
| Editable Templates | Template metadata + conditional CSS | High — no structural locking or per-template policies |
| Component Inheritance | Utility modules + copy | High — no inheritance system |
| Parsys / Layout Container | UE sections + block drag-drop | Medium — less granular |
| Multifield | Child items (UE) / table rows (DA) | Low — equivalent capability |
| Workflow | AEM Workflow (xwalk only) / Sidekick plugins | High — no native multi-step workflow in pure EDS |
| ClientLib categories | Block CSS files (auto-loaded per block) | Low — simpler but less flexible |
| ClientLib dependencies | ES Module imports | Low — equivalent |
| ClientLib embed | Copy source / NPM build step | Medium — no runtime embed |
| Overlay (/apps/ over /libs/) | Fork / shared module | High — no overlay system |
| Cross-repo dependencies | NPM / submodules | Medium — possible but no native support |
| Multi-theme single repo | CSS custom property themes | Low — works well for visual theming |
| Dispatcher caching | EDS CDN (automatic) | Low — simpler |
| Dispatcher rules | No equivalent | High — cannot write Apache rules |
| OSGi services | External microservices | High — no server-side services |
| Schedulers | GitHub Actions / cloud functions | Medium — requires external system |
| JCR queries | Query API (JSON index) | High — limited to indexed metadata |
| AEM Forms | Not available | High — no native forms engine |
| Translation workflows | Not available | High — no native translation management |
| MSM / Live Copy | Folder structure only | High — no inheritance or live sync |
| Content Fragments | JSON sheets / Query API | High — no structured content model |
| Experience Fragments | Fragment block | Low — equivalent |
| DAM metadata schemas | Not available | High — no DAM schema enforcement |
Key Takeaways
- EDS is not simplified AEM. It is a different paradigm designed for editorial web delivery.
- What translates well: Component rendering logic (Sling Model → Block JS), ClientLib dependencies (→ ES Modules), multifield (→ child items / table rows), Experience Fragments (→ Fragment block)
- What partially translates: Template-based page types (→ metadata + conditional CSS), multi-theme (→ CSS custom properties), Parsys (→ UE sections, less granular)
- What does not translate: Component inheritance, Dispatcher rules, OSGi services, JCR queries, multi-step workflow, template policies, AEM Forms
- The xwalk path preserves more AEM capabilities: By keeping content in AEM JCR, you retain AEM Workflow, AEM Forms (partially), DAM integration, and structured content
- Choose EDS when: Site content is primarily editorial, performance is critical, authoring simplicity is valued, developer velocity matters
- Avoid pure EDS when: Complex server-side logic is required, regulatory workflow enforcement is needed, existing AEM component library is too large to rebuild, JCR queries are central to the architecture
Next Steps
In the next chapter, we examine the architecture question that most AEM developers ask: Where does content actually go in EDS?
We will cover the content storage architecture: JCR in AEM, da.live content bus in EDS, how the preview/publish pipeline works, where assets are stored, and the lifecycle from authoring to delivery.
Enjoyed this chapter?
Get an email when I publish the next chapter. No spam — just new technical deep-dives.
Comments
Share feedback or questions about this blog post.
No comments yet. Be the first to share your thoughts.