πŸ”₯ FlashX

The most powerful, beautiful, and developer-friendly Flutter notification package. Zero boilerplate Β· Works with every state manager Β· Stunning by default.

pub.dev License: MIT Flutter Dart Platforms


✨ Why FlashX?

Feature FlashX fluttertoast another_flushbar bot_toast
All platforms βœ… ⚠️ Limited βœ… βœ…
State mgmt. agnostic βœ… βœ… βœ… βœ…
Queue system βœ… ❌ βœ… βœ…
Priority queue βœ… ❌ ❌ ❌
Future tracking API βœ… ❌ ❌ ❌
Glassmorphism βœ… ❌ ❌ ❌
7 built-in animations βœ… ❌ ⚠️ 2 ⚠️ 3
Custom widget βœ… ❌ βœ… βœ…
Gradient backgrounds βœ… ❌ ❌ ❌
Duplicate prevention βœ… ❌ ❌ ❌
Dismiss by ID βœ… ❌ ❌ βœ…
Progress bar βœ… ❌ βœ… ❌
RTL support βœ… βœ… βœ… βœ…
Dart 3 / null-safe βœ… βœ… βœ… βœ…

πŸš€ Quick Start (2 minutes)

1. Install

dependencies:
  flashx: ^1.0.0
flutter pub get

2. Initialize

Wrap your MaterialApp builder β€” that's it:

import 'package:flashx/flashx.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: FlashXWidget.init(), // ← One line
      home: HomeScreen(),
    );
  }
}

3. Show notifications

FlashX.success("Profile saved!");
FlashX.error("Payment failed.");
FlashX.warning("Weak internet connection.");
FlashX.info("Version 2.0 is available.");

Done. πŸŽ‰


πŸŽ›οΈ All APIs at a Glance

Convenience methods

FlashX.success("Saved");
FlashX.error("Failed", title: "Oops");
FlashX.warning("Low battery");
FlashX.info("New update");
final id = FlashX.loading("Uploading...");
FlashX.dismissById(id);
FlashX.dismissAll();

Full control with FlashOptions

FlashX.show(FlashOptions(
  title: "No Internet",
  message: "Please check your connection.",
  type: FlashType.error,
  position: FlashPosition.top,
  animation: FlashAnimation.elastic,
  duration: Duration(seconds: 5),
  actionText: "Retry",
  onAction: () => reconnect(),
  secondaryActionText: "Dismiss",
  onSecondaryAction: FlashX.dismissAll,
  showProgress: true,
  dismissDirection: FlashDismissDirection.horizontal,
  priority: FlashPriority.critical,
));

Future tracking

await FlashX.future(
  future: uploadData(),
  loading: "Uploading your file...",
  success: "Upload complete! πŸŽ‰",
  error: "Upload failed. Please retry.",
);

With dynamic messages based on result:

await FlashX.future<User>(
  future: fetchUser(),
  loading: "Fetching profile...",
  success: (user) => "Welcome back, ${user.name}!",
  error: (e) => "Error: ${e.toString()}",
);

Extension methods

// On BuildContext
context.flashSuccess("Saved!");
context.flashError("Failed!");

// On String
"Done!".flashSuccess();
"Oops!".flashError();

// On Future
uploadFile().flashFuture(
  loading: "Uploading...",
  success: (_) => "Done!",
  error: (e) => "Failed: $e",
);

🎨 Customization

Global config

FlashX.configure(FlashXConfig(
  position: FlashPosition.bottom,
  animation: FlashAnimation.bounce,
  duration: Duration(seconds: 3),
  borderRadius: BorderRadius.circular(20),
  blur: true,                   // Glassmorphism globally
  maxVisible: 3,                // Max stacked notifications
  stackedMode: false,           // Show one at a time (default)
  showProgress: true,
  dismissDirection: FlashDismissDirection.horizontal,
));

Custom theme per notification

FlashX.show(FlashOptions(
  type: FlashType.custom,
  message: "Premium feature unlocked.",
  themeData: FlashThemeData(
    backgroundColor: Color(0xFF1E1B4B),
    textColor: Colors.white,
    iconColor: Colors.amberAccent,
    actionColor: Colors.amber,
    progressColor: Colors.amber,
    borderColor: Color(0xFF312E81),
    borderWidth: 1,
  ),
));

