Library / SDK
hadashiA/VContainer avatar
hadashiA/VContainer

VContainer: a GC-free DI container for Unity, and when it is the wrong tool

The extra fast, minimum code size, GC-free DI (Dependency Injection) library running on Unity Game Engine.

3,062 stars270 forksC#MIT

At a glance

What is it?
VContainer is an MIT-licensed dependency injection library for Unity 2018.4 and newer, built around constructor injection and disposable lifetime scopes. It is fast and small, but its API deliberately omits the container features that make other DI frameworks convenient.
Who is it for?
Adopt VContainer if you are on Unity 2018.4 or newer, your project already has clear domain logic, and you want constructor injection with scopes you can dispose per level or scene. Do not adopt it if you need a container that resolves by string key, supports runtime XML or JSON wiring, or lets you register types without touching the code that constructs them; those are the features the project deliberately leaves out.
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 26 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

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

Editorial analysis

The problem VContainer solves in a Unity project

Unity's component model makes dependencies implicit. A MonoBehaviour finds a service by calling FindObjectOfType, reading a static singleton, or holding a reference assigned in the inspector. All three work until the scene changes, the object is instantiated from a prefab, or a test needs a fake implementation. VContainer replaces those lookups with constructor injection: a class declares what it needs as constructor parameters, and the container supplies the instances.

The intended audience is Unity developers who already separate domain logic from presentation and want that separation enforced by the type system. The README states the goal directly: the API is meant to assist "correct DI way" by selecting features carefully, so that "the DI declaration" does not become "overly complex." That sentence is also a warning. VContainer is not trying to be the most capable container; it is trying to be the smallest one that still supports constructor, method, property and field injection.

Pure C# classes can be entry points too. The README notes that a class implementing IStartable can run on VContainer's own PlayerLoopSystem, which means gameplay code does not have to be a MonoBehaviour to receive a Start or Update callback. For a project that wants domain logic testable outside the editor, that is the part that matters most.

How registration and resolution actually work

A VContainer application is organised around LifetimeScope, a MonoBehaviour that owns an IContainerBuilder. In Configure you register types and their lifetimes. The README example registers a CharacterService as Lifetime.Scoped, an IRouteSearch mapped to AStarRouteSearch as Lifetime.Singleton, a component found in the hierarchy, and an entry point. When the scope builds, the container walks constructor parameters and resolves each one.

Lifetimes are the axis of control. Scoped means one instance per scope, Singleton means one per container. Disposal follows the same structure: when a scope is disposed, instances registered in it are released. That is why the README's level-loading example creates a child scope with CreateChild, CreateChildFromPrefab, or CreateChild with an extra builder callback, and then calls Dispose when the level unloads. The scope is the unit of cleanup, not the individual object.

Scopes can also be chained across additive scene loads. LifetimeScope.EnqueueParent sets the parent for scopes created inside the using block, and LifetimeScope.Enqueue adds registrations that apply to scenes not yet loaded. Both are static and both are scoped to a using block, so the relationship exists only while the block runs. This is a narrow mechanism, and it is the one to read carefully if your scenes load additively.

Installing VContainer from UPM or OpenUPM

The README requires Unity 2018.4 or newer. The Git URL method edits the project manifest directly. Open Packages/manifest.json and add the dependency line under "dependencies", keeping the version suffix that the README shows:

json
{
  "dependencies": {
    "jp.hadashikick.vcontainer": "https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer#1.19.0"
  }
}

After the editor refreshes, the package appears in the Package Manager under its Git source. The alternative is the OpenUPM registry, which requires the openupm-cli tool. Run this from a terminal in the project root:

bash
openupm add jp.hadashikick.vcontainer

The third option is manual: download the .unitypackage from the releases page and open it in the editor. The README lists all three, and the Git URL is the only one that pins a version in a file you can commit.

A first real use is a scope with one service and one entry point. Create a class deriving from LifetimeScope and register in Configure:

csharp
public class GameLifetimeScope : LifetimeScope
{
    public override void Configure(IContainerBuilder builder)
    {
        builder.RegisterEntryPoint<ActorPresenter>();
        builder.Register<CharacterService>(Lifetime.Scoped);
        builder.Register<IRouteSearch, AStarRouteSearch>(Lifetime.Singleton);
        builder.RegisterComponentInHierarchy<ActorsView>();
    }
}

Attach GameLifetimeScope to a GameObject in the scene. At play, the container constructs ActorPresenter, injects CharacterService, ActorsView, and the three IWeapon parameters marked with Key, and calls IStartable.Start on VContainer's PlayerLoopSystem. If a constructor parameter has no registration, the scope throws during build rather than returning null.

