Under Construction
Unity••19 min•226 views••

Unity Switches From Mono To CoreCLR: What Do Developers Actually Get?

Minh Khoa

Minh Khoa

Author

image.pngShort answer: CoreCLR it replaces the Mono runtime underneath Unity, not MonoBehaviour and also does not remove IL2CPP. The three most noteworthy changes are a more modern Garbage Collector, better runtime for managed code, and faster code reload in the Editor.

When people hear “Unity drops Mono,” it is easy to think:

Mono bị bỏ
→ MonoBehaviour biến mất?
→ Project phải viết lại?
→ IL2CPP không còn cần thiết?

In practice, you still write code as before:

public class Player : MonoBehaviour
{
    private void Update()
    {
        transform.Translate(Vector3.forward * Time.deltaTime);
    }
}

GameObject, MonoBehaviour, Awake, Start, Update and Coroutine remain unchanged. What is replaced is the execution and management engine for C# under Unity API.


CoreCLR Where Is It Located?

C code# is not CPU run directly. Roslyn compiles it into IL and packages it into an assembly like Assembly-CSharp.dll.

C#
↓ Roslyn Compiler
IL trong Assembly-CSharp.dll
↓ Mono JIT hoặc CoreCLR RyuJIT
Machine Code
↓
CPU

Mono and CoreCLR like two versions of the same interpreter: both receive IL and then translate it into machine code when needed. CoreCLR is a newer runtime, developed alongside the modern .NET ecosystem.

MonoBehaviour = Unity lifecycle API
Mono/CoreCLR  = Runtime chạy managed C# phía dưới

The name MonoBehaviour is only a API historical name. It does not require Unity to continue using the Mono runtime.


Mono And CoreCLR How Are They Actually Different?

The differencescurrent MonoCoreCLR new
JIT compilerMono JITRyuJIT
Garbage CollectorBoehm GC, non-movingPrecise, moving, generational GC
C platform#Moving away from modern .NETNET 10 and C# 14
Code reloadUsually reloads the entire AppDomainMore granular assembly reload
ToolingUnity’s own toolchainCloser to the standard .NET debugger, profiler, and MSBuild

Among them, GC and code reload are the two changes most likely to affect real projects.


1. A More Modern Garbage Collector

Unity currently uses Boehm GC. This is GC conservative and non-moving: where an object is placed in memory usually stays there.

CoreCLR uses generational GC:

Object mới tạo       → Gen 0
Sống qua collection  → Gen 1
Sống lâu hơn nữa     → Gen 2

The idea is based on a very practical observation:

Most newly created objects die very quickly.

For example UI creating many temporary strings:

private void Update()
{
    scoreText.text = "Score: " + score;
}

Short-lived objects mainly live in Gen 0. GC can focus on processing the young object region instead of frequently scanning the entire managed heap.

CoreCLR GC can also move live objects to compact gaps:

Trước: [Live][Dead][Live][Dead][Live]
Sau:   [Live][Live][Live][Free.........]

This reduces fragmentation and provides a better foundation for memory management.

But do not interpret this as:

GC mới tốt hơn → allocation trong Update không còn vấn đề

Allocation still has a cost. Collection at the wrong time can still cause frame spikes. CoreCLR helps the garbage collector work better; it does not make garbage free.


2. Faster Code Reload, But Static State Is Easier to Cause Bugs With

Unity with Mono often reloads the entire AppDomain when compiling code or entering Play Mode. A familiar side effect is that static state gets reset:

public static class GameSession
{
    public static int Score;
    public static event Action OnGameOver;
}

Many projects unconsciously rely on this behavior:

Enter Play Mode
→ Domain Reload
→ Static field trở về giá trị ban đầu

CoreCLR switches to more granular reload via AssemblyLoadContext. Unchanged assemblies can be kept; only the necessary code is reloaded.

The Editor has less work to do, but static state is no longer guaranteed to be reset for you.

For example: events being called multiple times

private void OnEnable()
{
    GameEvents.OnGameOver += ShowGameOver;
}

If the code does not unsubscribe:

Play lần 1 → 1 listener
Play lần 2 → 2 listeners
Play lần 3 → 3 listeners

An event may call UI three times, keep old objects in memory, and prevent the old assembly from unloading.

Cleanup must be explicit:

private void OnDisable()
{
    GameEvents.OnGameOver -= ShowGameOver;
}

