Skip to main content
OZAN ALTINBAS
Architecture

SFRA vs PWA Kit: Choosing Your SFCC Storefront Architecture

By 13 min read

SFRA and PWA Kit are the two storefront architectures most Salesforce B2C Commerce teams have shipped since 2021, and the choice fixes where pages render, where code runs, which skills you need and how hard the next migration will be. SFRA renders HTML on the B2C Commerce application server from cartridges. PWA Kit is a React application on Managed Runtime that talks to the platform over SCAPI.

The SFRA-or-headless question also has a new answer in 2026: Salesforce's storefront chooser now marks Storefront Next as the recommended option for new storefronts and has no separate PWA Kit row. This guide compares SFRA and PWA Kit technically, shows where Storefront Next fits, and goes deep on hybrid routing and session sync. For the business case for headless, read Headless Commerce Cloud: is it right for your business?; for a platform overview, start with the SFCC guide.


The short answer

  • SFRA fits a team strong in the Script API and ISML that wants a complete storefront quickly and relies on connector cartridges with their own storefront UI.
  • Headless fits a team with React and Node.js skills that wants app-like navigation or several front ends on one back end, and can own a second deployable. For a new headless build, evaluate Storefront Next before PWA Kit.
  • Hybrid fits an existing SFRA site moving page groups to headless one at a time, with a due date for finishing.

SFRA, PWA Kit, Composable Storefront, Storefront Next: what the names mean

Search results mix these terms:

NameWhat it isWhere it runsHow it reads commerce data
SFRA (Storefront Reference Architecture)Reference storefront delivered as cartridges: JavaScript controllers in an MVC pattern, ISML templates, Bootstrap 4B2C Commerce application serversScript API (dw.*), in the same process
PWA KitReact framework plus the Retail React App templateManaged RuntimeSCAPI through @salesforce/commerce-sdk-react hooks; SLAS for shopper login
Composable StorefrontSalesforce's product name for PWA Kit and Managed Runtime togetherManaged RuntimeSCAPI (OCAPI can be called too, but it is deprecated as of April 2026)
Storefront NextServer-first React storefront: React Router 7 framework mode, React 19, Tailwind CSS, shadcn/ui, ViteManaged RuntimeGenerated SCAPI clients called from route loaders and actions

The Composable Storefront overview describes two technologies: PWA Kit to build the storefront and Managed Runtime to host it. Both came from Mobify (acquired by Salesforce in 2020), hence the /mobify paths. The SFRA overview dates PWA Kit's launch, as an alternative to SFRA, to 2021.


How SFRA works

An SFRA request goes through the eCDN to a B2C Commerce application server. The cartridge path resolves the controller, which builds view data through models and the Script API, and an ISML template renders the HTML. Routing, data access and rendering share one process: there is no network hop between "storefront" and "commerce engine".

You customise by overlay: a custom cartridge extends a base controller with server.append, server.prepend or server.replace and never edits app_storefront_base (see the cartridge development guide).

Caching is declared per route. SFRA ships middleware in app_storefront_base/cartridge/scripts/middleware/cache.js: applyDefaultCache (24 hours), applyInventorySensitiveCache (30 minutes) and two promotion-sensitive variants that also mark the response as personalised.

// app_custom/cartridge/controllers/Brand.js
'use strict';

var server = require('server');
var cache = require('*/cartridge/scripts/middleware/cache');

// Rendered on the B2C Commerce app server; applyDefaultCache sets a 24-hour page cache
server.get('Show', cache.applyDefaultCache, function (req, res, next) {
    var CatalogMgr = require('dw/catalog/CatalogMgr');
    var category = CatalogMgr.getCategory(req.querystring.cgid);

    res.render('brand/landing', {
        categoryName: category ? category.displayName : null
    });
    next();
});

module.exports = server.exports();

You get one codebase, one deployment target and the whole Script API; you pay with a full document request on every navigation.


How PWA Kit works

PWA Kit projects usually start from the Retail React App, a server-side rendered React storefront with home, listing, product, cart and checkout pages already built. Since v3, template extensibility lets you override individual files in an overrides/ directory instead of forking the app.

Per the PWA Kit overview, the same source runs in two contexts. The first request is rendered by Managed Runtime's App Server (React, Node.js and Express); the browser then hydrates the page and later navigations happen on the client. Salesforce's Storefront Next migration reference spells out a consequence: PWA Kit is stateless on the server, so pages are server-rendered as a guest shopper would see them, and client-side state lives in TanStack Query.

