MicroVM.nix

GitHub
https://github.com › microvm-nix › microvm
MicroVMs are Virtual Machines but use special device interfaces (virtio) for high performance. This project runs them on NixOS/Linux hosts and macOS (via vfkit) ...Read more
Intro - microvm.nix
GitHub Pages documentation
https://microvm-nix.github.io › microvm
Starting with the reasons why for the remainder of this chapter, this handbook guides you through the provisioning of MicroVMs on your NixOS or macOS machine.Read more
Packages - microvm

NixOS Search - Packages
https://search.nixos.org › packages
Create and manage the lifecycle of MicroVMs backed by containerd. Name: flintlock; Version: 0.8.1; Homepage · Source; License: Mozilla Public License 2.0.Read more
Running NixOS Micro VMs on MacOS

Reddit · r/NixOS
4 comments · 2 weeks ago
I've actually been working on my own custom firecracker setup using Nix and i've got it booting in about 1.5 seconds now by skipping stage 1 ...
Skip to main content
Running NixOS Micro VMs on MacOS : r/NixOS
 

r/NixOS

Advertise on Reddit

Open chat
Create
Create post
Open inbox

User Avatar
Expand user menu
Skip to Navigation Skip to Right Sidebar

Back
 
Go to NixOS
r/NixOS
•
15d ago
abhin4v

Running NixOS Micro VMs on MacOS

  r/NixOS - Running NixOS Micro VMs on MacOS
abhinavsarkar.net

Open
 
Upvote
48

Downvote
 
4
Go to comments


Share
 u/QuestSoftware avatar
QuestSoftware
•
Promoted
 
Identity systems are the #1 entry point for modern attacks and the volume isn't slowing down. Yet research shows most organizations overestimate their readiness, underinvest in recovery, and can't fully see their own identity attack surface.
Learn More
quest.com
 Thumbnail image: Identity systems are the #1 entry point for modern attacks and the volume isn't slowing down. Yet research shows most organizations overestimate their readiness, underinvest in recovery, and can't fully see their own identity attack surface.
 
Sort by:

Best
 
Search Comments
Expand comment search
Comments Section
theutz
•
15d ago
I was just gonna start looking into this! Thanks for the detailed write up!

Upvote
7

Downvote
 
Reply

Award

Share
 
Reddich07
•
14d ago
Thanks a lot! It’s a great write-up.

Upvote
3

Downvote
 
Reply

Award

Share
 
 u/chihuahua826 avatar
chihuahua826
•
15d ago
I've actually been working on my own custom firecracker setup using Nix and i've got it booting in about 1.5 seconds now by skipping stage 1 of boot entirely, and i'm using the firecracker kernel rather than the nix one. Been running it under jailer with a typescript app that orchestrates the VMs on the host. They communicate to the host via sockets, I just use socat to bridge localhost to the socket internally


Upvote
1

Downvote
 
Reply

Award

Share
 
billsb
•
12d ago
Releasing that on GH ?

Upvote
1

Downvote
 
Reply

Award

Share
 
Community Info Section
r/NixOS
 Joined
NixOS - Purely functional
Created Aug 26, 2011
Public
48K
Weekly visitors
1.1K
Weekly contributions
COMMUNITY ACHIEVEMENTS
Repeat Contributor
Flag Planter
Repeat Contributor, 
Flag Planter
2 unlocked

View All
MODERATORS
Message Mods
 u/kxra avatar
u/kxra
u/iElectric avatar
u/iElectric
Domen
View all moderators
Reddit Rules
Privacy Policy
User Agreement
Your Privacy Choices
Accessibility
Reddit, Inc. © 2026. All rights reserved.

Expand NavigationAbout Posts Notes μBlog Links Photos Now       

Skip to main content
Running NixOS Micro VMs on MacOS
 🖋️April 9, 2026
⏳A four minute read
7 💬 5 🗣️  ❤️ 10 🔁
programmingnix
microvm.nix is a framework to run NixOS based micro VMs on various platforms. In particular, it can use vfkit to run micro VMs on macOS that use the macOS virtualization framework to provide a more performant VM than QEMU.

microvm.nix works well but the documentation is a bit lacking. I had to figure out some gotchas while setting this up on my MacBook Pro M4, so I decided to write this note.

