How to use
- Copy the installation command and review the source package before installing it in your own agent environment.
- Check the source document for required tools, credentials and supported hosts.
- Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/thesimpleapp/flutter-app-skills --skill flutter-custom-design-systemBefore you start
- Installation does not include a model subscription, API allowance or permission to access your files.
- Repository stars and installation counts describe activity, not an independent quality or security test.
Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.
Flutter custom design system
Stock Material/Cupertino skills are the wrong default here. If this repo already named colors, type, radius, motion, or a pressable, use those names and values. Do not restyle the app toward FilledButton / NavigationBar / ColorScheme.fromSeed unless the user asked to throw the system away.
Companion skill: flutter-native-ui — only for apps that actually want Material 3 or Cupertino chrome.
References
references/
tokens.md ThemeExtension mount, context accessor, 1:1 rule
pressable.md Scale/sink press, NoSplash, focus ring, semanticsDetect the system first
Before writing a widget, search the repo for:
ThemeExtension<extension <Name> on BuildContextthat returns colors/tokens- files named
*tokens*,*semantics*,*theme*,WIDGETS.md,DESIGN-SYSTEM.md - a widget named
*Pressable NoSplash.splashFactory/splashFactory: NoSplash
Then open a nearby production screen and copy its accessor (context.pt, St6Theme.of(context), context.colors, …). Product code must use that accessor, not a new one.
No system yet, and the user wants one: install the pattern in references/tokens.md and references/pressable.md. One token module, one extension, one pressable. Do not add a third-party UI kit.
Hard rules
Tokens
- Values live in one source (Dart token file, generated from CSS/JSON, or a signed-off
tokens.dart). Widgets never contain raw hex, magic radii, or ad-hoc durations. - Runtime mount is a
ThemeExtension<T>onThemeData.extensions, plus a single context accessor. Do not import aFooColorsclass into random widgets beside the extension. - 1:1 with the system file. If the handoff says
#C9A24B, the token is#C9A24B. Do not “improve” contrast, invent a light theme, or add roles the system does not name. - Missing role: add it to the token source and the extension together, or ask. Never
#hexin the widget as a shortcut. - Dark mode only exists if the system shipped it. Do not invent a dark palette.
Chrome
- A stranger should not be able to tell the app is default Flutter Material. No ink ripples, no M3 primary-container pills, no stock
NavigationBarindicator, unless the system specifies them. - Every tap goes through the house
Pressable(create it if the repo has none). Press = scale and/or sink.splashFactory: NoSplash.splashFactoryand transparent overlays on the theme and on the pressable. - Do not wrap branded controls in
FilledButton/ElevatedButton/InkWell“to get accessibility for free” and then fight the splash. Put semantics on the pressable. - Use Material behavior (focus, media query, text scaler,
Shortcuts) without Material look.
Type and space
- Type roles come from the system (or the extension’s text styles), not
TextTheme.of(context).titleLargeunless the system mapped ontoTextTheme. - Spacing, radius, and motion come from token numbers (
space200,radiusControl,durationPress). NoEdgeInsets.all(13)and noDuration(milliseconds: 180)invented at the call site.
Keys and debug
- Interactive controls:
const ValueKey<String>('kebab-name')so tests canfind.byKey. - God-mode, galleries, prefills, jump chips:
kDebugModeonly, and they still go through the real auth/session path. No release backdoors.
Do not
- Add
google_fontsif the system already vendors faces. If goldens matter, load those faces withFontLoader— Roboto goldens are not the product. - Add
flutter_screenutil, GetX, or a second design package. - Mix stock M3 components onto a branded surface “just this once.”
Build a screen
- Read the token file, the extension, the pressable, and one existing screen.
- Scaffold with the project’s shell (custom app bar / tab bar), not a fresh
AppBar+NavigationBar. - Color, type, space, radius, motion: extension/tokens only.
- Taps: house pressable. Icons: the system’s icon set, not
Icons.favoriteunless that is the system. - Safe area and keyboard:
SafeAreaon content,MediaQuery.sizeOf/viewInsetsOf/textScalerOf. Window width breakpoints if the system defines them; otherwise keep the existing shell’s rule. - Verify with the project’s analyzer and a running frame.
When to refuse Material defaults
Refuse these on a branded surface unless the system’s widget inventory lists them:
FilledButton, NavigationBar, NavigationRail, NavigationDrawer, SnackBar (if the system has a toast), FloatingActionButton, Chip, Card, Material with elevation tint, InkWell with default splash.
OS-native affordances that are not chrome may still use .adaptive() (Switch.adaptive, Checkbox.adaptive) when the system does not specify a replacement.
Verify
grepthe files you touched forColor(0x/Color.from/#. Hits belong in the token file, not the widget.- Every new tap target goes through the house pressable.
- Analyzer clean. Hot reload. Confirm the running frame against a nearby branded screen, not against Material 3 gallery memory.
- Widget tests use
find.byKey, not visible copy, when a key exists.