Commerce data comes from SCAPI through commerce-sdk-react hooks, with SLAS issuing shopper tokens. If your integrations still run on OCAPI, read SCAPI vs OCAPI first.

// overrides/app/pages/product-detail/index.jsx (excerpt)
import {useProduct} from '@salesforce/commerce-sdk-react'

// productId comes from the route params. The hook calls the SCAPI Shopper
// Products API; React Query caches the response and hydrates it on the
// client after server-side rendering.
const {data: product, isLoading} = useProduct({
    parameters: {
        id: productId,
        allImages: true,
        expand: ['availability', 'images', 'prices', 'variations']
    }
})

PWA Kit on Managed Runtime: services and limits

Managed Runtime puts a web application firewall, an API proxy, a CDN and edge functions (such as the request processor) in front of the App Server. Deployments are immutable bundles; rolling back means deploying an earlier one. Constraints to design around:

  • App Server requests time out after 20 seconds in production and 16 seconds elsewhere (HTTP 502).
  • Requests and responses are capped at 6 MB; bundles at 400 MB.
  • Cookies are off by default and must be enabled per environment. Hybrid Auth needs them.
  • The production environment limit starts at 0, so ask Support to raise it well before launch. Since 29 September 2026, only environments associated with a Staging or Production B2C Commerce instance can be marked as production.
  • Further environments cost nothing extra, up to 100 per organisation.

The default Cache-Control lifetime for PWA Kit page responses is 600 seconds. Salesforce's cache hit ratio guide says to keep personalised and fast-changing content (names, cart counts, prices, inventory, promotions) out of the server render so the CDN can reuse it, and to strip marketing parameters in app/request-processor.js so similar URLs share a cache entry.


Where Storefront Next fits

Storefront Next is Salesforce's newer headless storefront and the "recommended option" in the storefront chooser. It keeps PWA Kit's back end (SCAPI, SLAS and Managed Runtime) and changes the front end:

  • Server-first data flow. Route loaders fetch data before rendering, with streaming SSR and Suspense, instead of PWA Kit's fetch-on-render hooks.
  • Sessions in httpOnly cookies managed on the server, where PWA Kit commonly keeps tokens in browser storage.
  • Tooling. Vite, Vitest and strict TypeScript instead of Webpack and Babel; React Router 7 file-based routes instead of React Router 5; Tailwind and shadcn/ui instead of Chakra.

Salesforce provides a migration tool for SiteGenesis, SFRA and PWA Kit storefronts. PWA Kit is still documented, the Hybrid Auth guide targets v3, and the Managed Runtime feature retirement list names no PWA Kit end date. But its policy only guarantees security patches for 24 months after each major version's general availability, and v3.0.0 shipped in June 2023: confirm v3's support horizon with Salesforce before planning years ahead. Most of this article applies to both headless options; the differences sit in the React layer.


SFRA vs PWA Kit side by side

DimensionSFRAPWA Kit
RenderingServer-side ISML; full document on every navigationServer-side render on first request, then client-side navigation
Data accessScript API in the same processSCAPI over HTTPS, SLAS tokens
DeploymentCode versions on B2C Commerce instancesImmutable bundles on Managed Runtime, plus a cartridge for hooks and Custom APIs
Page cachingPer-route page cache set by middlewareManaged Runtime CDN driven by Cache-Control (600 s default)
PersonalisationRendered on the server per request; weigh it against the page cacheServer renders the guest view; personalise on the client
Core skillsScript API, ISML, cartridge overlays, BootstrapUniversal React, Node.js and Express, REST APIs, Webpack (Skills for Success)
Extending behaviourserver.append, prepend, replace in an overlay cartridgeTemplate extensibility, SCAPI hooks (before, after, modifyResponse), Custom APIs
Page DesignerISML page types and components; SFRA ships layouts and componentsHeadless Page Designer: React components, arch_type: "headless" metadata, usePage()
EinsteinBuilt-in display of Einstein recommendations and predictive search (SFRA features)Retail React App's useEinstein hook calls the Einstein API from the browser
Active DataNativePWA Kit 3.3.0 or later; product use cases only
Connector cartridgesPlug in, UI includedServer logic can run in hooks; storefront UI must be rebuilt in React

