DEV Community

Cover image for Hux UI: A Flutter component library that actually solves your frontend problems
Zoe
Zoe

Posted on

Hux UI: A Flutter component library that actually solves your frontend problems

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
Enter fullscreen mode Exit fullscreen mode

Wrap your app:

MaterialApp(
  theme: HuxTheme.lightTheme,
  darkTheme: HuxTheme.darkTheme,
  home: YourApp(),
)
Enter fullscreen mode Exit fullscreen mode

Start using components:

HuxButton(
  onPressed: _handleSubmit,
  isLoading: _isSubmitting,
  primaryColor: Colors.blue, // Text color auto-calculated for readability
  child: Text('Submit'),
)
Enter fullscreen mode Exit fullscreen mode

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'),
)
Enter fullscreen mode Exit fullscreen mode

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
)
Enter fullscreen mode Exit fullscreen mode

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
)
Enter fullscreen mode Exit fullscreen mode

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'),
      ),
    ],
  ),
)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)