AEM Edge Delivery Services Overview
Overview of AEM Edge Delivery Services, how it differs from traditional AEM, and what changes in the delivery and authoring model.
Content Objective
This chapter covers:
- What AEM Edge Delivery Services actually is and what problem it solves
- How EDS architecture differs from traditional AEM rendering
- What the "Edge" in Edge Delivery actually means
- The two authoring paths: Document Authoring and Universal Editor
- Why performance is a first-class citizen in EDS
- Key concepts you will encounter throughout this series
When developers first hear the phrase "Edge Delivery Services," most assume it is just another Adobe marketing term for a CDN layer in front of AEM.
That assumption is wrong.
AEM Edge Delivery Services is a fundamentally different architecture for building and delivering web content. It is not a feature added on top of traditional AEM. It is a complete rethinking of how content is authored, stored, rendered, and delivered.
If you come from a traditional AEM background, almost everything you know about request flow, rendering, and components works differently here.
Understanding this before writing code is critical. Developers who jump straight into blocks and models without understanding the philosophy end up fighting the framework instead of working with it.
Why Did Adobe Build EDS?
To understand what EDS is, we first need to understand what problem it was built to solve.
Traditional AEM is a powerful content management platform. It handles complex content models, workflows, personalization, and multi-site management very well.
However, traditional AEM has a specific challenge: performance.
In traditional AEM, a page request follows this path:
Browser
↓
CDN / Dispatcher
↓
AEM Publish (Sling Renders the Page)
↓
Response
AEM Publish must execute Java code, resolve Sling resources, execute Sling Models, render HTL templates, and assemble the final HTML on every cache miss. For highly dynamic or frequently updated pages, this creates latency.
Beyond server-side rendering, the real performance killer is often the frontend code that ships with traditional AEM sites: heavy JavaScript frameworks, large clientlibs, blocking resources, and CSS that loads synchronously.
Google's Core Web Vitals made this impossible to ignore.
Starting in 2021, Core Web Vitals became a ranking signal. Slow sites hurt SEO. For enterprise brands running AEM, poor Lighthouse scores were a business problem, not just a technical inconvenience.
Adobe's answer was EDS.
What is AEM Edge Delivery Services?
AEM Edge Delivery Services is a composable, cloud-native content delivery platform designed to deliver perfect Lighthouse scores by default.
The core philosophy is simple:
,[object Object],
EDS achieves performance by:
- Serving static HTML from a global edge network (no server-side rendering per request)
- Delivering zero JavaScript frameworks out of the box (vanilla ES modules only)
- Using lazy loading for everything below the fold
- Generating critical CSS inline to avoid render-blocking stylesheets
- Treating performance as a constraint, not an afterthought
This is a meaningful shift. In traditional AEM, performance is something you optimize after building. In EDS, performance is built into the architecture before you write a single line of code.
The EDS Architecture
The EDS architecture involves three primary layers.

Layer 1: Authoring
Content is created by authors in one of two places:
- Document Authoring (DA) — Authors write in a Google Docs or SharePoint document using familiar tools. Tables become blocks. Headings become sections. The experience is as simple as writing an email.
- Universal Editor (UE) — Authors edit directly on the rendered page in a WYSIWYG interface, similar to the AEM Sites page editor. This is called the xwalk approach and is what you are using if you connected EDS to AEM Cloud Service.
Both authoring paths ultimately produce the same output: structured content that EDS can understand.
Layer 2: Sync and Preview
When an author saves or publishes content, a sync process runs:
Author saves content
↓
AEM Code Sync (GitHub App) detects changes
↓
Content is pushed to the EDS Content Bus
↓
Preview URL becomes available (.aem.page)
The aem-code-sync GitHub app bridges your GitHub repository (where your blocks and styles live) with the AEM Edge network. Your code and your content travel through different paths but are assembled at the edge.
Layer 3: Delivery
When a user visits your site, the request is served from the AEM Edge Network, which is a global CDN backed by Fastly.
User's Browser
↓
AEM Edge Network (nearest PoP)
↓
Cached HTML Response (static, pre-built)
There is no AEM Publish instance involved in a production page request. There is no Sling. There is no Java. The HTML was already built and is sitting at the edge node closest to the user.
This is why EDS sites consistently score 100 on Lighthouse. The delivery layer does not have the same bottlenecks as traditional AEM.
The Two Delivery URLs
Every EDS site has two delivery URLs. Understanding the difference is essential for day-to-day development.
| URL Pattern | Purpose |
|---|---|
main--{repo}--{owner}.aem.page | Preview — Latest authored content, used for review and testing |
main--{repo}--{owner}.aem.live | Live — Published content, your production URL |
For your project:
Preview: https://main--eds-poc--codewithnaveenrapelli.aem.page
Live: https://main--eds-poc--codewithnaveenrapelli.aem.live
When an author previews a page, they see it on .aem.page. When they publish, it becomes available on .aem.live.
Important: Publishing in EDS means pushing content from preview to live. It does not mean deploying code. Code is always deployed by pushing to the main branch of your GitHub repository.
How a Page Request Works in EDS
Let's trace a complete page request to understand what happens under the hood.
When a user visits https://main--eds-poc--codewithnaveenrapelli.aem.live/adc-test:
1. Browser requests /adc-test
2. Request hits AEM Edge Network (CDN)
3. Edge returns cached HTML (if available)
4. Browser downloads scripts/styles from same origin
5. JavaScript runs: scripts.js + delayed.js
6. Blocks are decorated: decorate() called for each block
7. Page is fully rendered
Notice that steps 1-3 happen before any JavaScript runs. The HTML structure is already in the response. JavaScript enhances the page, it does not build it.
This is a critical architectural difference from SPA-based approaches where JavaScript is the page.