Page Designer. Headless Page Designer needs PWA Kit 2.7.0 or later, a SLAS client with the sfcc.shopper-experience scope, and arch_type: "headless" in every page, component and aspect type metadata file. Custom scripts in headless metadata are ignored, so logic that sat in a component script moves into React. Each Business Manager site can be connected to only one Managed Runtime environment. ISML and headless pages can coexist, so merchandisers keep working while pages migrate.

Einstein. The Retail React App's useEinstein hook sends activity events (product views, searches, add-to-cart, checkout steps) and fetches recommendations from the Einstein API, skipping both when Do Not Track is on. On a custom headless build you own that instrumentation, and recommendation quality depends on it.


Performance: what actually differs

Neither architecture is fast by default; they fail in different places.

  • SFRA pays for a full document request on every click. A page-cache hit is cheap; a miss runs controllers and templates on the app server. The usual problem is personalisation quietly lowering the cache hit rate (see the SFCC caching guide).
  • PWA Kit pays on the first visit: server render, JavaScript download and hydration on the shopper's device. After that, Salesforce notes, "subsequent page requests can often be served without server requests". The client-side weight is the trade-off that Storefront Next's server-first model addresses.

Salesforce's go-live checklist recommends Lighthouse CI from mid-implementation so regressions surface early. Ignore vendor benchmark tables: compare your own field data (Chrome UX Report or RUM) for the templates that carry revenue.


SEO implications

Both send server-rendered HTML; for PWA Kit the question is what that HTML contains.

  • Check the server render. Append ?__server_only to a PWA Kit URL to stop hydration and see what the server delivered. Entry pages (home, category, PLP, PDP) need their real content there, with little layout shift once the client takes over.
  • Keep your URLs. The Retail React App's default routes, /category/:categoryId and /product/:productId, are unlikely to match your SFRA URL rules. Salesforce's checklist notes most customers keep their existing URLs, and recommends redirecting any that won't exist and watching rankings in Search Console. Managed Runtime manages redirects, and SCAPI has a Shopper SEO url-mapping endpoint.
  • Sitemaps still come from the platform. For PWA Kit, hybrid or custom headless sites, B2C Commerce can generate the sitemap once an eCDN vanity domain and matching hostname alias exist; routes not configured in Business Manager go through the uploadCustomSitemapAndTriggerSitemapGeneration endpoint.
  • In hybrid, crawlers see one hostname, but two stacks emit <head> tags, so canonical, hreflang and structured-data logic must produce identical output on both.

The Commerce Cloud SEO guide covers the platform-side settings.


Cost to build and run

Licensing depends on your contract (see Salesforce Commerce Cloud pricing), but the structural costs are clear:

  • SFRA: one codebase, one pipeline, one skill set, and a complete reference storefront to start from.
  • PWA Kit: two codebases (the React app, plus cartridges for hooks, Custom APIs, jobs and services), two pipelines, Managed Runtime roles in Account Manager, and front-end dependency upgrades you own.
  • Hybrid: both, plus the routing between them. In Salesforce's words, "the longer your site is in hybrid mode, the more time you have to spend on the operating complexity involved".

Hybrid storefronts: running SFRA and PWA Kit together

Salesforce calls this a hybrid storefront or phased headless rollout: one hostname, some paths served by SFRA, others by a headless storefront on Managed Runtime.

How traffic is split

The eCDN, available on Primary Instance Group (production, staging, development) and on-demand sandbox instances, evaluates a Cloudflare rule expression at the edge: matching paths go to the Managed Runtime origin, everything else to SFRA. You set the rule in the Business Manager eCDN UI or with the CDN Zones API's createMrtRules endpoint (CDN routing rules).

The hybrid routing matrix lists six ready-made splits: Modern Core (only cart and checkout stay on SFRA), Modern Checkout, Modern Entry Only, Legacy Entry Only, Catalog-Only, and Account and Auth Only. The Catalog-Only expression sends category, product and search pages to PWA Kit:

(http.request.uri.path matches "^(/[^/]+/[^/]+)?/(category|product|search)(/.*)?$" or http.request.uri.path matches "^/mobify.*" or http.request.uri.path matches "^/callback.*" or http.request.uri.path matches "^/worker\.js.*")

The last three clauses are required in every configuration: /mobify carries PWA Kit's proxies and static assets, /callback the SLAS authentication callback, and /worker.js the service worker.

Edge routing is half the job. In the PWA Kit app, remove SFRA-owned paths from app/routes.jsx (or overrides/app/routes.jsx) so React Router does a full page load instead of a client-side transition, and make the catch-all route redirect to the default origin instead of rendering PageNotFound. Keep the two definitions complementary. Localhost has no eCDN, so local development uses the hybrid proxy in pwa-kit-runtime.

