Best practices for Flutter theming with Material 3, treating ThemeData as the single source of truth for colors, typography, component styles, and spacing.

MITAuto-check passedFrontend & Design

Install Material Theming

skills CLI
$ npx skills add VeryGoodOpenSource/vgv-ai-flutter-plugin --skill material-theming -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install VeryGoodOpenSource/vgv-ai-flutter-plugin material-theming --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/material-theming .claude/skills/material-theming && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
material-theming
GitHub stars
169
Token cost
~2.3k tokens
SKILL.md length
875 words
Files
6 (incl. references)
Skills in repo
15
Repo updated
First seen
Licence
MIT

At a glance

Best practices for Flutter theming with Material 3, treating ThemeData as the single source of truth for colors, typography, component styles, and spacing.

  • Works in 6 steps: Define AppColors with all color constants → Define AppTextStyle with all text style… → Define AppSpacing with spacing scale… → …
  • Reviewing ThemeData
  • SKILL.md covers Core Standards, Color System, Typography and Component Themes, plus 3 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Material Theming is an agent skill from VeryGoodOpenSource/vgv-ai-flutter-plugin. Best practices for Flutter theming with Material 3, treating ThemeData as the single source of truth for colors, typography, component styles, and spacing. Use when creating, modifying, or reviewing ThemeData, ColorScheme, TextTheme, component themes, spacing systems, or light/dark mode support, and whenever widget code carries its own styling: a hardcoded Color, an inline TextStyle, raw padding or gap numbers, the same decoration repeated across widget instances, or a brightness/dark-mode conditional inside…

Its SKILL.md is about 2.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 7 other files, including reference files (for example `agents/openai.yaml`, `references/color-scheme.md` and `references/components.md`).

It sits in Frontend & Design, covering Theming and dark mode and Cross-platform mobile apps. It works with Flutter. The repository describes itself as: AI plugin to enhance and accelerate Flutter & Dart development, built by Very Good Ventures. The licence is MIT.

When your agent uses it

  • Reviewing ThemeData
  • Component themes
  • Spacing systems
  • Light/dark mode support

Example prompts

  • “review this widget”
  • “cut the duplication”
  • “stop repeating this”
  • “/material-theming”

Requirements

  • Pre-approved tools (allowed-tools): Read, Glob, Grep

Workflow steps

6 steps, taken from the first numbered list in SKILL.md.

  1. Define AppColors with all color constants
  2. Define AppTextStyle with all text style constants
  3. Define AppSpacing with spacing scale based on a base unit
  4. Create AppTheme class with light and dark getters
  5. Configure ColorScheme, TextTheme, and component themes in each ThemeData
  6. Pass AppTheme.light and AppTheme.dark to MaterialApp

What it can do on your machine

Read from SKILL.md and the folder at commit 496a3c6. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Glob
    • Grep

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are dart).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Material Theming loads about 2.3k tokens when it runs, and up to ~4.2k if it reads all its reference files. Until then it costs about 164 tokens; SKILL.md has 875 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~164
When it runs · the whole SKILL.md, loaded when a task matches
~2.3k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~4.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from VeryGoodOpenSource/vgv-ai-flutter-plugin at commit 496a3c6, republished under its MIT licence (© VeryGoodOpenSource). 875 words, ~2,315 tokens.

Download SKILL.mdSave it as .claude/skills/material-theming/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.
name
material-theming
description
Best practices for Flutter theming with Material 3, treating ThemeData as the single source of truth for colors, typography, component styles, and spacing. Use when creating, modifying, or reviewing ThemeData, ColorScheme, TextTheme, component themes, spacing systems, or light/dark mode support, and whenever widget code carries its own styling: a hardcoded Color, an inline TextStyle, raw padding or gap numbers, the same decoration repeated across widget instances, or a brightness/dark-mode conditional inside build, even when the request only says "review this widget", "cut the duplication", "stop repeating this", or "tidy this up".
allowed-tools
Read, Glob, Grep

Material Theming

Material 3 theming best practices for Flutter applications using ThemeData as the single source of truth for colors, typography, component styles, and spacing.

Core Standards