This tutorial requires Nix and Nix Darwin to be installed on the macOS machine.

To build a micro VM, we need a NixOS builder machine running AArch64 Linux. Thankfully, it is really easy to set up one with Nix Darwin. Assuming we have Nix Darwin set up with a Nix flake like:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-25.11-darwin";
    nix-darwin = {
      url = "github:LnL7/nix-darwin";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  
  outputs =
    inputs@{
      self,
      nixpkgs,
      nix-darwin,
      ...
    }:
    let
      system = "aarch64-darwin";
      pkgs = import nixpkgs { inherit system; };
    in
    {
      darwinConfigurations."Abhinavs-M4-MacBook-Pro" = nix-darwin.lib.darwinSystem {
        inherit system;
        specialArgs = { inherit inputs; };
        modules = [
          ./configuration.nix
        ];
      };
    };
}
First, we add Nix Linux builder config:

darwinConfigurations.${hostname} = nix-darwin.lib.darwinSystem {
  inherit system;
  modules = [
    ./configuration.nix
    {
      nix = {
        distributedBuilds = true;
        linux-builder = {
          enable = true;
          package = pkgs.darwin.linux-builder;
          systems = [ "aarch64-linux" ];
        };
      };
    }
  ];
};
Now, we switch the system config to build and start the Linux builder:

nix build .#darwinConfigurations.Abhinavs-M4-MacBook-Pro.system
sudo ./result/sw/bin/darwin-rebuild switch --flake .
We should verify that the builder is working:

sudo ssh linux-builder "uname -a"
# Should show "aarch64-linux"
It may take up to a minute for the builder to start. Once SSH works, we can proceed.

We create a microvm.nix file with the micro VM configuration:

{
  inputs,
  lib,
  pkgs,
  ...
}:
{
  networking.hostName = "my-microvm";
  services.getty.autologinUser = "root";
  microvm = {
    hypervisor = "vfkit";
    vcpu = 4;
    mem = 8192; # 8GB
    # graphics.enable = true;
    writableStoreOverlay = "/nix/.rw-store";
    volumes = [
      {
        image = "nix-store-overlay.img";
        mountPoint = "/nix/.rw-store";
        size = 40960; # 40GB
      }
    ];
    shares = [
      {
        proto = "virtiofs";
        tag = "ro-store";
        source = "/nix/store";
        mountPoint = "/nix/.ro-store";
      }
      {
        proto = "virtiofs";
        tag = "projects";
        source = "/Users/abhinav/Projects";
        mountPoint = "/projects";
      }
    ];
    interfaces = [
      {
        type = "user";
        id = "usernet";
        mac = "02:00:00:01:01:01";
      }
    ];
  };

  networking.interfaces.eth0.useDHCP = true;

  systemd.tmpfiles.rules = [
    "d /nix/.rw-store/nix-build 0755 root root -"
  ];

  nix = {
    settings = {
      sandbox = false;
      build-dir = "/nix/.rw-store/nix-build";
    };
    registry.nixpkgs.flake = inputs.nixpkgs;
  };
  system.stateVersion = "25.11";
}
This configures a micro VM with 4 VCPU, 8GB RAM and 40 GB disk. The disk image is used to store the Nix packages downloaded within the VM. It is mounted at /nix/.rw-store. The host’s Nix store is mounted read-only at /nix/.ro-store. The writableStoreOverlay option combines these two with overlays to create the VM’s Nix store at /nix/store.

We can share additional directories from the host and mount them in the VM, as we do here for the /Users/abhinav/Projects directory from the macOS host.

Next couple of lines set up networking in the VM. The vfkit hypervisor supports only NAT networking. This means:

The VM can make outgoing connections to the host/internet.
The host cannot initiate connections to the VM.
There are ways to work around this using gvisor-tap-vsock and vmnet-helper, but we are not going into it here.

We can uncomment the graphics.enable = true; line if we want a graphical NixOS VM.

Finally, the workaround for the big gotcha! By default Nix does builds in a sandbox and the sandbox is created (and deleted) on the root filesystem. However, microvm.nix uses a temporary filesystem residing in RAM for the root filesystem. This means that the Nix builds may cause the root FS and RAM to fill up, causing out-of-memory or out-of-disk-space errors. To prevent that, we disable the sandbox and set the build directory to be at /nix/.rw-store/nix-build on the disk image we mounted.

