---
schema_version: "1"
id: ffe693290781727b0f471230b4935ee6a18c56e1e08164bce56364b0b7a39459
title: Architecture Overview
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/commerce-cloud/b2c-commerce/guides/commerce-apps/architecture.md
canonical_url: https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/architecture.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: f16a78a58f3db5d2fa100c11074dbd35d936953bfa7b7c598c29e48d3dccbf38
products:
  - Composable Storefront
  - Salesforce APIs
---
# Architecture Overview

Understand the Commerce Apps framework, extension points, and packaging structure.

## The Commerce Apps Framework

Commerce Apps are the "feature packaging" layer that merchants use to apply native or third-party customizations to their site and storefront. Commerce Apps support both backend and frontend (Storefront Next) code. Public apps use the centralized [Commerce App Registry](https://github.com/SalesforceCommerceCloud/commerce-apps) hosted on GitHub; private apps install from WebDAV without a registry listing. Both paths use the same install framework to bridge third-party service logic and the storefront through metadata, code, and UI orchestration.

> **Note:** The examples in this guide focus on the tax domain, but the same architectural patterns and automation workflows apply identically to all other merchant service categories (for example, address verification, ratings & reviews, and shipping).

## Architecture Hierarchy: Domain, Extension, UI Target, Component

Commerce Apps are organized in a hierarchy:

**Domains** are the top-level commerce categories: Payments, Tax, Shipping, Order Management System (OMS), Ratings & Reviews, Loyalty, Fraud, and so on. Each domain represents a functional feature area of a commerce application.

**Storefront extensions** are UI features within a domain that merchants can turn on individually. For example, the Shipping domain has separate storefront extensions for Delivery Estimation and Shipping Options & Calculations, so merchants can turn on only the features they need.

**UI targets** are named landing zones on Storefront Next pages where components render. Each extension contains one or more components that can target defined UI targets across different storefront surfaces (PDP, PLP, Cart, Checkout, My Account, and so on). Targets follow a semantic namespace: `{namespace}.{surface}.{domain}.{feature}`.

**Components** are the React elements that render within each UI target. They can come from the platform (as pre-built Storefront Next components) or from an ISV extension (replacing the platform component).

**Example:** The Ratings & Reviews domain includes extensions for Star Rating, Review Summary, Reviews List, Q&A, and Review Purchase. The Star Rating extension has UI targets on PDP (`sfcc.pdp.reviews.rating`), Product Card (shared), and Quick Add. Each target renders a component that displays the aggregate star rating for a product.

## The Three Architectures for Commerce Apps

There are three distinct architectures for building a Commerce App. Each architecture determines what goes into your Commerce App Package (CAP). The right one depends on your domain, your needs, and what platform capabilities you want to use.

### UI-Only

Your Commerce App delivers only Storefront Next extensions — React components that replace or extend platform UI targets. There is no backend cartridge or IMPEX in your CAP. This architecture is appropriate when the platform already provides the backend APIs you need, and you only want to customize the shopper-facing experience.

Your CAP includes the `storefront-next/` and `app-configuration/` directories, but no `cartridges/` or `impex/` directories.

### Backend-Only

Your Commerce App delivers only backend cartridges and IMPEX configuration — no Storefront Next extensions. This architecture is appropriate when the platform already provides the frontend components and a formal backend interface contract, and you supply only the backend logic that fulfills that contract.

You implement platform-defined extension point hooks (for example, `sfcc.app.tax.calculate` or `sfcc.app.oms.order.retrieve`). The platform provides both the frontend components (where the domain has storefront UI) and the extension point interface — you implement only the script API endpoints. This is the most turnkey approach, but it requires the platform to have defined extension points for your domain. Tax and OMS currently have live extension points.

Your CAP includes the `cartridges/`, `impex/`, and `app-configuration/` directories but no `storefront-next/` directory.

### Fullstack

Your Commerce App delivers both Storefront Next extensions and backend cartridges. You own the full stack for your feature: frontend components, backend SCAPI or service integrations, and all data handling. This architecture gives you full creative and functional control over both the UX and the data layer.

Your CAP includes the `storefront-next/`, `cartridges/`, `impex/`, and `app-configuration/` directories.

There are two sub-types of fullstack apps:

#### Extension Points

You replace the platform's default UI components with your own Storefront Next extensions, and your backend implements platform-defined extension point hooks. The platform defines the backend interface contract — you supply the hook implementations that fulfill it. This sub-type is available for domains where the platform has defined formal extension points.

#### Custom SCAPI

You replace the platform's default UI components with your own Storefront Next extensions, and your backend is a custom SCAPI that supplies data to those components. No platform-defined extension points are required — you define your own API contract. This sub-type is available for any domain, even if the platform hasn't defined formal extension points yet.

## Commerce App Package (CAP) Structure

A CAP is a standardized `.zip` file with the following directory layout:

```
commerce-{app-name}-app-v{n.n.n}/
├── commerce-app.json                  # App metadata (required)
├── README.md                          # Documentation (required)
├── app-configuration/
│   ├── tasksList.json                 # Post-install merchant setup steps (required)
│   ├── adminComponents.json           # BM admin UI components (optional)
│   └── translations/                  # Localized BM-rendered strings (optional)
│       ├── en-US.json                 #   required when translations/ exists
│       ├── de.json
│       └── ja.json
├── icons/                             # App icon (required)
│   └── {isv-name}.png                 # CI extracts to commerce-apps-manifest/icons/
├── cartridges/                        # Backend-only or Fullstack apps
│   ├── site_cartridges/
│   │   └── int_cartridge_name/
│   │       ├── package.json
│   │       ├── cartridge/scripts/
│   │       │   ├── hooks.json         # Registers hooks with the platform
│   │       │   ├── hooks/             # Hook implementations
│   │       │   ├── helpers/           # Business logic
│   │       │   └── services/          # Service framework wrappers
│   │       └── test/                  # Unit tests
│   └── bm_cartridges/                 # Business Manager extensions (optional)
│       └── bm_cartridge_name/
│           └── cartridge/
│               ├── controllers/
│               └── scripts/
├── storefront-next/                   # UI-only or Fullstack apps
│   └── src/extensions/{app-name}/
│       ├── target-config.json         # Maps components → UI targets
│       ├── index.ts                   # Barrel exports
│       ├── components/                # React components
│       └── locales/                   # i18n translation files
│           ├── en-US/translations.json
│           ├── en-GB/translations.json
│           └── it-IT/translations.json
├── impex/                             # Backend-only or Fullstack apps
│   ├── install/
│   │   ├── jobs.xml
│   │   ├── services.xml
│   │   ├── meta/
│   │   │   ├── system-objecttype-extensions.xml
│   │   │   └── custom-objecttype-definitions.xml
│   │   └── sites/SITEID/
│   │       └── preferences.xml
│   └── uninstall/                     # Cleanup for uninstalled apps
│       └── services.xml
```

## Extension Points and Domain Isolation

Commerce Apps introduce domain-specific extension points that replace the legacy shared hooks (both business defined hooks like `dw.order.calculate` and general before/after SCAPI hooks). This eliminates code conflicts where multiple integrations (for example, two tax providers) compete for the same hook.

| Domain   | Commerce Action     | Legacy Hook                                          | Commerce App Extension Point  |
| :------- | :------------------ | :--------------------------------------------------- | :---------------------------- |
| Tax      | Any basket mutation | `dw.order.calculateTax`                              | `sfcc.app.tax.calculate`      |
| Tax      | Order creation      | `dw.order.createOrderNo`                             | `sfcc.app.tax.commit`         |
| Tax      | Payment/order fails | N/A                                                  | `sfcc.app.tax.cancel`         |
| OMS      | Retrieve one order  | N/A                                                  | `sfcc.app.oms.order.retrieve` |
| OMS      | List customer orders | N/A                                                 | `sfcc.app.oms.order.list`     |
| OMS      | Cancel or return     | N/A                                                  | `sfcc.app.oms.order.cancel` or `sfcc.app.oms.order.return` |
| Shipping | Calculate rates     | `dw.order.calculateShipping`                         | `sfcc.app.shipping.calculate` |
| Fraud    | Pre-auth check      | `dw.ocapi.shop.basket.payment_instrument.beforePOST` | `sfcc.app.fraud.preAuth`      |
| Fraud    | Post-auth check     | `dw.ocapi.shop.basket.payment_instrument.afterPOST`  | `sfcc.app.fraud.postAuth`     |

> **Note:** Tax and OMS extension points are live. See [Supported Domains](/docs/commerce/b2c-commerce/guide/supported-domains.md) for the full domain timeline, and [Connect a Third-Party OMS](/docs/commerce/b2c-commerce/guide/connect-third-party-oms.md) for the OMS contracts.

## UI Targets Framework

The UI Targets framework is how Commerce Apps deliver frontend components to the storefront. It is a build-time mechanism, not a runtime injection.

**How it works:** The core Storefront Next application defines explicit placeholders using `<UITarget targetId="..." />` React components. These contain no business logic and serve only as injection points. During the build process, a Vite plugin replaces UITarget entries with the actual React components specified in the extension's `target-config.json`.

**Naming convention:** Platform-defined targets use the `sfcc` namespace: `sfcc.{surface}.{domain}.{feature}`. For example, `sfcc.pdp.reviews.rating` identifies the star rating component location on the product detail page.

**Custom namespaces:** SI partners and customers can create their own UI targets with their own namespace prefix (not `sfcc`). This makes the target's framework extensible beyond platform-defined locations.

**Installation mechanism:** When storefront PR creation is requested, the install job processes eligible Storefront Next or cartridge content from the CAP and attempts to create a pull request against the merchant's Storefront Next repository. The PR includes the extension code and target configuration. The branch is named `commerce-app-install/{app-name}/{version}/{site-id}` and the PR title follows the pattern `[Commerce App] Add {app-name} {version} storefront UI`. When PR creation succeeds, a "Merge Storefront PR" task is prepended to the merchant's configuration task list. Components become part of the merchant's build after the PR is merged.

**Manual integration:** If the merchant prefers not to use the automated pull request flow (for example, when installing from Business Manager without GitHub integration configured), they can use `b2c cap pull` to download the installed app package. The `storefront-next/` extensions and `cartridges/` can then be reviewed and integrated into the merchant's storefront and cartridge projects through their standard source control and deployment processes. See [b2c cap pull](/docs/commerce/b2c-commerce/guide/development-environment.md#b2c-cap-pull) for details.

## Installation and State Machine

Commerce App installation is tracked at the site level but the app's artifacts are deployed at the instance level. Cartridges, service definitions, custom object types, and other instance-scoped resources are shared across all sites on the instance. However, each site has its own installation record (`CommerceFeatureState`), its own cartridge path entry, and its own configuration state. This means a merchant installs an app per site, but the underlying code and instance resources are only deployed once and shared.

### Happy Path

The standard lifecycle from installation through activation:

`INSTALLING` → `INSTALLED` → `NOT_CONFIGURED` → `CONFIGURING` → `CONFIGURED`

- **INSTALLING:** The platform is processing the CAP. It unpacks the archive, deploys cartridges to the active code version, executes IMPEX data imports, and optionally attempts a storefront pull request when requested.
- **INSTALLED:** Code is deployed and metadata is imported, but the app isn't yet active. The merchant completes the configuration tasks.
- **NOT_CONFIGURED:** The app is installed but configuration hasn't started yet. To begin, the merchant opens the setup wizard.
- **CONFIGURING:** The merchant has started but not yet finished the setup wizard (defined by `tasksList.json`). Tasks can include verifying API credentials, setting site preferences, or running a test transaction.
- **CONFIGURED:** All configuration tasks are complete. The platform automatically transitions to this state when the last task is marked complete. The app is now active and the app extension point hooks begin executing.

### Error Paths

- `INSTALLING` → `INSTALL_FAILED` — The installation job encountered an error. Check system job logs for details.
- `CONFIGURING` → `CONFIGURATION_FAILED` — Configuration encountered an error during the setup process.

### Uninstall Flow

Any post-install state (`INSTALLED`, `NOT_CONFIGURED`, `CONFIGURING`, or `CONFIGURED`) can transition to `UNINSTALLING`:

`{any post-install state}` → `UNINSTALLING` → `UNINSTALLED`

- **UNINSTALLING:** The platform is removing the app. This includes removing cartridges from the site's cartridge path, and — if this is the last site using the app — deleting cartridge files and executing uninstall IMPEX.
- **UNINSTALLED:** The app has been successfully removed from the site.
- **UNINSTALL_FAILED:** The uninstallation job encountered an error (`UNINSTALLING` → `UNINSTALL_FAILED`). Check system job logs for details.

### Per-Site Tracking

State is tracked per-site in the `CommerceFeatureState` system object. Site A can have an app fully configured while Site B is still in progress, even though they share the same code baseline.

## Two Ways to Install

Install Commerce Apps using either method:

**Business Manager (no-code, registry apps):** Navigate to the Cart & Checkout Hub in Business Manager, select a registry Commerce App, and click Install. The platform handles the installation. After installation, you're redirected to a configuration task list.

**CLI (pro-code, private or local CAPs):** Use the [B2C CLI](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/b2c-developer-tooling.md#run-the-b2c-cli) to validate your CAP (`b2c cap validate`), package it (`b2c cap package`), and install it on a target instance (`b2c cap install`). The CLI handles packaging, WebDAV upload, and job execution automatically. See [Development Environment Setup](/docs/commerce/b2c-commerce/guide/development-environment.md) for the full command reference.
