Introduction
Flutter package development often focuses on stateless utilities or UI components, but as apps grow in complexity you may need packages that maintain internal state and support hot reload during development. A stateful, hot-reloadable package lets you iterate on logic, UI, or service layers in real time—without restarting your host app. In this tutorial, you’ll learn how to scaffold a package, wire up internal state, link it as a local dependency, and leverage hot reload to boost your feedback loop.
Setting Up a Hot-Reloadable Package
Scaffold a package:
flutter create --template=package my_stateful_package
Add flutter section in pubspec.yaml to register assets and entry points:
flutter:
plugin:
platforms:
android: false
ios: false
assets
Inside lib/, create a stateful widget entry:
library my_stateful_package;
export 'src/stateful_widget.dart';
In the host app’s pubspec.yaml, reference your package via path:
dependencies:
my_stateful_package:
path
Managing Internal State
Inside src/stateful_widget.dart, build a self-contained state manager. You can opt for ChangeNotifier or your favorite state pattern. Here’s a minimal ChangeNotifier example:
import 'package:flutter/widgets.dart';
class CounterModel extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
class StatefulCounter extends StatefulWidget {
@override
_StatefulCounterState createState() => _StatefulCounterState();
}
class _StatefulCounterState extends State<StatefulCounter> {
final CounterModel model = CounterModel();
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: model,
builder: (_, __) => Text('Count: ${model.count}'),
);
}
}Key points:
All logic lives inside the package.
You can update CounterModel or the UI and hot reload your host app to see changes instantly.
Integrating with Flutter Apps
To see hot reload in action:
flutter run your host application.
Import your package widget:
import 'package:my_stateful_package/stateful_widget.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: StatefulCounter());
}
}Modify stateful_widget.dart—change styling, behavior, or state transitions—and hit “r” in your terminal (or use IDE hot reload).
The package code will be recompiled in place, and the host app will inject updated widgets without a full restart.
Testing and Iteration
Automated tests ensure your package is robust and maintainable:
Under test/, write unit tests for your model:
import 'package:flutter_test/flutter_test.dart';
import 'package:my_stateful_package/src/stateful_widget.dart';
void main() {
test('CounterModel increments', () {
final model = CounterModel();
expect(model.count, 0);
model.increment();
expect(model.count, 1);
});
}Use flutter test --coverage for coverage metrics.
Perform widget tests to confirm UI updates correctly on state change.
Continuous integration: configure GitHub Actions or similar to run flutter test and ensure your package updates remain stable. Because you’re using path dependency during dev, you’ll catch issues early before pushing to pub.dev.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
Creating a stateful, hot-reloadable Flutter package enhances your developer experience and accelerates feedback loops. By structuring your package with clear state management, linking it locally for hot reload, and implementing thorough tests, you build high-quality, reusable components.