← All @molecule/* packages · App templates

@molecule/app-theme

Core interface · theme · App (browser) · v1.0.1 · Apache-2.0

Theme system with dark/light mode

npm install @molecule/app-theme

npm · Source on GitHub

How it works

@molecule/app-theme is the theme core interface on the app (browser) side: the API your app calls, with no vendor inside.

Choose the implementation by bonding one of its 2 providers: @molecule/app-theme-css-variables, @molecule/app-theme-css-variables-liquid-glass.

import { getProvider } from '@molecule/app-theme'

const theme = getProvider() // null until a bond is wired at startup
theme?.toggleMode() // light <-> dark
const unsubscribe = theme?.subscribe((t) => applyBranding(t))

Providers (2): @molecule/app-theme-css-variables, @molecule/app-theme-css-variables-liquid-glass

Works with: @molecule/app-bond

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Theme interface and utilities for molecule.dev.

Framework-agnostic theme contract — a {@link Theme} (colors, spacing, typography, radii, shadows, z-index) plus a {@link ThemeProvider} bond for reading/switching themes, dark/light toggling, and change subscriptions. Bond a provider (e.g. @molecule/app-theme-css-variables, which applies the palette as CSS variables) at startup; {@link lightTheme}/{@link darkTheme} are the base defaults.

Quick Start

import { getProvider } from '@molecule/app-theme'

const theme = getProvider() // null until a bond is wired at startup
theme?.toggleMode() // light <-> dark
const unsubscribe = theme?.subscribe((t) => applyBranding(t))

Type

core

Installation

npm install @molecule/app-theme @molecule/app-bond

API

Interfaces

Theme

Complete theme definition.

interface Theme {
  name: string
  mode: 'light' | 'dark'
  colors: ThemeColors
  breakpoints: ThemeBreakpoints
  spacing: ThemeSpacing
  typography: ThemeTypography
  borderRadius: ThemeBorderRadius
  shadows: ThemeShadows
  transitions: ThemeTransitions
  zIndex: ThemeZIndex
}

ThemeBorderRadius

Border radius scale.

interface ThemeBorderRadius {
  none: string
  sm: string
  md: string
  lg: string
  xl: string
  full: string
}

ThemeBreakpoints

Responsive viewport breakpoints from mobileS (320px) to desktop (2560px).

interface ThemeBreakpoints {
  mobileS: string // 320px
  mobileM: string // 375px
  mobileL: string // 425px
  tablet: string // 768px
  laptop: string // 1024px
  laptopL: string // 1440px
  desktop: string // 2560px
}

ThemeColors

Color palette definition.

interface ThemeColors {
  // Base colors
  background: string
  backgroundSecondary: string
  backgroundTertiary: string
  surface: string
  surfaceSecondary: string
  inputBackground: string

  // Text colors
  text: string
  textSecondary: string
  textTertiary: string
  textInverse: string

  // Brand colors
  primary: string
  primaryLight: string
  primaryDark: string
  secondary: string
  secondaryLight: string
  secondaryDark: string

  // Semantic colors
  success: string
  successLight: string
  warning: string
  warningLight: string
  error: string
  errorLight: string
  info: string
  infoLight: string

  // Border colors
  border: string
  borderSecondary: string
  borderFocus: string

  // Other
  overlay: string
  shadow: string
}

ThemeProvider

Manages theme state including the active theme, mode toggling, and change subscriptions.

interface ThemeProvider {
  /**
   * Returns the currently active theme.
   */
  getTheme(): Theme

  /**
   * Sets the active theme by reference or by name.
   *
   * @param theme - A `Theme` object or a theme name string to activate.
   */
  setTheme(theme: Theme | string): void

  /**
   * Toggles between light and dark mode for the active theme.
   */
  toggleMode(): void

  /**
   * Subscribes to theme changes. The callback fires whenever
   * `setTheme()` or `toggleMode()` is called.
   *
   * @param callback - Invoked with the new theme after each change.
   * @returns An unsubscribe function.
   */
  subscribe(callback: (theme: Theme) => void): () => void

  /**
   * Returns all registered themes. Optional — not all providers
   * support multiple themes.
   */
  getThemes?(): Theme[]
}

ThemeShadows

Box-shadow scale from none to xl for elevation levels.

interface ThemeShadows {
  none: string
  sm: string
  md: string
  lg: string
  xl: string
}

ThemeSpacing

Theme spacing scale mapping size tokens (xs–3xl) to CSS values (e.g. '4px', '16px').

