In a design system, what are the trade-offs between applying a theme at build time and switching it at runtime?
answer
- when are the values decided
- one output per theme
- switch without a reload
- indirection and first-paint cost
- generate sets, swap at the root
basics
~20 sBuild-time theming bakes each theme's values into its own output: simple and fast, but switching means loading another output. Runtime theming resolves values while the app runs, allowing instant switching and nested scopes, at the cost of indirection and startup work.
solid answer
~40 sWith **build-time** theming, a token build step emits a separate set of resolved values for each theme and the app ships or loads the one it needs. It is simple, needs no lookup while running and suits themes fixed for a session, but each theme multiplies the outputs and switching means reloading or fetching another output. With **runtime** theming, components reference named semantic values resolved while the app runs, so the app can switch instantly, scope a sub-theme to one region and follow a user's choice; the price is an indirection layer, the need to know the theme before first paint, and more combinations to test. Most mature systems are hybrid: generate each theme's value set at build time, then swap which set is active at runtime, at the root or at a scope.
go deeper
Recall the two moments: values baked when the app is built, or resolved while it runs, and which one allows switching without a reload.
Explain the costs on each side: output multiplication and reloads versus indirection, first-paint timing and a bigger test matrix, and why the hybrid is common.
Show how you would pick per theme: release-driven themes baked in, user-driven ones at runtime, and what the change costs in pipeline and tests.
Weigh a runtime theming layer as a long-term platform commitment: it enables data-delivered themes and scoping, but every future theme multiplies the support matrix.
## Two moments a theme can be applied A **theme** is a set of values (colors, radii, typography choices, sometimes spacing) that a design system's components draw on through **semantic tokens**, names such as surface, text-primary or accent that describe a role rather than a raw value. The question is *when* each semantic name is turned into a concrete value: once, when the app is built, or continuously, while it runs. ## Build-time theming A token build step reads the token source and writes out fully resolved values for one theme, or one output per theme. - **Strengths:** no lookup while running, the simplest mental model, the smallest runtime footprint, and values that can be inlined or optimised by the platform's own tooling. - **Weaknesses:** switching themes means loading a different output or restarting; every added theme multiplies the outputs to build, ship and test; a region of a screen cannot easily wear a different theme unless the build also emits scoped outputs. - **Fits:** a theme fixed per release or per deployment, such as a seasonal event skin that every player sees for the duration of the event. ## Runtime theming Components keep referring to semantic names, and the running app resolves them against whichever theme is active. - **Strengths:** instant switching with no reload, **scoped sub-themes** for one region, user-chosen themes, and new themes delivered as data rather than as a new build. - **Weaknesses:** an indirection layer on every themed value, the obligation to know the theme **before the first frame** or risk a wrong-theme flash, and a larger test matrix because any component can meet any theme in any scope. - **Fits:** a choice the user makes, such as a player picking their faction's theme in a game's companion app. ## Side by side | Concern | Build-time | Runtime | |---|---|---| | Switching during a session | reload or load another output | instant | | Nested or scoped themes | only with extra scoped outputs | natural | | Runtime cost | none for resolution | an indirection per value | | Wrong-theme flash risk | only if the wrong output loads | real, unless resolved before first paint | | Adding a theme | a new output to build and ship | a new value set, possibly as data | | Test surface | one theme per output | every theme in every scope | ## The hybrid most systems land on 1. Author tokens once, with a semantic tier and one value set per theme. 2. At build time, generate each theme's value set in each platform's format. 3. At runtime, mark which set is active at the root of the app, and optionally at a scope such as a panel. 4. Components never know which theme is active; they only reference semantic names. This keeps the build doing the heavy lifting (validation, aliasing, per-platform conversion) while the running app only chooses between prepared sets. ## Choosing, in a game companion app A multiplayer game's companion app might carry both kinds. The seasonal event skin changes with each release, so baking it in at build time is cheap and safe. The player's faction theme is a personal choice that can change mid-session and that one region, such as an opposing faction's match summary, may need to override, so it belongs at runtime. Asking which themes are chosen by *people* and which by *releases* usually answers the question. ## Native mobile Native platforms face the same split. Resources compiled into the app per configuration are the build-time form; a theme object or value set chosen and swapped while the app runs is the runtime form. The trade-offs, reload versus instant switch and simplicity versus flexibility, are the same on every platform.
- Why does runtime theming make a wrong-theme flash possible, and does build-time theming avoid it?Runtime theming needs the user's choice before the first frame; if that choice is read late, from asynchronous storage or a profile request, the default theme paints first. Build-time theming avoids it only if the right output is chosen before loading, which moves the same problem to whatever picks the output.
- When is pure build-time theming the right call?When nobody switches themes during a session and no region needs a different theme: one theme per release or per deployment. Then runtime indirection buys nothing, and the simpler model, smaller footprint and smaller test surface win. Adding a user choice later is the usual trigger to move to the hybrid.
saying these in an interview costs you the question
- Runtime theming means rebuilding the app once per theme.
- Build-time theming lets users switch themes instantly without a reload.
- Runtime theming has no cost, so build-time theming is never justified.
- Components should branch on the theme's name to choose values.
- Runtime theming removes the need to test each theme.