How sessions stay in sync: Hybrid Auth

SFRA identifies a shopper with the dwsid session cookie; PWA Kit uses a SLAS JWT. Since B2C Commerce 25.3, Hybrid Auth keeps the two in sync inside the platform and replaces the older Plugin SLAS cartridge. The setup in outline:

  1. Create a SLAS client (public or private) with the sfcc.session_bridge scope.
  2. In Business Manager, open Merchant Tools > Site Preferences > Hybrid Auth Settings, enable it and enter the same client ID.
  3. Remove plugin_slas from the cartridge path, and make sure no custom code calls the session bridge endpoints itself.
  4. In PWA Kit, enable hybridAuthEnabled on CommerceApiProvider, then enable cookies on the Managed Runtime environment.
// overrides/app/components/_app-config/index.jsx (excerpt)
<CommerceApiProvider
    // ...existing props
    hybridAuthEnabled={true}
>

The setup guide's prerequisites are PWA Kit 3.12 or later and commerce-sdk-react 4.0.0 or later; new implementations must start on v3. Third-party identity provider logins must run through SLAS, not Business Manager. Hybrid Auth supports SiteGenesis as well as SFRA.

Storefront Next in hybrid mode

The eCDN routing and Hybrid Auth setup are the same. On the app side, Storefront Next declares which paths belong to SFRA in config.server.ts:

site: {
    hybrid: {
        enabled: true,
        legacyRoutes: ['/cart', '/checkout', '/checkout/:confirmationId'],
    },
}

The eCDN rule must also send ^/resource.* and ^/action/.* to Managed Runtime, because React Router resource routes and actions live there.

Hybrid rules of thumb

  • Move more than one page. Salesforce recommends the home page plus the next one or two steps of the most common journey; the SPA benefit only appears when shoppers navigate between headless pages.
  • Read the basket guidance in Salesforce's hybrid implementation guidance before both stacks write to the same basket.
  • Set an end date. Every month in hybrid means two front ends to patch and test.

Migration paths

FromToRoute
SFRAPWA Kit or Storefront NextHybrid rollout by page group, starting with Catalog-Only or Modern Core
PWA KitStorefront NextSalesforce's migration reference and migration tool; same SCAPI, SLAS and Managed Runtime back end
SiteGenesisHeadlessHybrid with Hybrid Auth; Salesforce does not support SiteGenesis with Plugin SLAS

Server-side assets survive a move to headless: services, jobs, custom objects and Business Manager configuration. The presentation layer does not: ISML, client-side JavaScript and view logic in SFRA controllers. Business logic in controllers must move into SCAPI hooks or Custom APIs, and that refactor is often what an estimate misses.


Decision matrix

SituationChooseWhy
New storefront, Script API and ISML team, fixed launch dateSFRAComplete reference storefront, one deployable, connector cartridges plug in
New storefront, React and TypeScript team, long-term headless planStorefront Next, after evaluating it against PWA KitSalesforce's recommended option; same SCAPI, SLAS and Managed Runtime back end
Live PWA Kit site that performs wellStay on PWA Kit v3, keep upgrading, plan the Storefront Next moveStill documented and targeted by Hybrid Auth; a migration reference and tool exist
Live SFRA site with slow browse pagesHybrid, catalogue pages firsteCDN routing plus Hybrid Auth; checkout stays untouched
Many connector cartridges with storefront UISFRA, or hybrid with those flows left on SFRAUI parts must be rebuilt in React

Key takeaways

  • SFRA keeps everything in one process on the B2C Commerce app server; PWA Kit moves the storefront onto Managed Runtime and reaches commerce data over SCAPI and SLAS.
  • In 2026 the headless choice is PWA Kit or Storefront Next. Salesforce recommends Storefront Next for new storefronts; PWA Kit is still documented, but confirm v3's support horizon.
  • Hybrid is documented: eCDN rules split paths, app/routes.jsx filtering stops soft navigation into SFRA, and Hybrid Auth keeps dwsid and the SLAS token in sync.
  • The headless SEO risk is the server render's content and the URL change, not JavaScript crawling as such.
  • Page Designer, Einstein and connector cartridges all work headless, but each needs rebuild work. Estimate it before choosing.

For an architecture review of your storefront options or a phased headless plan, see the SFCC consulting services or get in touch.

Further reading