Back to blog
Jan 05, 2026
5 min read

Linuxulator on FreeBSD Feels Like Magic

Most linux software just work on FreeBSD

For the past few years, my editor of choice has been Visual Studio Code. It’s not perfect and definitely not lightweight, but it strikes a sweet spot between features, extensions, and performance.

Running the proprietary Microsoft build on FreeBSD isn’t really an option but thankfully, the open-source build works just fine. So why write this post at all if VS Code already works?

Because there’s one thing that’s been holding me back from fully daily-driving FreeBSD:

ARM64, or nothing

I need an ARM64 machine. Period.

After spending time on Apple’s M1/M2 Macs (coming from a large x86_64 desktop), going back to x86_64 feels like a regression, both in performance and battery life. Unfortunately, there’s currently no FreeBSD-supported (or even Linux, as far as I can tell) ARM64 laptop that truly rivals Apple Silicon. I really hope Framework or someone else changes that in the coming years.

The productivity killer for me: remote dev

On both Debian (my favorite Linux distro) and macOS, VS Code is a great experience. But most of the projects I work on live elsewhere: embedded Linux systems, OpenWRT devices, and more recently, FreeBSD boxes.

That usually means NFS mounts, SSHFS, or similar setups. And honestly? They’re awful.

My current go-to stack is SvelteKit with a Go backend, and my day job involves a lot of OpenWRT work. As projects grow, editing code over NFS or SSHFS becomes painful especially with many LSPs running. In some cases, it took 5–10 minutes just to open a file. NFS was slightly more tolerable, but after running into countless weird permission issues, I gave up on it entirely.

At that point, it had become a real blocker to my productivity.

Enter VS Code Remote SSH

Over the last couple of days, I started experimenting with VS Code’s Remote SSH extension. It’s officially supported on most major operating systems but notably not on OpenWRT (musl-based) or FreeBSD.

I tried it on OpenWRT anyway.

And to my surprise… it worked out of the box.

I could connect over SSH, edit files directly on the device, and everything felt smooth. Performance was far better than expected. No hacks. No drama. It honestly felt like magic, working directly on the target device as if it were local.

Naturally, I tried FreeBSD next

I’m currently working on a fairly large FreeBSD-centric project, Sylve. Managing it over SSHFS/NFS has been a nightmare due to the sheer number of files and directories.

So, without reading much about compatibility or support, I decided to try Remote SSH on FreeBSD as well.

Predictably, I hit this:

Unsupported platform: FreeBSD

Fair enough.

But before giving up, I did a bit of searching and that’s when I stumbled upon this excellent repository: https://github.com/morganwdavis/vscode-server-freebsd

The setup was almost laughably simple. In fact, I had already done most of it while initially configuring FreeBSD:

service linux enable # This enables the Linuxulator emulation layer
service linux start
pkg install linux_base-rl9 # Install a Linux base system (Rocky 9 in this case)

The Linux-specific PATH does not go into the global environment or .zshrc. Instead, I placed it in a separate file, .bash_linux, in my home directory:

PATH="/compat/linux/usr/local/sbin:/compat/linux/usr/local/bin:/compat/linux/usr/sbin:/compat/linux/usr/bin:/compat/linux/sbin:/compat/linux/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

This file is only sourced when VS Code connects over SSH via the Linuxulator. That’s achieved by explicitly telling sshd to accept the BASH_ENV variable:

sysrc sshd_flags="-o AcceptEnv=BASH_ENV"

And then setting it from the client-side SSH config:

SetEnv BASH_ENV=".bash_linux"

After everything was set up, my final SSH config for the FreeBSD box looked like this (on the macOS client):

Host sylve-code
    Hostname 192.168.72.172
    SetEnv BASH_ENV=".bash_linux"
    User root
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
    ServerAliveInterval 60
    ServerAliveCountMax 3
    RemoteCommand /compat/linux/bin/bash

And then… it just worked

I was honestly skeptical. I expected half my extensions to break, language servers to crash, or performance to be mediocre at best.

None of that happened.

Every extension I rely on worked flawlessly except Rollup, which doesn’t ship FreeBSD binaries. But even that wasn’t a blocker: it does have a WASM build, so I simply overrode the dependency in npm:

{
  "overrides": {
    "rollup": "npm:@rollup/wasm-node@^4.30.1"
  }
}

Problem solved.

Final thoughts

The result? A fast, smooth, fully-featured remote development experience on FreeBSD running Linux binaries transparently via the Linuxulator.

It genuinely feels like magic.

More importantly, it’s a testament to how stable the Linux ABI itself is and how well FreeBSD’s Linuxulator implements it. This setup completely changed how I work with FreeBSD, and it finally removed one of the biggest friction points in my workflow.

I’m seriously impressed and genuinely excited to see how far this can go. This is one of those rare setups that feels fragile on paper but in practice, it just works.