Most Flutter UI kits assume you're on MaterialApp. fossui doesn't. Every component reads its own theme first, so the same button, switch, and text field render identically whether your app root is MaterialApp, CupertinoApp, or a bare WidgetsApp. This isn't an anti-Material stance, most fossui apps will still run on MaterialApp. It's about not locking the components to it.
Registering the theme takes one line under each shell:
// MaterialApp
MaterialApp(theme: FossThemeData.light.toThemeData());
// CupertinoApp or bare WidgetsApp
FossTheme(data: FossThemeData.light, child: const MyApp());
Everything else comes from one accessor, context.fossTheme, so a component never needs to know which shell it's under:
- Colors: 26 semantic roles (background, primary, destructive, and so on), light and dark
- Radii: a five-step scale, from small controls to fully rounded
- Spacing: one base unit, scaled consistently across every component
- Typography: a six-step type scale
- Shadows: four elevation levels
- Motion: named durations for the things that animate (overlays, drawers, toasts)
Retheme once at the root and the whole app follows, no per-component color or radius props to keep in sync.
fossui is young and mobile-first. Web and desktop compile and should work, but they're less exercised than mobile, so verify on the platforms you ship.
Full breakdown, resolution order, and a working three-shell example: the theming docs.
Top comments (1)
The bare WidgetsApp claim is the interesting one, because that is where Flutter starts asserting on you. Text selection is the piece I would check first. EditableText needs selection controls handed to it, and the Material and Cupertino ones come from those shells. Under a bare WidgetsApp, what does a long press on a fossui text field give you, and does the copy and paste toolbar match the rest of the kit?
Second, does anything in the kit still reach for Ink or InkWell internally? That is usually the last Material dependency to leave, and it only announces itself as No Material widget found the moment a user taps.
384 KB for 30 components is a good number to lead with.