An exploration in embedded Linux

Embedded Linux — without tears

A set of experiments in what the next-generation embedded Linux build system could look like: native builds, modern languages first-class, AI that understands the system, one tool from laptop to production. Pre-1.0 and rough around the edges — we're sharing the work as it takes shape.

Goals

What we're aiming for.

[yoe] next-gen is a vendor-neutral project, built in the open to help small teams do big things. Small teams and startups don't have an enterprise's problems at smaller scale — they have different problems, and we build for those. Three north stars guide the experiment — everything else is in service of these.

01 / Productivity

Drastically improve developer productivity

Shrink the loop between an idea and a running image. Fewer rebuilds, fewer context switches, fewer tools to learn — so engineers spend their time on the product, not on the build.

02 / Integrate

Easily integrate complex workloads

Modern edge devices ship Go services, Rust agents, Python ML, container workloads, and kernel drivers side by side. Pulling these together should be straightforward, not a custom integration project each time.

03 / Scale

Scale to build anything

From tiny Zephyr images to complex AI workloads. From one application to a complete distributed system — one tool, one mental model, with caching that keeps up as projects grow.

The status quo

The existing systems have served us well …

With all due respect for the past and those who built Yocto, Buildroot, and other build systems — these are remarkable tools. They have enabled us to build and ship real products, and they solve a real problem. However, these tools were designed for an era of slow ARM hardware, scarce CI, and frozen SDKs. They still work, but they're increasingly bumping up against the demands of today's edge products.

Cross-compilation friction

Sysroot management, host contamination, mismatched pkg-config — time better spent shipping features.

SDK drift

OS team builds an SDK. App team uses it. Six months later, version mismatches between teams turn into a long debugging session.

Stack traces from generated shell

A failure ten layers deep in machine-generated bash, and the actual fix lives elsewhere in the recipe tree.

Modern languages deserve first-class support

Go, Rust, and Python wheels are where most edge application work happens today — they belong at the center of the build, not bolted on.

Full rebuild for a small change

Tweak a kernel config or bump a single package, and the build wants to start over from scratch. Most edits should be incremental — minutes, not hours.

Updates feel like a risk event

Modern edge devices stay connected and need security patches across their lifetime. Bumping a package or following upstream should be routine, not a dedicated engineering effort.

What we're exploring

One tool. Every layer. Built natively.

We're prototyping [yoe] as a single unified tool that builds every layer — kernel, root filesystem, and applications — natively on the target architecture, with no cross-compilation toolchain and no SDK handoff. One engine, three ways to drive it: a traditional CLI, an interactive TUI, and an AI assistant. Pieces work today; pieces are still on the bench.

01 / Native

No cross-compilation

Build ARM and RISC-V on a Mac, on real hardware, or in cloud CI. QEMU user-mode emulation transparently runs foreign-arch containers — same tool, native pipeline, no extra toolchain setup.

02 / Languages

Cargo, Go modules, pip — as-is

Modern languages already solved dependency resolution, caching, and reproducibility. [yoe] uses what they ship instead of reinventing it. Even pre-built PyPI wheels just work.

03 / AI

AI as a first-class interface

Starlark units, queryable dependency graphs, structured logs. An assistant can create units from a URL, diagnose a failed build, audit CVEs, and trace why a package is in your image.

04 / No SDK

Same tool, system to app

System engineers and application developers run the same tool against the same config. New hire clones the repo, types yoe, ships.

05 / Cache

Cached at the unit level

Every unit produces a content-addressed package — apk or deb. Most developers never rebuild — they pull. Local, team, and global cache layers, no global lock.

06 / Sandboxed

Per-unit container, bwrap-isolated

Each unit runs in its own Docker container with a bubblewrap sandbox. Toolchain pinning per-unit/task; no host pollution; no leaks between build units.

07 / Distros

Alpine, Debian, or Ubuntu — per image

Pick the base the workload needs, image by image. Alpine keeps things small and musl-clean; Debian and Ubuntu bring glibc, systemd, and a far larger catalog. One project builds all three side by side.

Try it

Give it a try.

All you need is one self-contained tool, Docker, and Git. No global state, no hidden caches, no SDK to install. The first build assembles a Docker toolchain container, fetches default unit modules, and produces a bootable QEMU image. Expect rough edges — this is an experiment, and we'd love to hear what breaks.

For ARM64, register QEMU user-mode once with yoe container binfmt, then add --machine qemu-arm64. The build runs inside a real ARM64 container, transparently emulated by your host kernel.

Full quickstart →

~/yoe-test  ·  bash
# Download the binary (Linux x86_64)
curl -L https://github.com/yoebuild/yoe/releases/latest/download/yoe-Linux-x86_64 -o yoe
chmod +x yoe && mv yoe ~/bin/

# Create a project, build, run
yoe init yoe-test
cd yoe-test
yoe build base-image
yoe run base-image
Why now

The pieces finally lined up.

A decade ago, this combination wasn't realistic. Three things have changed.

Hardware

ARM & RISC-V build at full speed

Modern dev boards and cloud instances (AWS Graviton, Hetzner CAX) run native arm64 builds at full clock. QEMU user-mode covers the rest. Native builds are now practical for nearly every target, opening the door to a simpler design.

Ecosystems

Languages bring their own tools

Cargo, Go modules, pip, npm, Zig — they already handle resolution, caching, lockfiles, and reproducibility. A modern build system should compose with these, not reimplement them.

AI

An assistant can carry the load

The hardest part of embedded Linux isn't writing recipes — it's knowing which knobs to turn and why. Structured Starlark and a queryable graph let an AI do the legwork, so developers can stay focused on the product instead of holding the whole build system in their head.

Build the future of embedded Linux

We're testing whether ARM, RISC-V, and x86 can share one tool — without a cross-compile dance, an SDK handoff, or a rebuild on every config change. Pre-1.0, plenty unfinished. Try it on a board you care about and tell us what you find.

If any of this resonates, come think it through with us.

Sponsors

[yoe] is supported by

Interested in supporting the project? Get in touch →

Questions, ideas, or things that broke?

We'd like to hear from you — about a board you're targeting, a unit that won't build, or an idea worth trying.