Dart VM vs native code

Greetings Flutter masters and apprentices. There is something that is not very clear to me after reading the first chapter of Flutter Apprentice. It is stated that Dart is compiled to native ARM/x86 code, but also later it is stated that hot reload/restart are only available in developer mode, because they depend on Dart VM. So I am a bit confused. When is Dart running using a VM and when is run compiled in native code?

Dart VM is always involved … but it does not imply that Dart is always interpreted

Depending on the compilation pipelines, JIT or AOT is used (see bellow for official explainer [1]),

The difference is how the “code” runs

For AOT, a lite/stripped version of the Dart VM is used, named: “precompiled runtime”, and its title, because, it does not contain any compiler components and is incapable of loading Dart source code dynamically … which is not the case with JIT

1: Dart overview | Dart

Native platform: For apps targeting mobile and desktop devices, Dart includes both a Dart VM with just-in-time (JIT) compilation and an ahead-of-time (AOT) compiler for producing machine code.

Also there you can read:

Dart Native (machine code JIT and AOT)
During development, a fast developer cycle is critical for iteration. The Dart VM offers a just-in-time compiler (JIT) with incremental recompilation (enabling hot reload), live metrics collections (powering DevTools), and rich debugging support.

When apps are ready to be deployed to production — whether you’re publishing to an app store or deploying to a production backend — the Dart AOT compiler enables ahead-of-time compilation to native ARM or x64 machine code. Your AOT-compiled app launches with consistent, short startup time.

The AOT-compiled code runs inside an efficient Dart runtime that enforces the sound Dart type system and manages memory using fast object allocation and a generational garbage collector.

Thank you @yeradis for the to-the-point answer, and for the references!