interface ThemeSpacing {
  xs: string // 4px
  sm: string // 8px
  md: string // 16px
  lg: string // 24px
  xl: string // 32px
  xxl: string // 48px
  xxxl: string // 64px
}

ThemeTransitions

CSS transition duration presets (fast, normal, slow).

interface ThemeTransitions {
  fast: string
  normal: string
  slow: string
}

ThemeTypography

Typography scale (font families, sizes, weights, and line heights).

interface ThemeTypography {
  fontFamily: {
    sans: string
    serif: string
    mono: string
  }
  fontSize: {
    xs: string // 12px
    sm: string // 14px
    base: string // 16px
    lg: string // 18px
    xl: string // 20px
    '2xl': string // 24px
    '3xl': string // 30px
    '4xl': string // 36px
    '5xl': string // 48px
  }
  fontWeight: {
    light: number
    normal: number
    medium: number
    semibold: number
    bold: number
  }
  lineHeight: {
    tight: number
    normal: number
    relaxed: number
  }
}

ThemeZIndex

Theme z-index scale for layering UI elements (dropdowns, modals, toasts, etc.).

interface ThemeZIndex {
  hide: number
  base: number
  dropdown: number
  sticky: number
  fixed: number
  modal: number
  popover: number
  tooltip: number
  toast: number
}

Functions

createDarkTheme(overrides)

Creates a dark theme by merging default dark-mode tokens with optional overrides for colors, spacing, typography, etc.

function createDarkTheme(overrides?: Partial<Theme>): Theme
  • overrides — Partial theme tokens to merge over the defaults.

Returns: A complete Theme object with mode: 'dark'.

createLightTheme(overrides)

Creates a light theme by merging default light-mode tokens with optional overrides for colors, spacing, typography, etc.

function createLightTheme(overrides?: Partial<Theme>): Theme
  • overrides — Partial theme tokens to merge over the defaults.

Returns: A complete Theme object with mode: 'light'.

getProvider()

Retrieves the bonded theme provider, or null if none is configured.

function getProvider(): ThemeProvider | null

Returns: The bonded theme provider, or null.

hasProvider()

Checks whether a theme provider is currently bonded.

function hasProvider(): boolean

Returns: true if a theme provider is bonded.

setProvider(provider)

Registers a theme provider as the active singleton.

function setProvider(provider: ThemeProvider): void
  • provider — The theme provider implementation to bond.

Constants

darkColors

Default dark theme colors.

const darkColors: ThemeColors

darkTheme

Default dark theme.

const darkTheme: Theme

defaultBorderRadius

Default border radius.

const defaultBorderRadius: ThemeBorderRadius

defaultBreakpoints

Default responsive breakpoints (320px mobileS → 2560px desktop).

const defaultBreakpoints: ThemeBreakpoints

defaultShadows

Default box-shadow scale (none → xl, rgba-based).

const defaultShadows: ThemeShadows

defaultSpacing

Default spacing scale (4px xs → 64px xxxl).

const defaultSpacing: ThemeSpacing

defaultTransitions

Default CSS transition durations (150ms fast, 250ms normal, 350ms slow).

const defaultTransitions: ThemeTransitions

defaultTypography

Default typography scale (system font stacks, rem-based sizes, weight/line-height presets).

const defaultTypography: ThemeTypography

defaultZIndex

Default z-index scale.

const defaultZIndex: ThemeZIndex

lightColors

Default light theme colors.

const lightColors: ThemeColors

lightTheme

Default light theme.

const lightTheme: Theme

Available Providers

ProviderPackage
CSS Variables@molecule/app-theme-css-variables
Liquid Glass@molecule/app-theme-css-variables-liquid-glass

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-bond ^1.0.1

Runtime Dependencies

  • @molecule/app-bond

  • Recoloring: find the REAL source of truth first. Apps scaffolded from a template ship a per-app stylesheet (e.g. app/src/theme.css) that hardcodes the --color-* variables and loads AFTER the bond — its values win, and editing this package's Theme objects (or the bond's palette) has NO visible effect there. Precedence: per-app theme stylesheet > theme bond > base defaults. Recolor by editing whichever file actually defines the variables; the bond's Theme palette applies only when no per-app stylesheet defines colors.

  • Read theme values through the provider or the CSS variables it emits — never hardcode hex values in components; surfaces and status colors come from the theme so light AND dark both work.

  • {@link getProvider} returns null when nothing is bonded — theme switching is optional; guard rather than throw.