Choose your app's features

Pick the Arc CMS features your app has in src/custom/features.ts. A feature that is off has no menu item, no page, no settings tab and no Cloud Function. Its data stays, and turning it back on brings everything back.

Choose

  1. Open src/custom/features.ts. As shipped, it is empty, which means every feature is on except the installable app:

    export const CUSTOM_FEATURES: FeatureChoice = {};
  2. List what the app does not have in off, and the installable app in on if you want it:

    import type { FeatureChoice } from '../app/core/features/feature-registry';
    
    export const CUSTOM_FEATURES: FeatureChoice = {
        on: ['pwa'],
        off: ['content', 'sms', 'payments'],
    };
  3. Save. A running npm run dev restarts by itself and checks the choice; npm run build checks it first too.

  4. Deploy all the functions once, so the functions of the features you turned off are removed from the project (see Cloud Functions follow the features).

The features

Everything not in this table is core and always on: sign-in with email and Google, users and profiles, the media manager, languages, the feedback button, notifications, the email engine, automations, banners, and the admin and member dashboards.

IdDefaultNeedsWhat goes when it is off
contentOnContent types, entries, authors, static pages (/p/), public content pages and publishing
searchOnSearch settings, the admin search box and its results page, the public /search page and every search function
seoOnDiscoverability settings, the sitemap, RSS feeds, robots.txt, llms.txt and IndexNow
formsOnaudienceSignup forms, their pages and emails
audienceOnContacts, lists, contact tags and fields, app users and the App audience settings
email-marketingOnaudienceBroadcasts, drip campaigns and announcements
smsOnSMS settings, SMS logs, test SMS and phone sign-in
paymentsOnProducts, transactions, payment settings, pricing, checkout, credits, and the member's Payments, Account and Premium pages
dataOnThe Data menu: import and export
contactOnThe Messages inbox, contact forms on published pages and their functions
pwaOffThe installable app: manifest, service worker, install prompt and install stats
analyticsOnGoogle Analytics in the browser, the dashboard's analytics section and Analytics settings, and their functions. To keep it but wait for consent, see Analytics

Each feature has its own page under All features, and Feature ids lists the ids alone.

When the build refuses a choice

npm run dev and npm run build resolve the choice before anything else, so a choice that cannot work never reaches the browser. They stop with a message that starts with src/custom/features.ts: and says what to change:

You wroteThe message
A name that is not a feature, such as off: ['payment']unknown feature "payment" in "off". Features: content, search, seo, ...
The same feature in both listsInstallable app (pwa) is in both "on" and "off". Keep it in one.
A feature off while another one needs it, such as off: ['audience']Signup forms (forms) needs Audience (audience), which is off. Turn off forms as well, or keep audience.
Something other than a list"off" must be a list, like off: ['payments']

A typo stops the build on purpose: it must never leave a feature on that you meant to turn off.

What turning a feature off does

In the browser

At the next build, or straight away with npm run dev:

Cloud Functions follow the features

A feature's functions are exported from their own file in functions/src/features/, such as functions/src/features/payments.ts. A function that needs two features sits in a file named after both, such as functions/src/features/search+content.ts.

Before every functions build and every test run, scripts/arc-features.mjs reads src/custom/features.ts and writes two generated files in functions/src/: the list of features that are on, and the exports of every feature file whose features are all on. functions/src/all.ts re-exports that list, so a feature that is off is not in the build at all. Both files are ignored by git.

At the next deploy of all the functions, the functions that are no longer in the build are deleted from the project:

See Deploy.

scripts/arc-features.mjs loads the TypeScript files directly, which needs Node 22.18 or later.

Data, rules and indexes

They stay as they are. Turn the feature back on, build and deploy, and everything is there again.

Make your own code follow the features

Your codeHow it checks a feature
An admin menu item in src/custom/nav.tsSet feature: 'payments' on the item (Change the admin menu)
Routes in src/custom/routes.tsWrap them: ...whenOn('payments', [ ... ]), from src/app/core/features/feature-routes.ts (Add pages and routes)
A component or serviceisOn('payments'), from src/app/core/features/features.ts
A Cloud Function in functions/src/custom/isFeatureOn('payments'), from functions/src/feature-flags.ts

The test suite always runs with every feature on, whatever src/custom/features.ts says, so an app that turns features off can still run all of it. A test about one particular choice mocks src/custom/features.ts itself, or, for a Cloud Function, functions/src/feature-flags.ts.