wslc: A native Linux container runtime for Windows
Sign in<br>Subscribe
WSL has always been about reducing friction between Windows and Linux. First came the syscall translation layer. Then a full Linux kernel. Then GPU passthrough and systemd. The next piece is wslc: a native Linux container runtime built directly into WSL, with a Docker-compatible CLI and a plugin API that lets Windows applications drive containers directly. It has not been formally announced, but the code is public in microsoft/WSL, so everything here is grounded in what is already merged.<br>What wslc is<br>wslc ("WSL Containers") runs OCI-compatible Linux containers inside a dedicated Hyper-V VM, managed from Windows through a new binary: wslc.exe. The VM is separate from your regular WSL 2 distros.<br>The Windows side talks to the VM over Hyper-V sockets, multiplexed through a single channel. Messages like WSLC_FORK, WSLC_MOUNT, and WSLC_UNIX_CONNECT go in, and the init handler inside the VM dispatches them. The Docker Engine REST API is proxied the same way: WSLC_UNIX_CONNECT relays a Windows-side connection to /var/run/docker.sock in the guest.<br>The VM defaults are modest and configurable through the SDK:<br>2 vCPUs<br>2000 MB of RAM<br>32 GB dynamic VHDX<br>5 minute boot timeout<br>The CLI<br>The command surface will look familiar to anyone who has used Docker:<br>wslc run ubuntu:24.04<br>wslc container list<br>wslc pull postgres:16<br>wslc exec bash<br>wslc image list<br>wslc logs<br>wslc stop<br>wslc rm There are container, image, volume, session, and registry subgroups. wslc session shell drops you into the VM's init namespace for debugging. wslc run supports port publishing, environment variables, volume mounts, working directory, user, entrypoint, and command overrides. Recent work added --filter to image list and image prune (PR #40671) and --since, --until, and --timestamps to logs (PR #40667).<br>Bind mounting Windows folders<br>You mount a Windows folder into a container the way you would expect:<br>wslc run -v C:\Users\me\project:/workspace ubuntu:24.04Underneath, the path is validated, then shared into the VM through a privileged HCS AddShare call that returns a share GUID. The guest mounts it one of two ways: the legacy path uses Plan 9 (9p over an HV socket file descriptor), and the newer path uses virtiofs behind a feature flag. The virtiofs path reuses an existing share if the same Windows folder is already mounted with the same access mode, which avoids piling up devices on the host.<br>GPU support<br>wslc passes the GPU through via CDI (Container Device Interface) v0.6.0. At VM boot, the init handler writes a CDI spec for the WSL GPU device into /etc/cdi/microsoft.com-wslc.json and configures Docker to use it. The CDI kind is microsoft.com/wslc and the device identifier is microsoft.com/wslc=gpu, backed by /dev/dxg. The Windows GPU driver libraries are mounted in from the host and assembled with an overlay filesystem, the same approach WSLg uses. For ML work that needs a GPU inside a container, this runs on the same Windows GPU driver your desktop already uses.<br>Driving containers from Windows applications<br>The most interesting piece for Windows developers is the plugin API, added in PR #40521 and introduced in WSL 2.9.0. wslc extends the existing WSL plugin DLL interface with hooks and API calls specific to the container runtime.<br>A Windows application that loads a wslc plugin DLL receives lifecycle hooks:<br>OnSessionCreated and OnSessionStopping: the VM session lifecycle. An error from OnSessionCreated aborts the session.<br>ContainerStarted: fired after the container is actually running, with the full Docker inspect JSON. If the hook returns an error, wslc stops the container and propagates the failure.<br>ContainerStopping: fired before a container stops.<br>ImageCreated: fired when an image is pulled or imported (not on local build or load).<br>ImageDeleted: fired when an image is removed.<br>The plugin also gets API calls it can make back into wslc:<br>WSLCMountFolder: mount a Windows folder into the session VM on demand, returns the Linux mount point.<br>WSLCUnmountFolder: unmount it.<br>WSLCCreateProcess: start a process in the VM's root namespace with full argument and environment control.<br>WSLCProcessGetFd: get stdin, stdout, or stderr back as a Windows HANDLE.<br>WSLCProcessGetExitEvent: a Windows event HANDLE signaled when the process exits.<br>WSLCProcessGetExitCode and WSLCReleaseProcess: read the exit code and clean up.<br>Put together, a Windows application can mount its own folders into the container VM, spawn processes there and wire their I/O straight to Windows handles, and react to container lifecycle events as native Windows events. An IDE that brings up a build container when you open a project, streams its output to a terminal pane, and tears the workspace down when you close the project is exactly the kind of integration this is built for.<br>The SDK<br>wslc ships a public C API (wslcsdk.dll), a WinRT projection, and C# bindings. Applications can manage containers programmatically: pull images,...