Flutter Singleton Class Tutorial: Step-by-Step Implementation
RulTech > Blogs > Dart Singleton > Flutter Singleton Class Tutorial: Step-by-Step Implementation

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() or Get.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.