How I Do Web Development (Astro, NextJS, etc.) On FreeBSD

Written by: Donovan / Last updated: Jul 9, 2025

I’ve been using FreeBSD as my daily driver for over 10 years.

In fact, I’ve been continuously running the same OS on the same drive non-stop. Never once removed FreeBSD or reinstalled it. I just install major and minor updates when they become available.

Even when I did a complete hardware upgrade and replaced the entire system, I kept my FreeBSD drive as is.

Needless to say, I’m loyal to FreeBSD. ๐Ÿ˜Š

Problem is: I’m also a web developer. I use modern frameworks like Astro, NextJS and Sveltekit.

FreeBSD web development

You can’t natively develop using these tools anymore on FreeBSD. There’s just not enough interest there in the community to bother making the dependencies compatible.

So what do you do?

You need to cheat and use Linux. Inside FreeBSD.

How to install a Linux web development environment inside FreeBSD

1. Go ahead and setup bhyve (I’ll assume you’re using ZFS like I am):

doas pkg install vm-bhyve grub2-bhyve bhyve-firmware

2. Set up VM directory and environment

sudo mkdir -p /vm
sudo zfs create -o mountpoint=/vm zroot/vm
sudo vm init

3. Download Linux ISO (I use Debian for this)

cd /vm
fetch https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.5.0-amd64-netinst.iso 

4. Create and configure Linux/Debian VM

sudo vm create debian
sudo nano /vm/debian/vm.conf

Then paste this into the vm.conf file:

loader="grub"
cpu=2
memory=16G
disk0_type="virtio-blk"
disk0_name="disk0.img"
disk0_size="20G"
network0_type="virtio-net"
network0_switch="nat"
grub_run-partition="1"
grub_run_dir="/boot/grub"

5. Create private NAT switch (this is so you have network/Internet access)

doas vm switch create -t standard nat

Bring it up:

doas ifconfig vm-nat inet 10.0.0.1/24 up

6. Configure PF NAT workaround for wireless Internet connections

IMPORTANT: If you are using wifi, you must do this step. It’s basically a workaround to route traffic through a firewall.

Edit /etc/pf.conf:

ext_if="wlan0"
nat on $ext_if from 10.0.0.0/24 to any -> ($ext_if)

pass out on $ext_if from any to any keep state

Save it and enable PF:

doas sysrc pf_enable="YES"
doas pfctl -f /etc/pf.conf

7. Install Linux from the ISO

doas vm install -f debian /vm/debian-12.5.0-amd64-netinst.iso
  • Proceed with install
  • Use guided partitioning
  • Install GRUB to /dev/vda
  • Skip network config for now or use manual
  • Finish install and reboot

8. Set a static IP in Linux

Connect to Linux using:

doas vm console deb

You’ll get a login prompt. Login and configure your network if you haven’t already:

ip addr add 10.0.0.2/24 dev enp0s1
ip link set enp0s1 up
ip route add default via 10.0.0.1
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf

Get SSH running while you’re at it:

sudo apt install openssh-server

9. You can now SSH into your Linux VM

ssh user@10.0.0.2

10. Create a script to start vm when you want to develop

I didn’t make mine persistent at boot. Just created a two line script to start the vm when I need to:

doas ifconfig vm-nat inet 10.0.0.1/24 up &&
doas vm start deb

I then run sshfs so I can mount the folder of my project over SSH:

sshfs donovan@10.0.0.2: /mnt/ssh

This is so I can open up images using Gimp and view my project folder in my graphical file manager if needed.

11. Make sure to create an SSH tunnel

If you just SSH into your Linux VM to develop, you’re probably going to run into issues when developing.

Parts of my app weren’t working due to CORS issues and so on, because I was connecting to my development server using 10.0.0.2:4321 instead of localhost:4321.

So create an SSH tunnel like so:

ssh -L 4321:localhost:4321 donovan@10.0.0.2

Now you can just run bun run dev or yarn dev or whatever, and connect to your project normally using localhost in your browser.


I think that’s it. I might have missed something here so let me know if I did.

But now you can see, I can continue using my FreeBSD machine with native bhyve running a Linux development environment for web/Node stuff.

Works perfectly.

Well why not just install Linux and forget FreeBSD you might ask?

Because I’m a winner, that’s why. ๐Ÿ˜„

View Archive