Open-source project
flutter-it/get_it avatar
flutter-it/get_it

get_it for Dart and Flutter: Service Locator Setup and Trade-offs

Get It - Simple direct Service Locator that allows to decouple the interface from a concrete implementation and to access the concrete implementation from everywhere in your App. Maintainer: @escamoteur

1,475 stars163 forksDartMIT

At a glance

What is it?
get_it is a Dart and Flutter service locator that registers dependencies once and retrieves them by type. It suits applications that need shared access and test substitution, but its global container also changes how dependencies are discovered.
Who is it for?
Adopt get_it when a Dart or Flutter application deliberately wants a shared service locator, straightforward test replacement, and access without BuildContext. Do not adopt it for codebases that require constructor-only dependency discovery or automatic dependency graphs.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 24 days ago.
What is it written in?
Mainly Dart, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What get_it solves in Dart and Flutter applications

get_it addresses the need to access services, models, and business logic from locations that are not naturally connected to a widget tree. A Flutter widget can receive dependencies through constructor parameters, but passing them through every layer can become cumbersome when application services are needed by utilities, business logic, or code outside the widget hierarchy. The README presents get_it as a container that holds important objects after they are registered at startup.

The intended audience is Dart and Flutter developers who want a shared dependency registry without code generation, annotations, or a Flutter dependency. Because the package is framework agnostic, the same approach can be used in Flutter applications, pure Dart packages, server-side software, and command-line applications. The package does not provide widgets, state management, or application screens. Its responsibility is registration and retrieval of objects.

The central abstraction is a type parameter. An application registers an ApiClient, then asks for that type when constructing a UserRepository. The repository itself does not need a BuildContext. This can reduce the amount of dependency plumbing in code that is already connected to the application container, although it also means that dependencies become available through a global locator rather than being declared at each consumer.

Registration lifetimes and retrieval flow

get_it supports several registration types, each representing a different object lifetime. A singleton is created during registration and shared by later callers. A lazy singleton is created on first access, which delays construction until the object is needed. A factory creates a new instance on each retrieval, which suits stateless services or short-lived objects.

The README's example registers ApiClient as a singleton and UserRepository as a lazy singleton. The repository factory closes over the locator and retrieves ApiClient when the repository is first requested. This creates a simple data flow: registration stores a typed factory or instance, later code requests UserRepository, and the first request constructs it with ApiClient. Subsequent requests receive the cached lazy singleton.

For multiple implementations, get_it supports named instances and multiple registrations. It also supports scopes, which create hierarchical registration areas for application states such as login, logout, sessions, and feature flags. These features are useful when a single global container cannot represent the lifetime of every object. They also increase the number of lifecycle rules that an application team must manage.

Installation and first registration

The README gives the dependency declaration for a Flutter or Dart package. Add the package under dependencies in pubspec.yaml, then import the public API in Dart code. The documented declaration is:

yaml
dependencies:
  get_it: ^8.0.2

After adding the dependency, configure the dependencies at startup. The following example follows the README's service pattern. The singleton is created immediately, while the lazy singleton is created only when it is first requested.

dart
final getIt = GetIt.instance;

void configureDependencies() {
  getIt.registerSingleton<ApiClient>(ApiClient());
  getIt.registerLazySingleton<UserRepository>(
    () => UserRepository(getIt<ApiClient>())
  );
}

The code assumes the import and service definitions from the README are present. A Flutter application can then retrieve the repository from a button callback without passing BuildContext. The first lookup constructs UserRepository if it has not already been constructed. A later lookup returns the same lazy singleton.

Async startup, scopes, and unregistering

get_it extends the basic registry beyond synchronous objects. The README documents async objects and startup orchestration, including dependency ordering for objects that require asynchronous initialization. This addresses a common startup problem where one service must finish initialization before another service is created. The README does not provide a complete startup specification, so applications should consult the linked async object documentation before assuming the exact initialization sequence.

Scopes provide another lifetime boundary. They are relevant when login and logout should create or remove a group of services instead of leaving every dependency in the root container. Named registrations allow multiple implementations of one type to coexist. Multiple registrations can be retrieved as a collection when an application needs to inspect or combine all available implementations.