Next, we integrate the VM config with the Nix Darwin flake:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-25.11-darwin";
    nix-darwin = {
      url = "github:LnL7/nix-darwin";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    microvm = {
      url = "github:microvm-nix/microvm.nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs =
    inputs@{
      self,
      nixpkgs,
      nix-darwin,
      microvm,
      ...
    }:
    let
      system = "aarch64-darwin";
      microvm-system = builtins.replaceStrings [ "-darwin" ] [ "-linux" ] system;
      pkgs = import nixpkgs { inherit system; };
      microvm-run =
        let
          runner = self.nixosConfigurations.microvm.config.microvm.declaredRunner;
        in
        pkgs.writeShellScriptBin "microvm-run" ''
          cleanup() { stty "$(stty -g)"; }
          trap cleanup EXIT
          stty intr ^] susp ^] quit ^]
          exec ${runner}/bin/microvm-run
        '';
    in
    {
      darwinConfigurations."Abhinavs-M4-MacBook-Pro" = nix-darwin.lib.darwinSystem {
        inherit system;
        specialArgs = { inherit inputs; };
        modules = [
          ./configuration.nix
          {
            nix = {
              distributedBuilds = true;
              linux-builder = {
                enable = true;
                package = pkgs.darwin.linux-builder;
                systems = [ "aarch64-linux" ];
              };
            };
            environment.systemPackages = [ microvm-run ];
          }
        ];
      };
      nixosConfigurations.microvm = nixpkgs.lib.nixosSystem {
        system = microvm-system;
        specialArgs = { inherit inputs; };
        modules = [
          microvm.nixosModules.microvm
          ./microvm.nix
          { microvm.vmHostPackages = nixpkgs.legacyPackages.${system}; }
        ];
      };
    };
}
Let’s go over the tricky bits. The microvm-run wrapper script rebinds Ctrl + ] to send the interrupt, suspend and quit signals instead of the usual Ctrl + C so that we can use Ctrl + C inside the VM without it causing the VM to shut down. We add the script to our system packages. Lastly, the nixosConfigurations.microvm defines the actual micro VM using the microvm.nix file.

Finally, we build and install the micro VM:

nix build .#darwinConfigurations.Abhinavs-M4-MacBook-Pro.system
sudo ./result/sw/bin/darwin-rebuild switch --flake .
And, now we can run it from any directory:

microvm-run
Note that the disk image file will be created in the directory in which we run the above command.

After this, we can remove the Linux builder config and switch again to stop and delete it.

Now we have a performant micro VM running NixOS to play around with in our macOS machine. That’s all I had for this note. I hope this helps.

If you have any questions or comments, please leave a comment below. If you liked this post, please share it. Thanks for reading!

 ❤️ 10 🔁
Like, repost, or comment

Fediverse
Lobsters
Reddit
Discourse
Comments below
Send a Webmention for this post


Read Similar Posts

Aug 27 2022
Creating NixOS custom image for Digital Ocean VPS
Dec 9 2022
Solving Advent of Code “No Space Left On Device” with Parsers, Zippers and Interpreters
Oct 5 2022
Just, Nix Shell and Podman are a Killer Combo
Oct 7 2022
Software I use on my MacBook
Nov 16 2022
Monitoring VPS Network Usage with vnStat and NixOS
Explore Different Posts

Oct 30 2025
Ten Pointless Facts About Me
May 18 2023
An Ode to Bicycling
Aug 30 2019
Commute Duration Analysis
Mentioned In

Apr 13 2026
Notes for the Week #15 (2026)
Got suggestions, corrections, or thoughts? Post a comment!
5 Mentions

 lemmy.bestiver.se Apr 9, 2026
 @lobsters@mastodon.social Apr 9, 2026
 lemmit.online Apr 10, 2026
 alobbs.com Apr 12, 2026
 juev.org Apr 12, 2026
  Previous
Notes for the Week #14 (2026)	Next  
Notes for the Week #15 (2026)
Home About Posts Notes μBlog Links Projects Photos Readings Now      
  IndieWebClub Bangalore Webring  
  IndieWeb Webring  
© 2017–2026, Abhinav Sarkar
 IndieWebCamp  Webmention  Microformats  Atom feed