Gradient background

FlashX.show(FlashOptions(
  type: FlashType.custom,
  title: "Pro Plan",
  message: "Upgrade to unlock all features.",
  themeData: FlashThemeData(
    backgroundColor: Colors.transparent,
    textColor: Colors.white,
    iconColor: Colors.white,
    actionColor: Colors.amber,
    progressColor: Colors.amber,
    gradient: LinearGradient(
      colors: [Color(0xFF7C3AED), Color(0xFFEC4899)],
    ),
  ),
  actionText: "Upgrade",
  onAction: () => openUpgradeScreen(),
));

Glassmorphism

FlashX.show(FlashOptions(
  type: FlashType.success,
  message: "Saved with glass effect!",
  themeData: FlashThemeData.glassSuccess(dark: false),
));

Or enable globally:

FlashX.configure(FlashXConfig(blur: true));

Custom widget

FlashX.show(FlashOptions(
  type: FlashType.custom,
  customWidget: Row(
    children: [
      CircleAvatar(backgroundImage: NetworkImage(avatarUrl)),
      SizedBox(width: 12),
      Expanded(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("Alice sent you a message"),
            Text("Hey! Are you free tonight?", style: TextStyle(fontSize: 12)),
          ],
        ),
      ),
    ],
  ),
));

🎞️ Animations

Name Description
FlashAnimation.slide Slides in from the nearest edge
FlashAnimation.fade Fades in/out smoothly
FlashAnimation.scale Scales from center with ease-out-back
FlashAnimation.elastic Spring-like elastic entrance
FlashAnimation.bounce Bouncy entrance
FlashAnimation.rotation Rotation + scale + fade
FlashAnimation.ios iOS-style cubic-emphasized curve

Custom animation builder

FlashX.show(FlashOptions(
  message: "Custom animation!",
  animationBuilder: (controller, child) {
    return SlideTransition(
      position: Tween(begin: Offset(-2, 0), end: Offset.zero)
          .animate(CurvedAnimation(parent: controller, curve: Curves.elasticOut)),
      child: child,
    );
  },
));

πŸ“‹ Queue & Priority

// Normal (FIFO order)
FlashX.show(FlashOptions(message: "Normal", priority: FlashPriority.normal));

// Jumps ahead of normal items
FlashX.show(FlashOptions(message: "Important!", priority: FlashPriority.high));

// Goes to the front immediately
FlashX.show(FlashOptions(
  type: FlashType.error,
  message: "Critical error!",
  priority: FlashPriority.critical,
));

πŸ”‘ Duplicate Prevention

// Show only once even if called multiple times
for (int i = 0; i < 5; i++) {
  FlashX.show(FlashOptions(
    message: "You are offline",
    key: "offline_banner",  // ← unique key
  ));
}
// Only one notification is shown

🌐 Platform Support

Platform Supported
Android βœ…
iOS βœ…
Web βœ…
Windows βœ…
macOS βœ…
Linux βœ…

🧩 State Management

FlashX has zero dependency on any state management solution. Use it with:

  • βœ… GetX β€” call FlashX.success(...) anywhere
  • βœ… Provider β€” no setup needed
  • βœ… Riverpod β€” works in any ref.read() or callback
  • βœ… Bloc/Cubit β€” call from BlocListener
  • βœ… MobX β€” call from reactions
  • βœ… Stacked β€” call from ViewModelBuilder
  • βœ… setState β€” just call it!

πŸ—ΊοΈ Roadmap

  • Push-style grouped notifications
  • Custom enter/exit path animations
  • Notification history panel
  • Haptic feedback support
  • Sound/vibration customization
  • Scheduled/delayed notifications
  • Notification tap-through to routes

🀝 Contributing

Contributions, issues, and feature requests are welcome!

  1. Fork the repo
  2. Create your feature branch: git checkout -b feat/amazing-feature
  3. Commit your changes: git commit -m 'feat: add amazing feature'
  4. Push: git push origin feat/amazing-feature
  5. Open a pull request

Please read CONTRIBUTING.md first.


πŸ“„ License

MIT License Β© 2025 FlashX Contributors

Libraries

flashx