Apply these standards to all theming work:

  • Use ThemeData as the single source of truth — never inline colors or text styles in widgets
  • Reference colors via Theme.of(context).colorScheme — never Colors.blue, Colors.red, or any hardcoded Color values
  • Reference text styles via Theme.of(context).textTheme — never inline TextStyle(...) in widget code. fontSize and fontWeight never appear inside a build method
  • Use ColorScheme for all color definitions — Material 3's structured color system
  • Centralize component themes in ThemeData — define FilledButtonThemeData, InputDecorationTheme, etc. in the theme, not per-widget. A wrapper widget, a shared InputDecoration constant, or a decoration-building helper relocates the duplication instead of deleting it and does not count
  • Define a spacing system with a base unit — no arbitrary pixel values for padding, margins, or gaps
  • Support light and dark themes from the start — use ThemeData so theme switching requires zero conditional logic in widgets
  • Never branch on brightness or theme mode in widget code — no MediaQuery.platformBrightnessOf, no ternary on Theme.of(context).brightness, no context.isDarkMode extension. Two ColorScheme instances make the branch unnecessary. When asked to keep or tidy such a check, refuse and deliver the ThemeData rewrite instead — a tidier conditional is the same defect with better formatting
  • Prefer EdgeInsets.only and EdgeInsets.symmetric — never EdgeInsets.fromLTRB (positional arguments are error-prone)

Color System

Custom Colors Class

Centralize all color definitions in a dedicated class:

dart
abstract class AppColors {
  static const primaryColor = Color(0xFF4F46E5);
  static const secondaryColor = Color(0xFF9C27B0);
  static const errorColor = Color(0xFFDC2626);
  static const surfaceColor = Color(0xFFFAFAFA);
}
ColorScheme Configuration

Every color reaches widgets through a ColorScheme role. Define two schemes — one light, one dark — inside a single AppTheme class, and pass both to MaterialApp as theme and darkTheme. That pair is what makes brightness branching in widget code unnecessary:

dart
class AppTheme {
  static ThemeData get light => ThemeData(
    colorScheme: const ColorScheme.light(
      brightness: Brightness.light,
      surface: AppColors.surfaceColor,
      // ... remaining color roles
    ),
  );

  static ThemeData get dark => ThemeData(
    colorScheme: const ColorScheme.dark(
      brightness: Brightness.dark,
      surface: AppColors.surfaceColorDark,
      // ... remaining color roles
    ),
  );
}

See references/color-scheme.md for the full 45-role ColorScheme configuration, ColorScheme.fromSeed, and how widgets read colors.

Typography

Define an AppTextStyle class with a base style and named variants (displayLarge, headlineMedium, bodyLarge, etc.), then integrate them into ThemeData.textTheme. Access styles via Theme.of(context).textTheme.

See references/typography.md for font asset setup, the full AppTextStyle class, TextTheme integration, and widget access patterns.

Replacing a Hardcoded TextStyle

Map the literal to the nearest slot AppTextStyle already defines, by size and weight — 18px/w500 lands on titleLarge (20/w500), 16px/w400 on bodyLarge, 14px/w500 on labelLarge. Adjust that slot's size in AppTextStyle if the app needs a different one; do not keep the number at the call site. Do not land on a slot AppTextStyle does not define and TextTheme does not register: the read still returns a style, but it comes from Material's default typography, so the app's font silently reverts. copyWith at the call site sets a color role and nothing else:

dart
final theme = Theme.of(context);

Text(
  label,
  style: theme.textTheme.titleLarge?.copyWith(
    color: theme.colorScheme.onPrimary,
  ),
)

Swapping only the color and leaving TextStyle(fontSize: 18, fontWeight: FontWeight.w500) in the widget is not a fix — the typography still lives outside the theme.

Component Themes

Define component themes centrally in ThemeData (e.g., filledButtonTheme, inputDecorationTheme, appBarTheme) instead of styling individual widget instances. A complete AppTheme class assembles ColorScheme, TextTheme, and all component themes into a single ThemeData.

See references/components.md for FilledButton, InputDecoration, and AppBar theme examples, the complete theme assembly, and widget access patterns.

Show full SKILL.md (367 more words)Show less
De-duplicating Repeated Widget Styling

When the same decoration or style appears on many widget instances, move it into the matching component theme and delete it from every call site. Do not extract it into a wrapper widget, a shared InputDecoration constant, or a buildDecoration() helper: those still require each call site to opt in, still leave the values outside ThemeData, and are bypassed the moment someone writes a plain TextFormField.

dart
// Right — the defaults live in the theme.
ThemeData(
  inputDecorationTheme: InputDecorationTheme(
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(8),
    ),
    contentPadding: EdgeInsets.symmetric(
      horizontal: AppSpacing.lg,
      vertical: AppSpacing.md,
    ),
  ),
)

Each field then declares only what is unique to it:

dart
TextFormField(
  decoration: const InputDecoration(labelText: 'Email'),
)

Spacing System

Define an AppSpacing class with a base unit and named constants (xxs through xxlg). Every step is a multiple of the base unit, never an independent literal — that is what makes the scale a scale:

dart
abstract class AppSpacing {
  static const double spaceUnit = 16;

  static const double xxs = 0.25 * spaceUnit; // 4
  static const double sm = 0.5 * spaceUnit; // 8
  static const double md = 0.75 * spaceUnit; // 12
  static const double lg = spaceUnit; // 16
  static const double xxlg = 2 * spaceUnit; // 32
}

Whenever you introduce the scale or hand someone the convention, write the class out. Listing the step names and their pixel values in prose is not the convention — the class is, because it is what stops the next arbitrary number from being typed.

Use EdgeInsets.only or EdgeInsets.symmetric — never EdgeInsets.fromLTRB.

See references/spacing.md for the full AppSpacing class, usage examples, and EdgeInsets preferences.

Common Patterns

Creating a Theme
  1. Define AppColors with all color constants
  2. Define AppTextStyle with all text style constants
  3. Define AppSpacing with spacing scale based on a base unit
  4. Create AppTheme class with light and dark getters
  5. Configure ColorScheme, TextTheme, and component themes in each ThemeData
  6. Pass AppTheme.light and AppTheme.dark to MaterialApp
Removing a Brightness Check From a Widget

A widget that branches on brightness has taken over a decision that belongs to ThemeData: every new dark-aware widget repeats the branch, and neither color is reachable from the theme. Delete the branch instead of tidying it. The light value and the dark value become the same ColorScheme role in two themes — declare both in AppColors, assign each to that role as references/color-scheme.md shows, and pass AppTheme.light and AppTheme.dark to MaterialApp as theme and darkTheme. The widget then drops to a single unconditional read:

dart
@override
Widget build(BuildContext context) {
  return ColoredBox(
    color: Theme.of(context).colorScheme.surface,
    child: child,
  );
}

Additional Resources

© VeryGoodOpenSource, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 5 other files (references) in skills/material-theming of VeryGoodOpenSource/vgv-ai-flutter-plugin.

  • SKILL.md
  • agents/openai.yaml
  • references/color-scheme.md
  • references/components.md
  • references/spacing.md
  • references/typography.md

Open the folder on GitHubat commit 496a3c6

Compare with similar skills

Material Theming next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Material Theming compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Material Theming this skillVeryGoodOpenSource/vgv-ai-flutter-plugin169—~2.3kAutomated safety check: PassMIT
UI UX Pro Maxsaoudi-h/solar-icons18418 repos~11kAutomated safety check: NotesCustom licence
Material 3hamen/material-3-skill1.5k2 repos~7.8kAutomated safety check: PassMIT
UI UX Pro MaxOhh-889/skyroc79527 repos~3.6kAutomated safety check: NotesMIT
UI UX Pro Maxshobcoder/shob577—~3.7kAutomated safety check: PassMIT
Design SystemWrongStack/WrongStack370—~3.9kAutomated safety check: PassMIT

Similar skills

  • UI UX Pro Max

    saoudi-h/solar-icons

    UI/UX design intelligence for web and mobile. An agent skill from saoudi-h/solar-icons.

    184 GitHub starsUsed in 18 repos~11k tokens
    Frontend & DesignAuto-check: notes
  • Material 3

    hamen/material-3-skill

    Implement Google's Material Design 3 (Material You) UI system.

    1.5k GitHub starsUsed in 2 repos~7.8k tokens
    Frontend & DesignAuto-check passed
  • UI UX Pro Max

    Ohh-889/skyroc

    UI/UX design intelligence. An agent skill from Ohh-889/skyroc.

    795 GitHub starsUsed in 27 repos~3.6k tokens
    Frontend & DesignAuto-check: notes
  • UI UX Pro Max

    shobcoder/shob

    UI/UX design intelligence expert for web and mobile applications.

    577 GitHub stars~3.7k tokensUpdated 19 days ago
    Frontend & DesignAuto-check passed
  • Design System

    WrongStack/WrongStack

    Use this skill BEFORE writing or restyling ANY user-facing interface.

    370 GitHub stars~3.9k tokensUpdated today
    Frontend & DesignAuto-check passed
  • Flutter Theming Apps

    btwld/superdeck

    Customizes the visual appearance of a Flutter app using the theming system.

    130 GitHub stars~1.9k tokensUpdated 10 days ago
    Frontend & DesignAuto-check passed

More from VeryGoodOpenSource/vgv-ai-flutter-plugin