Unregistering is available through `unregister()`. The README states that the default behavior throws when nothing matches the registration. It also documents `getIt.skipUnregisterIfNotRegistered = true` for cases where a missing registration should be ignored. That setting changes a visible failure into a silent no-op, so it should be selected only when repeated cleanup is expected and the absence of a service is harmless. Disposal can be requested when unregistering, but the surrounding application still needs a correct lifecycle for the object being removed.

Testing and the circular factory warning

The package is designed to make test substitution possible. The README mentions `allowReassignment` and `reset()` for replacing real implementations with mocks, while `reset()` clears registrations between tests. Constructor injection remains available as another testing option. This gives a test suite several ways to isolate or replace dependencies, but the global locator still needs deliberate setup and cleanup.

A documented failure mode concerns an untyped tear-off. Registering `getIt.call` or an untyped `getIt.get` tear-off as a lazy singleton can re-enter the same lookup. For lazy singletons and cached factories, get_it detects this circular self-resolution and throws a descriptive `StateError`. Plain `registerFactory` factories are not guarded because recursive construction of the same type can be legitimate when building a tree.

The practical constraint is type clarity. The README suggests using `() => getIt<Impl>()` or a named function that keeps the concrete type argument. This avoids a subtle registration configuration that may otherwise look valid but resolve back into itself.

Limitations and alternative dependency injection designs

The main limitation is architectural rather than a missing feature. A global service locator makes objects accessible from anywhere, which is convenient in a large application but can hide where a dependency comes from. Constructor injection makes dependencies explicit in each component and lets a framework or test create that component with known values. If the project values local visibility, compile-time construction checks, or automatic dependency graph management, a constructor-based injection system may be a better fit.

get_it also does not remove the need to define lifetimes. Developers must decide which objects are shared, lazy, scoped, disposable, or created repeatedly. The package stores registrations, but it does not decide when a business service should be reset or whether a scope has ended. Poorly defined cleanup can leave stale instances in a container or cause an unregistering failure.

A second limitation is that the README does not document rollback, automatic graph validation, or a complete migration procedure. The actual upgrade cost therefore depends on how much application code depends on the global `getIt` instance. The package uses the MIT license, which permits use and modification under that license's terms. License obligations should be checked against the project's LICENSE file and the intended distribution model rather than inferred from the package metadata.

Maintenance and upgrade considerations

The repository is not archived. Its last push was on 2026-09-29, so its recent development record is current within the information available from the repository record. The latest listed release is v8.2.0, dated 2025-08-02. The README's installation example uses `get_it: ^8.0.2`, while the release list includes v8.2.0. That difference is compatible with the stated caret constraint, but applications should confirm the resolved version through their package manager before upgrading.

The package has no code generation or build_runner step according to the README, which lowers the setup cost for a new installation. Existing applications may still have upgrade work if they use scopes, async registration, disposal callbacks, named instances, or multiple registrations. Review CHANGELOG.md and the repository's current test and example files when moving from an earlier major version. The repository includes `test/`, `example/`, `pubspec.yaml`, `CHANGELOG.md`, and related project files, but the README does not describe a formal support window for older releases.

Editorial conclusion

Adopt get_it when a Dart or Flutter application deliberately wants a shared service locator, straightforward test replacement, and access without BuildContext. Do not adopt it for codebases that require constructor-only dependency discovery or automatic dependency graphs. Verify registration order, reset and disposal behavior, async initialization, and scope cleanup before integrating it into production startup logic.

Frequently asked questions

How do I install get_it in a Dart or Flutter project?

Add `get_it: ^8.0.2` under the `dependencies` section of `pubspec.yaml`. The README does not show the package manager command for resolving or installing the dependency, so no command is added here.

How does get_it register and retrieve a service?

Register a singleton with `registerSingleton<T>()`, or create one on first access with `registerLazySingleton<T>()`. Retrieve it with a type argument such as `getIt<UserRepository>()`. The README's example retrieves `ApiClient` while constructing a lazy `UserRepository`.

Can get_it replace dependencies in tests?

Yes. The README documents `allowReassignment` and `reset()` for replacing or clearing registrations, and it also mentions constructor injection as another testing option. Test setup must still arrange the required registrations for each test.

Official sources

  1. flutter-it/get_it on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/flutter-it-get-it.svg)](https://hysenlabs.com/projects/flutter-it-get-it)

Was this useful?