I mentioned during the call yesterday that I have a Roc app running on a unikernel.
Here are the components:
I also have my dog-park repo running on bare metal at https://dogpark.lynrummy.com/dogpark, but it's not a great example, since 95% of the app is client-side, so it's just Roc running in your browser, so nothing too exciting there. (As an aside, it also runs in roc-ray.)
Most people have no reason to ever run Roc on a unikernel, and that includes me to some degree, but if you're still reading, you are probably at least intrigued by the possibility of doing it.
My pure-zig unikernel actually runs on a Digital Ocean droplet running a Linux hypervisor but no actual Linux distribution. It runs right on the metal, so I literally load a "base image" on to my droplet. I don't have any shell support in the unikernel, but you can use my programming language called Shale to run little programs to walk the file system--you do it by sending a signed version of the Shale script to a web endpoint. See #off topic > shale programming language for more details.
The nice about zig-webbox/roc-webbox is that you can run webbox apps on either Linux or the unikernel. The apps are extensively tested to make sure that they behave the same on Linux as in the unikernel. On Linux, you're using the real standard library zig I/O code. On the unikernel, you're using custom stacks for TCP and FAT.
The unikernel is mostly single-threaded, so all your web endpoints need to be quick-running on the single-CPU droplet. You can have up to 256 TCP connections, and you can set up small jobs to run between we requests.
Even in unikernel mode, you're still using the HTTP server from zig's standard library--it just swaps in the unikernel's own IO library.
The TODO app itself is just vanilla HTML/JS on the client. The server persists the TODO data to the file system as one JSON file per user.
All the code is written by Claude.
Here is the platform code:
## THE WEBBOX PLATFORM: a Roc app answers a web request, and its Zig host is
## a webbox site (src/roc_site.zig). The app provides `handle!`, which the
## host calls as `roc_handle` for each request it routes to Roc; the app's
## effects are hosted functions (File.roc), which the host performs as they
## are called, through webbox's store, the same on every webbox host.
platform ""
requires {
handle! : Http.Request => Http.Response
}
exposes [File, Http]
packages {}
provides { "roc_handle": handle_for_host! }
hosted {
"roc_file_read": File.read_raw!,
"roc_file_write": File.write_raw!,
"roc_file_delete": File.delete_raw!,
}
targets: {
x64musl: {
inputs: [app],
output: Archive,
},
x64v1elf: {
inputs: [app],
output: Archive,
},
wasm32: {
inputs: [app],
output: Archive,
},
}
import File
import Http
handle_for_host! : Http.Request => Http.Response
handle_for_host! = |request| handle!(request)
You can try the TODO app here: https://dogpark.lynrummy.com/todo/
It's the most vanilla TODO app in the world; the app itself isn't the point.
Dog Park is here: https://dogpark.lynrummy.com/
It's running on the same "bare metal", but it's mostly a client-side app, and the platform story is a little messier there. But it does demonstrate the unikernel can run multiple apps.
The one problem with my unikernel is that it's built in zig. The zig community totally excludes people from their community who choose to build with LLMs. So with everything that I build with zig, I'm kinda on my own.
This is amazing
So with everything that I build with zig, I'm kinda on my own.
Is it about questions regarding Zig or OS dev? Or design advice? Or project contributions?
Zak Kohler said:
This is amazing
Thanks, Zak! I would love for folks to play around with it. It's all the power of Claude. :)
15 messages were moved from this topic to #show and tell > roc on a unikernel (venting about LLM policies) by Steve Howell.
TIL about unikernel. Sounds really cool, great you got it working as a platform!
Last updated: Nov 04 2026 at 18:54 UTC