Skip to content

Repository files navigation

yos

A host-side FreeBSD-libc emulator for wasm32 programs.

Userspace, unchained.

License: BSL 1.1 Guest ABI: FreeBSD libc / wasm32 Hosts

Important

yos has been merged into yetty. Development continues in the yos/ subtree of the yetty repository; this repository is an archive. Please file issues and pull requests against zokrezyl/yetty.

yos runs unmodified wasm32 binaries — built against FreeBSD libc headers — on Linux, macOS / iOS / tvOS, FreeBSD, and Windows. The wasm guest only ever sees a FreeBSD-shaped userspace; yos translates each libc call into the host's native libc on the way through. One wasm binary, every platform, no kernel ABI dragged along for the ride.


yetty — terminal unchained

yos was built for yetty — the terminal, unchained.

yetty is a GPU-accelerated terminal and rich-content runtime: it renders plots, images, diagrams, documents, video, and GUI panels inline with your terminal text. yos is what lets yetty carry a real BSD userspace — an interactive shell, an editor, a box of tools — onto platforms where a terminal normally can't spawn one. On iOS and tvOS, apps may not make kernel calls or JIT native code; in the browser there is no process model at all. yos sidesteps both: every program is wasm32, every libc call is a host-side bridge, and the same zsh or nvim build drops into a yetty session on a phone, a TV, or a browser tab exactly as it does on the desktop.

Try yetty: curl -fsSL https://yetty.dev/install.sh | bash — see the yetty repo for Windows, docs, and the full rich-content story.


Why FreeBSD libc

One wasm binary should run across desktop, mobile, and embedded without recompilation, and without the Linux kernel ABI baked in. Targeting FreeBSD libc — not WASI, not musl, not Linux — buys us:

  • One ABI to compile against. The wasm binary embeds no host assumptions; every libc call is a wasm import on env.<name>.
  • A natural iOS / tvOS fit via libSystem, which shares FreeBSD libc's BSD heritage.
  • Clean licensing. The stack is wasm3 (MIT) + mimalloc (MIT) + FreeBSD libc headers (BSD-2-Clause) + the host's own libc. yos itself is BSL.

What runs today

The umbrella package (nix build .#all) ships the host yos runtime plus a working wasm userspace built against FreeBSD libc:

  • zsh 5.9 — interactive shell, scripting, pipes, command substitution, fork + exec.
  • neovim 0.10.4 — full TUI, runtime tree, plugin loader.
  • FreeBSD coreutilscat, echo, mkdir, ln, head, id, kill, realpath, test, touch, uniq, basename, and more run cleanly; a second batch (awk, grep, sed, sort, wc, …) builds and is being brought up.

Every tool lives as a bare wasm module in result/libexec/<name> that yos's exec bridge loads directly. Per-tool runtime status — including the known gaps and their root causes — is pinned by the test suite under tests/integration/; a flipped xfail there is a real regression-net win.

Quick start

nix build .#all                # yos + zsh + nvim + tools
nix run   .#                   # sandboxed wasm-zsh under yos, host PATH stripped

./tools/yos.sh                 # interactive zsh
./tools/yos.sh nvim file.txt   # any wasm tool, passthrough args
./tools/yos.sh -c 'echo hi'    # one-shot zsh

How yos resolves a libc call

Every libc function the guest imports goes through a 3-tier ladder; yos picks the lowest tier that yields FreeBSD-correct behaviour:

  1. Host-libc passthrough. A bridge translates wasm pointers, calls the host's libc of the same name, returns. Covers most pure / stateless functions — strlen, memcpy, read, sin, qsort, …
  2. FreeBSD source compiled to wasm32. For functions whose host equivalent has the wrong shape (variadic printf, locale internals), yos compiles the FreeBSD libc source to wasm and dispatches to a sidecar wasm3 instance.
  3. Hand-written. State-bound operations — fork, execve, waitpid, pthread_create, mmap / brk, the fd table — live in C under src/yos/impl/.

Tier-1 bridges are autogenerated from the FreeBSD libc headers: libclang walks both the guest's FreeBSD-i386 headers and the host's, emits structured YAML deltas (widen / narrow / struct-convert / pointer-descent), and the generator emits one bridge per function. Adding a libc call is usually a header-only change.

  wasm guest                 yos bridge                    backend
  (FreeBSD libc,   ──▶   yos_brg_<name>:            ┌─▶  host libc
   wasm32 imports         pop wasm args,            │    (glibc / libSystem /
   on env.<name>)         translate offsets,        │     FreeBSD libc)
                          convert layout, remap ────┤
                          errno                     └─▶  yos subsystem
                                                         (mem / proc / pthread / vfs)

For the deeper "what's autogenerated, what's hand-written, why, and how the Nix packaging fits" picture, see docs/design.md.

Building it yourself

The Nix flake is the canonical build interface:

nix build .#yos              # host runtime
nix build .#sysroot          # wasm32 sysroot
nix build .#toolchain        # wasm-clang + wasm-ld + wasm-opt
nix build .#zsh .#nvim       # individual wasm ports
nix build .#all              # umbrella: yos + every wasm port

Without Nix (Linux dev):

meson setup build-linux && ninja -C build-linux
meson test -C build-linux            # integration suite

On Windows the host runtime builds with MSVC — no Nix, no MinGW:

build-tools\windows\build.bat
tools\yos.cmd path\to\guest.wasm

Repo layout

Path Role
src/yos/ host runtime — main.c, hand-written subsystems in impl/, codegen/
build-tools/ FreeBSD source, wasm toolchain shim, vendored wasm3 + mimalloc, per-package recipes
nixpkgs/ Nix package tree — host runtime, sysroot, toolchain, per-tool derivations
tests/integration/ end-to-end pty + scripted tests against real wasm guests
tools/ convenience launchers (yos.sh, wasm-pkg.sh)
flake.nix single source of truth for Nix outputs

Status

yos's host runtime builds cleanly on Linux, macOS, FreeBSD, and Windows (MSVC). zsh, nvim, and the coreutils batch ship in the umbrella; remaining gaps are tracked next to the xfail entries in the test suite. Next up: bash 5, FreeBSD bin/sh, and the harder coreutils (ls, mv, cp).

Licence

BSL. See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages