I'm originally a UX designer who recently started doing frontend development, and I quickly realized a pattern in the amount of time wasted refining the UI of every component.
You know the ones: shipping a text field without proper error states, buttons that look terrible in dark mode, loading spinners that don't match anything else in your app.
So I built the Hux UI to handle the stuff we always end up implementing anyway, but properly.
What's the Point?
Instead of copying the same button component between projects (and inevitably forgetting some edge case), you get components that:
- Work out of the box - No spending 2 hours styling a basic button
- Handle accessibility automatically - WCAG AA contrast calculations built in
- Adapt to themes properly - Light/dark mode without the headaches
- Include the stuff you forget - Error states, loading states, proper sizing
Quick Start
flutter pub add hux
Wrap your app:
MaterialApp(
theme: HuxTheme.lightTheme,
darkTheme: HuxTheme.darkTheme,
home: YourApp(),
)
Start using components:
HuxButton(
onPressed: _handleSubmit,
isLoading: _isSubmitting,
primaryColor: Colors.blue, // Text color auto-calculated for readability
child: Text('Submit'),
)
What's Different?
Smart defaults instead of setting up everything yourself:
// This handles loading states, proper sizing, theme adaptation
HuxButton(
onPressed: () {},
isLoading: true, // Automatically shows spinner, disables button
child: Text('Save'),
)
// vs fighting with this every time:
ElevatedButton(
onPressed: isLoading ? null : () {},
child: isLoading
? SizedBox(width: 20, height: 20, child: CircularProgressIndicator())
: Text('Save'),
)
Accessibility without the research:
The contrast calculation system automatically picks readable text colors:
HuxButton(
primaryColor: Color(0xFF1A5F7A), // Dark blue
child: Text('Button'), // Text will be white for readability
)
HuxButton(
primaryColor: Color(0xFFE8F4F8), // Light blue
child: Text('Button'), // Text will be black for readability
)
Forms that don't suck:
HuxTextField(
label: 'Email',
hint: 'Enter your email', // Built in, won't forget it
prefixIcon: Icon(Icons.email),
validator: (value) => value?.contains('@') == true ? null : 'Invalid email',
// Error states, focus states, sizing all handled
)
Component Overview
- HuxButton - Primary/secondary/outline/ghost variants, auto-contrast, loading states
- HuxTextField - Labels, hints, validation, icons, proper error styling
- HuxCard - Consistent containers with optional headers and actions
- HuxLoading - Spinners and overlays that match your theme
- HuxChart - Line/bar charts with proper theming (uses cristalyse under the hood)
- HuxContextMenu - Right-click menus with smart positioning
When to use this
Good fit if you:
- Want to stop rebuilding basic components
- Care about accessibility but don't want to become a WCAG expert
- Need consistent theming across light/dark mode
- Ship MVPs regularly and want things to look good by default
Maybe not if you:
- Need heavily customized components with unique behaviors
- Already have a comprehensive design system
- Prefer building everything from scratch
Technical Notes
- Built on Material 3 foundation
- Uses semantic design tokens (not hardcoded colors)
- All components use WCAG AA contrast calculations
- Theme-aware from the ground up
- Minimal dependencies (cristalyse for charts, feather icons, google fonts)
Real Example
Here's a login form that would take 30+ minutes to style properly from scratch:
Form(
child: Column(
children: [
HuxTextField(
label: 'Email',
hint: 'Enter your email',
prefixIcon: Icon(FeatherIcons.mail),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value?.isEmpty ?? true) return 'Email required';
if (!value!.contains('@')) return 'Invalid email';
return null;
},
),
SizedBox(height: 16),
HuxTextField(
label: 'Password',
hint: 'Enter your password',
prefixIcon: Icon(FeatherIcons.lock),
obscureText: true,
validator: (value) =>
value?.length ?? 0 < 6 ? 'Password too short' : null,
),
SizedBox(height: 24),
HuxButton(
onPressed: _login,
isLoading: _isLoading,
child: Text('Sign In'),
),
],
),
)
Everything just works - proper spacing, theme adaptation, error states, loading handling.
Try it
The library is small enough to understand quickly but handles enough edge cases that you'll actually save time. Perfect for prototypes, MVPs, or when you just want to focus on your app logic instead of styling buttons for the hundredth time.
flutter pub add hux
What problems do you always end up solving when building Flutter UIs? Let me know if there are common patterns I should add!
If this saved you some time, I'd really appreciate your support:
👍 Upvote Hux UI on Product Hunt and Peerlist
🐦 Follow me on Twitter for updates on new components and features
💼 Connect on LinkedIn and Peerlist
📝 Read more about my thoughts on design & product on Substack
🔗 Links:
Top comments (0)