What is a Block?
If you come from traditional AEM, you are used to components: Java classes, HTL templates, Sling Models, dialogs.
EDS does not have any of those.
In EDS, the fundamental unit of UI is a block.
A block is:
- A folder in your GitHub repo with two files:
block-name.jsandblock-name.css - An HTML table in the authored document with the block name as the first cell
- A
decorate(block)function that receives the block's DOM element and transforms it
When EDS loads a page, it finds all block tables in the HTML, maps them to their corresponding JavaScript files, and calls decorate() on each one.
That is the entire component model. No Java. No OSGi. No XML dialogs.
Document (DA or UE)
↓ author creates a table with "Hero" as the header
↓
HTML served to browser
↓
<div class="hero block">...</div>
↓
scripts.js loads blocks/hero/hero.js
↓
hero.js decorate(block) runs
↓
Rendered Hero
This simplicity is intentional. It means any developer who knows HTML, CSS, and JavaScript can build blocks without learning a new framework.
Document Authoring vs Universal Editor
Many developers are confused about which authoring path to use. The difference is:
Document Authoring (DA)
Authors write content in Google Docs or SharePoint. A table in the document becomes a block. The first row is the block name, subsequent rows are the block's content.
| Hero |
|-------------------------|
| Desktop Image | ← desktopImage field
| Title | ← title field
| Subtitle | ← subtitle field
This is the original EDS authoring approach. It is extremely fast for authors who live in Google Workspace or Microsoft 365. No training required. Authors already know these tools.
Best for: Content-heavy sites where authors are non-technical and prioritize speed of authoring.
Universal Editor (xwalk)
Authors edit directly on the rendered page. Fields appear as a properties panel when they click on a block. This feels identical to the traditional AEM Sites editor.
This approach requires:
- AEM Cloud Service instance
- AEM Code Sync connected to your GitHub repo
- Component models (
_block.json) that define each block's editable fields - Component definitions and filters for the UE sidebar
Best for: Teams migrating from traditional AEM who want a familiar editing experience, or organizations that need WYSIWYG editing without asking authors to work in spreadsheets.
This series focuses on the Universal Editor (xwalk) approach because that is the direction most enterprise AEM teams are moving.
The Project Structure
Every EDS project follows the same folder structure. This is not optional. The framework expects it.
your-project/
├── blocks/ ← All UI blocks live here
│ ├── hero/
│ │ ├── hero.js ← Block decorator function
│ │ ├── hero.css ← Block styles
│ │ └── _hero.json ← UE component model (xwalk only)
│ ├── cards/
│ └── footer/
├── scripts/
│ ├── scripts.js ← Page bootstrap, block loading
│ ├── aem.js ← EDS core utilities
│ └── delayed.js ← Non-critical scripts (analytics etc.)
├── styles/
│ ├── styles.css ← Global styles, CSS custom properties
│ ├── fonts.css ← Font declarations
│ └── lazy-styles.css ← Styles loaded after LCP
├── icons/ ← SVG icons referenced in content
├── models/ ← Shared UE model fragments
├── component-definition.json ← UE block registry
├── component-filters.json ← UE section filter rules
├── component-models.json ← UE model aggregator
├── fstab.yaml ← Content source mapping
├── head.html ← Extra tags injected into <head>
└── helix-query.yaml ← Content query configuration
Every file has a specific purpose. Nothing is arbitrary. In Chapter 3 we will walk through each file in detail.
Common Misconceptions About EDS
Misconception #1: EDS is just a CDN wrapper around AEM
Not true.
EDS replaces the entire rendering layer of traditional AEM. There is no Sling request processing. There is no HTL rendering. There is no Java code running per page request. EDS is a completely different rendering and delivery architecture.
Misconception #2: You need to know React or a JavaScript framework
Not true.
EDS is intentionally framework-free. Blocks are written in vanilla JavaScript. If you know document.querySelector, element.classList, and fetch, you can build anything in EDS.
Adding a JavaScript framework defeats the purpose of EDS. The performance architecture depends on zero framework overhead at load time.
Misconception #3: EDS is only for simple sites
Not true.
Enterprise brands including HSBC, Volvo, and Adobe.com itself run on EDS. Complex personalization, A/B experimentation, multi-language support, and e-commerce integrations are all supported.
The architecture handles complexity through composition of blocks, not through a monolithic rendering engine.
Misconception #4: EDS blocks are the same as AEM components
They are similar in concept but completely different in implementation.
| AEM Component | EDS Block |
|---|---|
| Java + Sling Model | Vanilla JavaScript |
| HTL Template | DOM manipulation in JS |
| XML Dialog | _block.json model (xwalk) |
| ClientLibs | block.css loaded per-block |
| Resource Type | Block folder name |
| Server-side rendered | Client-side decorated |
The mental model is similar (a self-contained unit of UI with content and presentation) but the implementation is entirely different.
Misconception #5: You can ignore Core Web Vitals in EDS
EDS makes good scores easy, but you can still break them.
Common ways developers degrade EDS performance:
- Loading third-party scripts in the critical path instead of
delayed.js - Using
document.writeor synchronous XHR in block decorators - Importing heavy libraries inside blocks (moment.js, lodash, etc.)
- Adding render-blocking stylesheets in
head.html - Not lazy-loading images below the fold
EDS gives you a 100/100 starting point. It is your job to not break it.
Real Production Scenario: Why My Block Doesn't Load
One of the most common issues developers encounter when starting with EDS:
,[object Object],
Most developers immediately start debugging JavaScript or checking for syntax errors.
The actual cause is almost always one of these:
-
Block folder name does not match class name — The folder
hero-bannergenerates classhero-banner. If your table header says "Hero Banner" (with a capital H), EDS converts it tohero-banner. These must match exactly. -
The block is not registered in
component-definition.json(xwalk only) — Universal Editor will not show the block in the sidebar until it is registered. -
_block.jsonhas a JSON syntax error — A trailing comma or missing bracket will prevent the UE from loading the entire properties panel, not just the broken block. -
The
decorate()function is not exported as default —scripts.jscallsblock.default(block). If you export a named function instead ofexport default function decorate(block), it will fail silently. -
Wrong file name — The JS file must be named exactly
{folder-name}.js.hero.jsmust be in thehero/folder.
blocks/
└── hero/
├── hero.js ← Must match folder name exactly
└── hero.css ← Must match folder name exactly
Start with the simplest possible check: does the block class name in the DOM match the folder name exactly?
We will cover block debugging in depth in Chapter 5.
The Performance Guarantee
Before we close this chapter, it is worth understanding why the performance of EDS matters beyond just Lighthouse scores.
Google's Core Web Vitals directly influence organic search ranking. For enterprise brands, a 10-point improvement in LCP (Largest Contentful Paint) can translate to measurable increases in organic traffic.
EDS delivers near-perfect scores by default because:
| Traditional AEM | EDS |
|---|---|
| Server renders HTML on request | HTML pre-built at edge |
| JavaScript framework loads first | Zero framework, blocks load lazily |
| All CSS blocks rendering | Critical CSS inline, rest deferred |
| Images need manual optimization | Auto-optimized via image delivery API |
| Fonts load synchronously | Font swapping with preloads |
The performance is built into the architecture. You start at 100. Your job is to not break it.
Key Takeaways
- EDS is not a CDN layer on top of traditional AEM — it is a completely different rendering and delivery architecture
- There is no server-side rendering per request — HTML is pre-built and served from the edge network
- Blocks are the fundamental unit of UI — a folder with a JS file, a CSS file, and an optional JSON model
- Two authoring paths exist: Document Authoring (Google Docs / SharePoint) and Universal Editor (WYSIWYG, xwalk)
- This series covers the Universal Editor (xwalk) path with AEM Cloud Service
- Performance is built-in, not bolted-on — EDS starts at 100/100 Lighthouse by design
- The project structure is fixed and intentional — every file has a specific purpose
- Most "block not loading" issues are not code bugs — they are naming, registration, or JSON syntax issues
- Zero JavaScript frameworks — vanilla ES modules only, by design
Next Steps
In the next chapter, we will set up a complete EDS project from scratch:
- Creating and connecting a GitHub repository
- Installing the
aem-code-syncGitHub App - Configuring
fstab.yamlto connect your AEM Cloud content - Understanding
helix-query.yamlandhelix-sitemap.yaml - Running the local development server with
aem up - Previewing your first page end-to-end
By the end of Chapter 2, you will have a fully working local EDS environment connected to your AEM Cloud instance and your first page rendering in the browser.
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.