Flutter Singleton Class Tutorial: Step-by-Step Implementation
What is a Singleton in Flutter?
In Flutter, a Singleton ensures only one instance of a class is created and used throughout your app. It’s perfect for services like API clients, database handlers, and settings storage.
In Flutter (and Dart), the Singleton pattern is a design pattern that ensures a class has only one instance and provides a global point of access to it. It’s widely used for services like API calls, database helpers, and settings managers.
Why Use a Singleton in Flutter?
✅ Memory efficient
✅ Centralized data or logic
✅ Global access to a single instance
✅ Ideal for services (e.g.,
ApiService
,DbService
,Logger
)
✅ Step-by-Step Guide to Create a Singleton Class in Flutter
Step 1: Create a Dart File
Create a Dart file for your singleton class. For example:lib/services/api_service.dart
Step 2: Define the Singleton Class
class ApiService {
// Step 1: Private constructor
ApiService._privateConstructor();
// Step 2: Static instance of the class
static final ApiService _instance = ApiService._privateConstructor();
// Step 3: Public getter to access the instance
static ApiService get instance => _instance;
// Step 4: Sample method
void fetchData() {
print("Fetching data from API...");
}
}
Step 3: Use the Singleton in Your App
Anywhere in your Flutter app, you can now use this singleton like:
import 'package:your_app/services/api_service.dart';
void main() {
ApiService.instance.fetchData();
}
Optional: Lazy Initialization Singleton
If you want to lazy load your instance only when it’s needed:
class LazyApiService {
static LazyApiService? _instance;
LazyApiService._();
static LazyApiService get instance {
_instance ??= LazyApiService._();
return _instance!;
}
void fetchData() {
print("Lazy loading fetch...");
}
}
Best Practices
Use singleton for stateless services.
Avoid using it for UI-related logic.
Prefer
Get.put()
orGet.lazyPut()
in GetX for service registration (if using GetX).
Bonus: Singleton with GetX (For Dependency Injection)
class MyService extends GetxService {
Future<MyService> init() async {
// initialization logic here
return this;
}
void log(String msg) {
print("Log: $msg");
}
}
// In main.dart or bindings:
Get.putAsync<MyService>(() async => await MyService().init());
// Usage:
Get.find<MyService>().log("Hello Singleton");
Final Thoughts
Using the Singleton pattern in Flutter improves performance and organizes code better, especially for service layers. It’s a best practice for shared logic and resources.
Singleton is a powerful pattern that helps manage shared services efficiently in Flutter. By following the steps above, you can confidently integrate singletons into your app for clean and maintainable code.