Not just events, we also need to actively clean up:

  • Static caches and singletons.
  • Threads, timers, and file watchers.
  • Cancellation tokens.
  • Native handles and network connections.

CoreCLR helps Unity reload less code. In return, projects should not rely on Domain Reload to silently clean up state for them.


3. RyuJIT And More Modern .NET

CoreCLR uses RyuJIT with Tiered Compilation:

Method được gọi lần đầu
→ Compile nhanh để chạy sớm

Method trở thành hot
→ Compile lại với optimization mạnh hơn

The runtime does not need to heavily optimize a method that only opens Settings once, but can focus on methods that are called millions of times.

Unity is also moving toward .NET 10, C# 14, MSBuild, and the standard .NET tooling. The most obvious benefits at first may be:

  • Compile and reload code faster.
  • Debugger, profiler, and IDE better.
  • Access to API and more modern .NET packages.
  • Managed hot paths have a better chance of being optimized well.

However:

Mono → CoreCLR ≠ FPS tự động tăng mạnh

In the early stages, Unity is prioritizing compatibility and performance parity. Whether a game becomes faster still depends on whether the bottleneck is in managed code, rendering, physics, GPU or elsewhere.


CoreCLR Is there Replacement IL2CPP or not?

No. The two systems get IL to CPU through two different paths.

CoreCLR — JIT when running

C# → IL → CoreCLR JIT → Machine Code

Like a translator standing next to you: whichever sentence you need, they translate it right then as it is spoken.

Suitable for the Editor, Desktop Player, debugging, and fast iteration.

IL2CPP — AOT before running

C# → IL → C++ → Native Compiler → Machine Code

Like translating the entire document first, printing it as a complete book, and only then releasing it.

IL2CPP is still necessary for Android, iOSMeta Quest, consoles, WebGL and platforms that do not allow JIT.

A future project may use all three:

Trong Editor        → CoreCLR
Build Android/iOS   → IL2CPP
Code Jobs/ECS       → Burst

So moving the Editor to CoreCLR does not mean APK using IL2CPP will automatically receive optimization from RyuJIT.


Do Old Projects Need to Be Rewritten?

Most gameplay code will still run normally. Areas that need closer checking include:

  • Static fields, static events, and singletons.
  • Editor tooling and reflection.
  • Native plugins or unsafe code.
  • Old DLLs targeting .NET Framework.
  • Save systems that use BinaryFormatter.
  • Code that depends on AppDomain or Assembly.Location.
  • Deterministic simulation.

For example, BinaryFormatter is removed in newer .NET because of security issues. Old save systems should be moved to System.Text.Json, JsonUtility or a clearly managed format.

CoreCLR may also produce results floating-point slightly different from Mono JIT. Small errors are usually insignificant, but they can cause desync with lockstep multiplayer, Photon Quantum, or deterministic replay after thousands of ticks.


Timeline and How to Prepare

The old roadmap put CoreCLR officially in Unity 6.8. The newer announcement at Unite Seoul in 7/2026 brings CoreCLR,.NET 10 and C# 14 into Unity 7, expected in early 2027.

Unity 6.6
→ Fast Enter Play Mode mặc định cho project mới

Unity 6.7
→ Experimental CoreCLR Desktop Player để test

Unity 7
→ CoreCLR + .NET 10 + C# 14 chính thức

To prepare a project:

  1. Enable Fast Enter Play Mode and try turning off Domain Reload.
  2. Enter/Exit Play Mode multiple times to find state that is being retained.
  3. Review static fields, singletons, and static events.
  4. Actively clean up threads, timers, callbacks, and events.
  5. Run Project Auditor, check Domain Reload warnings.
  6. Regression test save/loadplugins, and deterministic simulation.

If the project still runs correctly when Domain Reload is turned off, that is a good sign that the architecture is more ready for CoreCLR.


How to Remember

MonoBehaviour = Unity lifecycle API
CoreCLR       = Runtime mới chạy managed C#
IL2CPP        = Compile IL thành native code trước khi chạy
Burst         = Compiler tối ưu cho Jobs/ECS

The key takeaway: CoreCLR does not change much how we write gameplay. It changes how Unity runs C#, handles memory, and reloads code underneath. The biggest initial benefit may not be FPS an immediate increase, but a faster Editor and a C# platform that is no longer falling behind the modern .NET ecosystem.