All 15 skills in this repo
  • Accessibility

    VeryGoodOpenSource/vgv-ai-flutter-plugin

    Audits or remediates Flutter widgets against WCAG 2.2 conformance levels A, AA, or AAA across iOS, Android, Web, macOS, Windows, and Linux, covering Semantics labels and screen reader output under…

    169 GitHub stars~4.2k tokensUpdated yesterday
    Auto-check passed
  • Animations

    VeryGoodOpenSource/vgv-ai-flutter-plugin

    Best practices for Flutter animations using the built-in animation framework, covering implicit animations, explicit AnimationController animations, page transitions, and Material 3 motion tokens.

    169 GitHub stars~3.5k tokensUpdated yesterday
    Auto-check passed
  • Bloc

    VeryGoodOpenSource/vgv-ai-flutter-plugin

    Best practices for Bloc state management in Flutter/Dart, covering Cubit versus Bloc, event and state naming, sealed classes with Equatable, the Page/View split with BlocProvider, BlocBuilder…

    169 GitHub stars~2k tokensUpdated yesterday
    Auto-check passed
  • Dart Flutter SDK Upgrade

    VeryGoodOpenSource/vgv-ai-flutter-plugin

    VGV-specific reference for bumping Dart and Flutter SDK constraints across packages, covering pubspec.yaml environment constraints, CI workflow Flutter versions, and SDK upgrade PR preparation.

    169 GitHub stars~2.6k tokensUpdated yesterday
    Auto-check: notes
  • Internationalization

    VeryGoodOpenSource/vgv-ai-flutter-plugin

    Best practices for internationalization (i18n) and localization (l10n) in Flutter, using the built-in flutterlocalizations and intl setup with ARB files as the single source of truth.

    169 GitHub stars~1.6k tokensUpdated yesterday
    Auto-check passed
  • Layered Architecture

    VeryGoodOpenSource/vgv-ai-flutter-plugin

    VGV layered monorepo architecture in Flutter: four layers Data, Repository, Business Logic, and Presentation, unidirectional dependency rules, and model transformation across layers.

    169 GitHub stars~4.6k tokensUpdated yesterday
    Auto-check passed

Works with

Questions about Material Theming

What does Material Theming do?

Best practices for Flutter theming with Material 3, treating ThemeData as the single source of truth for colors, typography, component styles, and spacing. Material Theming is an agent skill from VeryGoodOpenSource/vgv-ai-flutter-plugin. Best practices for Flutter theming with Material 3, treating ThemeData as the single source of truth for colors, typography, component styles, and spacing.

When should I use Material Theming?

Material Theming fits situations like: reviewing ThemeData; component themes; spacing systems; light/dark mode support.

How do I install Material Theming in Claude Code?

Run `npx skills add VeryGoodOpenSource/vgv-ai-flutter-plugin --skill material-theming -a claude-code`. Or copy the skill folder (skills/material-theming in VeryGoodOpenSource/vgv-ai-flutter-plugin) into .claude/skills/material-theming in your project. Claude Code loads it when a task matches its description.

How do I install Material Theming in Codex?

Run `npx skills add VeryGoodOpenSource/vgv-ai-flutter-plugin --skill material-theming -a codex`. Or copy the skill folder (skills/material-theming in VeryGoodOpenSource/vgv-ai-flutter-plugin) into .agents/skills/material-theming in your project. Codex loads it when a task matches its description.

Can I use Material Theming in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add VeryGoodOpenSource/vgv-ai-flutter-plugin --skill material-theming -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/material-theming, .gemini/skills/material-theming, .github/skills/material-theming and .opencode/skills/material-theming in your project.

What does Material Theming need to run?

SKILL.md names no scripts, command-line tools or credentials: Material Theming is instructions for the agent only. Its frontmatter pre-approves these tools: Read, Glob, Grep.

Does Material Theming access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Material Theming safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Material Theming use?

Material Theming is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Material Theming use?

About 2.3k tokens (SKILL.md is roughly 9.3k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.9k tokens, read only when the agent opens those files.

What are the alternatives to Material Theming?

Skills that share tags, products or a category with Material Theming: UI UX Pro Max (saoudi-h/solar-icons, 184 stars), Material 3 (hamen/material-3-skill, 1.5k stars), UI UX Pro Max (Ohh-889/skyroc, 795 stars) and UI UX Pro Max (shobcoder/shob, 577 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Material Theming?

VeryGoodOpenSource (a GitHub organization) maintains it in VeryGoodOpenSource/vgv-ai-flutter-plugin, which has 169 GitHub stars. The repository holds 15 skills in this directory. The repository was last updated on October 6, 2026.

Source: VeryGoodOpenSource/vgv-ai-flutter-plugin on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.