In my introduction to ACCS I mentioned, almost in passing, that Adobe Commerce as a Cloud Service doesn’t support Luma. A few readers messaged me about that line more than anything else in the post. Fair enough. For most Magento frontend developers, Luma, Knockout and RequireJS have been the daily routine for years. So this post covers what replaces them: the Commerce Storefront on Edge Delivery Services.
I went through Adobe’s Commerce Storefront docs and the public boilerplate repo (hlxsites/aem-boilerplate-commerce) while writing this. The code below is copied from that repo, not invented. Where I’m giving an opinion rather than a fact, I’ll say so.
What Edge Delivery Services actually is
Edge Delivery Services (EDS) is Adobe’s hosting and delivery layer. It’s the same one behind AEM’s document-based sites. It takes content authored as documents, turns it into HTML and serves it from servers close to the shopper. You don’t run servers and you don’t run deployments. You push code to GitHub and EDS builds and publishes it.
That’s a big change from a PHP-rendered storefront. Magento doesn’t render the shopper-facing page anymore. The Commerce Admin, catalog and orders stay on the backend. The page itself is plain HTML, CSS and JavaScript.
Why ACCS uses EDS instead of Luma
It follows from how ACCS works. ACCS is versionless and you can’t touch the core code. A Luma theme is PHP templates, layout XML and overrides that live inside the application, which is exactly what ACCS doesn’t allow. A headless storefront that talks to Commerce only through GraphQL fits that model. Adobe updates the backend, and your frontend stays in your own Git repo, where it doesn’t get in the way of those updates.
Personally, I also think Adobe wanted one modern storefront it could put its weight behind instead of maintaining Luma forever. That part is my opinion, not something the docs say.
The architecture in three layers
Adobe’s architecture page describes it as three layers, and I find that the clearest way to think about it.
- Authoring. Merchants create pages as documents in DA.live (Adobe’s Document Author), Google Docs or SharePoint. A table inside a document defines a block, such as a hero or a product list.
- Delivery and logic. EDS turns those documents into HTML. Your Git repo holds the blocks, which are small JavaScript and CSS files that decorate each part of the page.
- Data. Commerce blocks load drop-in components, which are npm packages for cart, checkout, product details, search and account. Drop-ins call the Commerce GraphQL APIs (core Commerce, Catalog Service and Live Search) directly from the shopper’s browser.
API Mesh fits in on the data side. If you need to add a third-party source, such as stock from an ERP, you can merge it into the GraphQL layer instead of writing custom resolvers inside Commerce. I covered where that fits against PaaS in my ACCS vs Adobe Commerce on Cloud comparison.
One licensing detail that surprised me: the docs say drop-ins are included with an ACCS or Adobe Commerce Optimizer licence. If you’re on Adobe Commerce on Cloud (PaaS), you need a separate Adobe Commerce Optimizer licence to use them, plus the Compatibility Package on the backend.
Setting up the boilerplate, step by step
This is the order the docs recommend, with my notes added.
- Prerequisites. Get your GitHub account, Node, DA.live access and your Commerce backend details ready before you start.
- Confirm the backend. ACCS, Commerce on Cloud or Commerce Optimizer. On ACCS the services are already wired up, which saves a lot of time.
- Run Site Creator. The Site Creator app in DA.live sets up your repo, content, theme and storefront config, and gives you a preview URL. This is where your first working store comes from.
- Clone and install locally. Then follow the local development steps below.
Local setup has one gotcha that the README spells out. The repo’s .npmrc sets ignore-scripts=true as protection against npm supply-chain attacks. As a result, npm install on its own does not copy drop-in assets into scripts/__dropins__. You have to run the copy step yourself:
npm install
npm run install:dropins
npm startnpm start runs aem up, the local AEM dev server. If you skip install:dropins, things break in confusing ways, so make it a habit after every dependency change.
Customising blocks and drop-ins
Blocks
A block is a folder under blocks/ with a JS file and a CSS file. The JS file exports a decorate(block) function. Here’s the top of the boilerplate’s mini cart block. It reads its settings from the authored document with readBlockConfig:
import { render as provider } from '@dropins/storefront-cart/render.js';
import MiniCart from '@dropins/storefront-cart/containers/MiniCart.js';
import { events } from '@dropins/tools/event-bus.js';
// Initializers
import '../../scripts/initializers/cart.js';
import { readBlockConfig } from '../../scripts/aem.js';
export default async function decorate(block) {
const {
'start-shopping-url': startShoppingURL = '',
'cart-url': cartURL = '',
'checkout-url': checkoutURL = '',
} = readBlockConfig(block);
// ...
}The nice part: a merchant can change the cart URL in a document table without a developer deploying anything.
Drop-ins and initializers
Each drop-in gets set up once by an initializer in scripts/initializers/. The cart one points the drop-in at the core GraphQL endpoint and loads labels from a placeholders file:
await initializeDropin(async () => {
setEndpoint(CORE_FETCH_GRAPHQL);
const labels = await fetchPlaceholders('placeholders/cart.json');
const langDefinitions = { default: { ...labels } };
return initializers.mountImmediately(initialize, { langDefinitions });
})();(I trimmed a feature flag from the real file.) Beyond that, the docs give you several levels of customisation: restyle drop-ins with CSS, move or replace parts of the UI with slots, listen to drop-in activity through the event bus for analytics, and if nothing shipped fits, build your own drop-in with the Drop-in SDK. In practice I’d stay on the first three for as long as possible.
Performance and Lighthouse
EDS is built around performance. The AEM docs even have a guide called “Keeping it 100”, about holding a Lighthouse score of 100. The page arrives as lean HTML from the edge, and blocks load progressively. Compare that with a stock Luma theme, where getting good Lighthouse scores usually takes a lot of tuning. Your mileage will vary once marketing adds three tag managers.
Keep in mind that drop-ins fetch cart and account data in the browser, so a slow GraphQL response or a heavy API Mesh source shows up as a slow component, not a slow page.
SEO
Adobe has a dedicated SEO section that covers indexing, metadata, launch checks and even generative engine optimisation (GEO). Content pages are server-delivered HTML, which helps crawlers. Product pages need more care, since their data comes from Commerce, so read the indexing guidance before launch rather than after. Fast pages and clean HTML help, but they don’t replace a redirect plan when you move from Luma URLs.
EDS vs Luma vs Hyvä vs PWA Studio
| EDS Storefront | Luma | Hyvä | PWA Studio | |
|---|---|---|---|---|
| Works on ACCS | Yes | No | No | No (not the supported path) |
| Rendering | Edge HTML + browser drop-ins | PHP server-side | PHP server-side | React app |
| Stack | Vanilla JS, CSS | Knockout, RequireJS, LESS | Alpine.js, Tailwind | React, GraphQL |
| Content authoring | Documents (DA.live, Docs, SharePoint) | CMS, Page Builder | CMS, Page Builder | Mostly code |
| Hosting | Adobe edge, no servers | Commerce app | Commerce app | Separate Node host |
Limitations and gotchas
- Your fork is yours. The README is clear: once you fork the boilerplate, you don’t get updates. Suite releases (like
b2c-march-2026) are snapshots for new projects, not upgrades. You track the@dropins/*and@adobe/*npm packages yourself. There’s a weekly GitHub Action that opens update PRs, but it silently does nothing if your org blocks Actions from creating PRs. - Forgetting
install:dropinsafter a dependency bump. Covered above, and it’ll catch you at least once. - Different authoring habits. Merchants used to Page Builder need training on document tables. Some love it. Some don’t.
- Theme rewrite. Nothing from Luma or Hyvä carries over. Budget it as a frontend project.
- Browser-side data. Personalised and cart data load client-side, so design your loading states properly.
When Hyvä or PWA Studio still makes sense on PaaS
If you’re staying on Adobe Commerce on Cloud, EDS is optional, and it comes with that extra Commerce Optimizer licence. Hyvä is still a very sensible choice for a PaaS store with lots of PHP customisations and third-party modules that ship Hyvä compatibility. Your team stays in PHP and the performance is good. I’d only consider PWA Studio if you already run it and it’s stable. For a new headless build on PaaS, I’d evaluate EDS first, since that’s where Adobe is putting its effort.
Where I’d start
If you have access to a sandbox, run Site Creator this week and get a preview running. Then clone the repo, run the three commands above, and change one thing: restyle the mini cart or add a field to a block config. One afternoon of that will teach you more about the EDS model than reading the whole docs site. I’ll cover slots and the event bus in more depth in a later post.




