facebook / facebook/astryx

feat(theme): Brand Theming — multi-brand theme creation, distribution, and governance

Open
#918 8 comments 0 reactions 0 assignees View on GitHub
enhancement theming
Dominant language
TypeScript
Stars
13k
Forks
1.1k
Avg merge
1d 15h
Merged PRs (30d)
690

Description

## Summary

XDS should be the universal base layer that any brand can theme on top of. Today we have three built-in themes (`default`, `neutral`, `brutalist`) and one internal brand theme (Meta), but there is no documented path for brand teams to create, maintain, and distribute their own themes.

This issue tracks the full brand theming story — from token overrides to component customization to distribution.

## Motivation

XDS is designed as a single codebase with multiple themes. Different brands (Meta, external partners, OSS consumers) each have distinct visual identities — colors, typography, radius, spacing, motion — but share the same component logic and accessibility guarantees.

Brand teams should be able to own their theme layer without forking the component library.

## What exists today

- **`defineTheme` API** — flat token map + component style overrides + icon registry
- **CSS-based theming** — no StyleX build required for consumers; themes generate `@scope` rules
- **Light/dark tuple support** — `[light, dark]` values auto-convert to `light-dark()`
- **`xds theme build` CLI** — pre-compiles themes to static CSS for production
- **Three built-in themes** — `default`, `neutral`, `brutalist`
- **Theme nesting** — `` supports nested themes with `@scope` boundary isolation

## What's needed

### 1. Brand Theme Creation Guide
- Step-by-step guide for brand teams to create a new theme package
- Token reference: which tokens to override for color, typography, spacing, radius, motion
- Component override patterns: when to use `base`, `variant:value`, and intersection keys
- Icon registry: how to provide brand-specific icons

### 2. Theme Package Scaffold
- CLI command: `xds theme create ` → scaffolds a new theme package
- Generates: `defineTheme` boilerplate, `tsup` config, icon registry stub, `package.json`
- Optional: starter token presets (e.g. "warm", "corporate", "editorial")

### 3. Theme Validation & Linting
- Validate that all overridden tokens exist in the XDS token registry
- Warn on missing critical tokens (e.g. brand ships colors but no typography)
- Contrast ratio checks for color token pairs (accessibility)
- CI integration: theme packages run validation on PR

### 4. Theme Distribution
- How external brands publish their theme as an npm package
- How internal Meta brands register their theme for Storybook/sandbox
- Theme discovery: CLI or registry for finding available themes

### 5. Theme Governance
- Who owns the token contract? (XDS core team)
- How do breaking token changes get communicated to brand teams?
- Versioning strategy: theme packages pin to XDS core version ranges
- Migration guides when tokens are added, renamed, or removed

### 6. Brand Showcase
- Storybook page showing all registered themes side-by-side
- Sandbox theme switcher with brand themes included
- Visual diff tooling: compare brand theme against default baseline

## Open Questions

- Should brand themes live in the XDS monorepo (like `packages/themes/meta`) or in separate repos?
- How do we handle brand-specific components that don't exist in core (e.g. a branded hero section)?
- Should there be a "theme certification" process for quality/accessibility?

## Related

- #792 — CSS cascade ordering for 5-level theming priority
- #646 — Theming + CSS layer challenges (StyleX dependencies)
- #542 — Root-level color-scheme via data attributes
- #760 — Theme font declarations
- #762 — Component theming standards (xdsClassName targeting)
- #802 — Unified typography config + defineTheme API cleanup

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.