Where the design becomes a limitation

The performance claim in the README is specific: "Basically 5-10x faster than Zenject" and "zero allocation" in Resolve when no instances are spawned. Those numbers are the project's own, and the repository ships a benchmark image under website/static/img rather than a reproducible harness in the README. Treat them as a design target, not a measurement you can verify from the documentation alone.

The real cost is flexibility. VContainer has no string-keyed or XML-driven configuration; the README shows object-based Key attributes for multiple implementations of one interface, not named registrations. A team migrating from a container that reads its bindings from a config file will not find an equivalent here. Registration lives in C# and only in C#.

Diagnostics are editor-only. The README lists a "Diagnositcs window on unity editor" (spelled that way in the feature list), so a build that fails to resolve a dependency at runtime gives you less than the editor does. The SourceGenerator that accelerates resolution is optional and lives in its own top-level folder, VContainer.SourceGenerator, with a second folder, VContainer.SourceGenerator.Roslyn3, for the older Roslyn. Two source-generator projects means two things that can fall out of step with your compiler version.

Finally, the ECS integration is marked beta in the README's own feature list. Do not plan an ECS-heavy project around it without reading the documentation site first.

VContainer vs Zenject and vs Reflex

The README compares VContainer to Zenject on speed and allocation, and the repository carries a benchmark image for that comparison. The architectural difference is broader than the numbers. Zenject is the older, larger framework: more binding syntaxes, more installers, more conventions, and more ways to configure a container without touching the classes being constructed. VContainer removes that surface area on purpose, which is why its feature list is short and why the README describes its API as "simple and transparent." If your team needs convention-based binding or a large existing Zenject codebase, the migration is a rewrite of every installer, not a swap.

Reflex is the other comparison people search for. It is a smaller DI container for Unity, and the practical difference is scope management and lifecycle integration: VContainer's model is LifetimeScope plus its own PlayerLoopSystem, with child scopes created explicitly for levels and scenes. A project that only needs a flat container with no scene-scoped teardown may find VContainer's scope machinery heavier than necessary. A project that loads and unloads levels continuously will find that machinery is the point.

Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-09-05. Release 1.19.0 was tagged on 2026-07-01, 1.18.0 on 2026-05-14, and 1.17.0 on 2025-07-22. The gap between 1.17.0 and 1.18.0 was roughly ten months, so the release rhythm is not fixed. Plan upgrades around tags rather than around a schedule.

VContainer is MIT licensed. That permits use in commercial and closed-source Unity projects, and it requires that the copyright notice and permission notice be included in copies or substantial portions of the software. The repository ships a single LICENSE file at the top level. This is a description of the licence text, not legal advice; have your own counsel review distribution obligations if you ship a build that embeds the library.

Upgrade cost is concentrated in two places. The version suffix in Packages/manifest.json is a literal tag, so a Git URL install does not move until you edit that string. And any code that touches the SourceGenerator depends on the Roslyn version your Unity install ships; the presence of VContainer.SourceGenerator.Roslyn3 in the repository is evidence that this has been a compatibility concern.

Editorial conclusion

Adopt VContainer if you are on Unity 2018.4 or newer, your project already has clear domain logic, and you want constructor injection with scopes you can dispose per level or scene. Do not adopt it if you need a container that resolves by string key, supports runtime XML or JSON wiring, or lets you register types without touching the code that constructs them; those are the features the project deliberately leaves out. Before committing, verify two things in your own project: that every entry point you plan to use implements IStartable or another VContainer lifecycle interface rather than Unity's Update, and that the SourceGenerator package (VContainer.SourceGenerator) compiles against your Unity version, since it is listed as optional and is a separate top-level folder in the repository.

Frequently asked questions

How do I install VContainer in a Unity project?

Add the dependency line to Packages/manifest.json using the Git URL the README gives, including the #1.19.0 suffix, or run openupm add jp.hadashikick.vcontainer with the openupm-cli tool. A .unitypackage from the releases page is the third option. Unity 2018.4 or newer is required.

What is VContainer?

It is a dependency injection library for the Unity game engine, written in C# and licensed under MIT. The README describes it as fast, low-allocation in Resolve, and small in code size, with constructor, method, property and field injection.

How does VContainer compare with Zenject?

The README claims VContainer is basically 5-10x faster than Zenject and allocates zero in Resolve when no instances are spawned. The design difference is that VContainer deliberately offers a smaller API, so Zenject's convention-based and config-driven binding styles have no direct equivalent.

Official sources

  1. hadashiA/VContainer 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/hadashia-vcontainer.svg)](https://hysenlabs.com/projects/hadashia-vcontainer)