Skip to main content
Most Neo projects create custom themes to match their brand identity. Build on Neo’s defaults with NeoTheme.light() / NeoTheme.dark() and override only the tokens you need via copyWith.

Extending Neo’s Default Themes

Neo ships carefully designed light and dark themes through NeoTheme.light() and NeoTheme.dark(). Prefer copying those and overriding specific tokens instead of constructing every field from scratch. Benefits of Extending Default Themes:
  • Automatically inherit Neo’s color combinations
  • Maintain consistency with Neo’s design system
  • Reduce maintenance burden by leveraging tested color relationships
  • Focus only on your brand customizations rather than rebuilding everything
What You Typically Customize:
  • Brand colors (brand, fgOnBrand)
  • Optional spacing, radius, or typography adjustments
  • Nullable button/checkbox overrides on NeoColors when you need global widget tinting
What Neo Handles for You:
  • Semantic colors (success, warning, danger)
  • Ink ladders, fills, borders, and surface colors
  • Cross-platform visual consistency

Project Structure

The standard Neo theming structure organizes your custom colors and themes:

Creating Your Themes

Start from Neo’s factories and override only your brand colors:

Using Your Custom Themes

Apply your custom themes in your app’s main file:

Mixing Neo and Custom Colors

You can combine your custom colors with Neo’s built-in colors:

Best Practices

Theme Architecture

  • Start from NeoTheme.light() or NeoTheme.dark() instead of building a theme from scratch.
  • Keep brand colors in their own palette file.
  • Create both a light theme and a dark theme.

Customization Approach

  • Override brand colors first. Leave Neo’s other tokens in place until you have a reason to change them.
  • Use copyWith on NeoTheme and NeoColors so the relationships between tokens stay intact.
Last modified on September 30, 2026