Skip to content

Releasing Changes

Design system changes are broad and can affect many product surfaces at once. To validate design and interaction changes, it helps to have some structure around releases.

0 of 19 verified

For high-risk or broadly impactful changes, wrap the new behavior behind a LaunchDarkly feature flag. Stylus components must not import the LaunchDarkly SDK directly — design-system components are pure presentation and should not know about any feature-flag vendor. Instead, expose a component-owned React context (and/or an override prop) and let the consuming app resolve the flag value at the application root.

Pattern: stylus-owned context, app-resolved value

Section titled “Pattern: stylus-owned context, app-resolved value”

The reference implementation is <Logo> and BrandRefreshContext:

packages/stylus-ui/MyComponent/MyContext.tsx
import { createContext } from "react";
export const MyContext = createContext<boolean>(false);
export const MyProvider = MyContext.Provider;
packages/stylus-ui/MyComponent/MyComponent.tsx
import { useContext } from "react";
import { MyContext } from "./MyContext";
interface MyComponentProps {
/** Override the context value for this instance. Primarily for tests and stories. */
myFlag?: boolean;
}
export const MyComponent = ({ myFlag: override }: MyComponentProps) => {
const fromContext = useContext(MyContext);
const enabled = override ?? fromContext;
return enabled ? <NewLayout /> : <CurrentLayout />;
};

The consuming app mounts the provider once at its root, reading from whatever flag source it owns (LaunchDarkly via useLDFlag, a Redux selector, etc.):

// app root layout
import { MyProvider } from "stylus-ui/MyComponent";
import { useLDFlag } from "@/_lib/launchdarkly/clientSDKUtils";
export const RootProviders = ({ children }) => {
const enabled = useLDFlag("stylus_my_component_v2");
return <MyProvider value={enabled}>{children}</MyProvider>;
};
  • No vendor coupling in stylus. stylus-ui works the same whether the consuming app uses LaunchDarkly, Flagsmith, Redux, or hard-coded values.
  • No silent-empty-context bugs. The context has a typed default (usually false). Components rendered outside a provider get a deterministic fallback, not a vendor-specific quirk.
  • Call sites stay stable across the rollout lifecycle. During rollout, the provider value reads from the flag. At launch, it flips to a constant. At cleanup, the provider is deleted and the default changes. Application call sites (<MyComponent />) never need to change.
  • Tests don’t import LD. Tests can wrap <MyProvider value={true}> directly, or use the override prop.
  1. Replace the provider’s value={useLDFlag(...)} with value={true} (or delete the provider entirely once the default is flipped).
  2. In stylus-ui, remove the context, the override prop, and the old code path.
  3. Retire the LD flag.

For the canonical multi-PR rollout sequence, see the AIA-21 spec under specs/021-stylus-ui-ld-cleanup/.