<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>[yoe] - Blog</title>
    <subtitle>An exploration of a different approach to embedded Linux builds — native builds, language-native package managers, AI as a first-class interface. A set of experiments in progress, not a finished product.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://yoebuild.org/blog/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-06-11T00:00:00+00:00</updated>
    <id>https://yoebuild.org/blog/atom.xml</id>
    <entry xml:lang="en">
        <title>AI in the Build Loop [yoe]</title>
        <published>2026-06-11T00:00:00+00:00</published>
        <updated>2026-06-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/ai-integration/"/>
        <id>https://yoebuild.org/blog/ai-integration/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/ai-integration/">&lt;p&gt;A build system is a lot of small pieces — feeds, units, dependencies, task
steps, sandboxes. None of it is hard on its own. The hard part is holding all of
it in your head at once, which is exactly what humans are bad at and agents are
good at. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;nfG_UTerYeo&quot;&gt;latest video&lt;&#x2F;a&gt; shows how &lt;code&gt;[yoe]&lt;&#x2F;code&gt; uses
that: it ships Claude Code skills you install into your project, and wires a
diagnose step into the build loop.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;two-ways-to-install-the-skills&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#two-ways-to-install-the-skills&quot; aria-label=&quot;Permalink to this section&quot;&gt;Two ways to install the skills&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;ai-skills.html&quot;&gt;AI skills page&lt;&#x2F;a&gt; covers both
paths.&lt;&#x2F;p&gt;
&lt;p&gt;Run &lt;code&gt;yoe skills install&lt;&#x2F;code&gt; inside your project and it drops the skills into your
&lt;code&gt;.claude&#x2F;&lt;&#x2F;code&gt; folder. &lt;code&gt;yoe init&lt;&#x2F;code&gt; now does this by default. Keeping them local lets
you list, update, and diff them against your own edits. Note that &lt;code&gt;update&lt;&#x2F;code&gt;
overwrites, so rename a skill first if you’ve customized it.&lt;&#x2F;p&gt;
&lt;p&gt;The other path is the Claude Code plugin marketplace: add the &lt;code&gt;[yoe]&lt;&#x2F;code&gt;
marketplace, reload, and skills like &lt;code&gt;diagnose&lt;&#x2F;code&gt; and &lt;code&gt;new-unit&lt;&#x2F;code&gt; show up as
plugins.&lt;&#x2F;p&gt;
&lt;p&gt;Several skills ship in the set. Many are still ideas, but &lt;code&gt;diagnose&lt;&#x2F;code&gt; and
&lt;code&gt;new-unit&lt;&#x2F;code&gt; are in daily use, and the rest will fill in over time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;press-d-to-diagnose&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#press-d-to-diagnose&quot; aria-label=&quot;Permalink to this section&quot;&gt;Press &lt;code&gt;d&lt;&#x2F;code&gt; to diagnose&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The demo: add a bad &lt;code&gt;echo make error&lt;&#x2F;code&gt; task step to the &lt;code&gt;ca-certificates&lt;&#x2F;code&gt; unit.
&lt;code&gt;[yoe]&lt;&#x2F;code&gt; sees the unit is no longer cached, rebuilds it, and the build fails on
the first step. You could shell out and hunt for the problem yourself. Instead,
press &lt;strong&gt;&lt;code&gt;d&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;That runs the &lt;code&gt;diagnose&lt;&#x2F;code&gt; skill and hands it the build log, so the agent starts
from the evidence instead of searching for it. It reads the log, finds the bad
line, removes it from the unit, and the rebuild succeeds — all without leaving
the &lt;code&gt;[yoe]&lt;&#x2F;code&gt; terminal UI.&lt;&#x2F;p&gt;
&lt;p&gt;You can also run it from a Claude session: say “diagnose the unit that fails to
build” and get the same result. The TUI path keeps you in the build loop; the
Claude path keeps your agent and build side by side. Either way, the agent gets
the log instead of guessing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s next&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This is a trivial example on purpose — a one-line error, a one-line fix. The
point is the wiring, not the bug. The same pattern reaches harder problems as
the skills mature: porting BSPs from Yocto, expanding &lt;code&gt;new-unit&lt;&#x2F;code&gt;, and pulling
units across from Alpine, Debian, and other systems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;get-involved&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#get-involved&quot; aria-label=&quot;Permalink to this section&quot;&gt;Get involved&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The full set of walkthroughs is on the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt;. A few ways to go further:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Try a build&lt;&#x2F;strong&gt; — the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;&quot;&gt;Getting Started guide&lt;&#x2F;a&gt;
covers install and your first image.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Star and watch the repo&lt;&#x2F;strong&gt; — star it and click Watch to follow progress on
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;yoebuild&#x2F;yoe&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Subscribe to the newsletter&lt;&#x2F;strong&gt; — occasional progress notes; the email signup
is at the foot of every page on &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;&quot;&gt;yoebuild.org&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Add a machine or image&lt;&#x2F;strong&gt; — the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;ai-skills.html&quot;&gt;&lt;code&gt;&#x2F;new-machine&lt;&#x2F;code&gt; and &lt;code&gt;&#x2F;new-module&lt;&#x2F;code&gt; AI skills&lt;&#x2F;a&gt;
scaffold support for new boards and distros.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Open a discussion&lt;&#x2F;strong&gt; — questions, ideas, or a board you’d like ported next go
in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;GitHub Discussions&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Send a note&lt;&#x2F;strong&gt; — reach the team at
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20video%20feedback&quot;&gt;info@yoebuild.org&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Is It Time for a New Embedded Linux Build System?</title>
        <published>2026-06-11T00:00:00+00:00</published>
        <updated>2026-06-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/time-for-a-new-build-system/"/>
        <id>https://yoebuild.org/blog/time-for-a-new-build-system/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/time-for-a-new-build-system/">&lt;p&gt;I’ve been building products using embedded Linux for the past 20 years. The
first time I tried OpenEmbedded (the precursor to Yocto), it felt like a gift to
be able to run a single command and build a bootable ARM image from my x86
workstation. But things are changing. We have more and more components (both
hardware and software) available. We have AI tools. We have powerful processors
with loads of memory. Small teams (startups and industrial companies building
small&#x2F;medium volume connected products) want to do bigger things, yet they
struggle with the complexity of stitching it all together, miss their shipping
dates, and strain to maintain these systems once they’re in the field. This
article explores what has changed, and how we can build and maintain embedded
Linux systems more efficiently.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-embedded-systems-golden-age&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-embedded-systems-golden-age&quot; aria-label=&quot;Permalink to this section&quot;&gt;The Embedded Systems Golden Age&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;We live in a remarkable time for embedded systems engineering. We have:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A large number of Linux system-on-modules (SOMs), perfect hardware building
blocks for industrial products.&lt;&#x2F;li&gt;
&lt;li&gt;Zephyr, an excellent OS for building software on MCU platforms.&lt;&#x2F;li&gt;
&lt;li&gt;Mature tools (compilers, build systems, etc.).&lt;&#x2F;li&gt;
&lt;li&gt;A vast array of open source software we can apply to these systems.&lt;&#x2F;li&gt;
&lt;li&gt;Fast, reasonably priced prototyping (PCB assembly, mechanical 3D printing,
etc.).&lt;&#x2F;li&gt;
&lt;li&gt;More vendors upstreaming their Linux kernel support.&lt;&#x2F;li&gt;
&lt;li&gt;Yocto’s solid tooling for building images and custom parts of the system.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And all of this is available to companies of any size. It’s a bit like
inheriting a mansion: open source has handed us a sprawling house full of rooms
and features we’d never have built ourselves, and we have to live in it to stay
competitive. The catch is that nobody handed us the tools to keep the place
running. There is nothing holding us back, except our ability to put it all
together.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-embedded-linux-systems-are-currently-built&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#how-embedded-linux-systems-are-currently-built&quot; aria-label=&quot;Permalink to this section&quot;&gt;How Embedded Linux Systems are currently built&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Embedded Linux build systems solve the problem of putting all the pieces
together, and the existing ones have served us well. Buildroot (2001) and
OpenEmbedded&#x2F;Yocto (2003) are now the standard, supported by most SOC&#x2F;SOM
vendors, and some teams ship successfully on Debian, Ubuntu, or even Arch (as
Valve does with the Steam Deck).&lt;&#x2F;p&gt;
&lt;p&gt;The shape of mainstream embedded Linux development has held remarkably steady
for ~20 years: cross-compile on a powerful x86 workstation, assemble a BSP
(board support package), freeze an SDK (software development kit), ship the
image, and hold that line for years. It’s a model built for a static,
single-purpose, rarely updated product, and until recently, for that product, it
worked well.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-things-are-changing&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#but-things-are-changing&quot; aria-label=&quot;Permalink to this section&quot;&gt;But things are changing …&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The products have changed more than the tools that build them. Edge devices have
started behaving like cloud systems. They run containers, pull OTA (over the
air) updates, stream telemetry, and are managed remotely over their entire life.
A device is no longer a static artifact you flash once and forget; it’s a system
that keeps moving forward after it ships. That inverts the old release cadence:
instead of freezing an SDK and holding it for years, teams track upstream
continuously and push updates as a matter of course. The long LTS (long-term
support) freeze that the cross-compile model was built around no longer fits a
new class of products.&lt;&#x2F;p&gt;
&lt;p&gt;At the same time, the software itself has outgrown the cross-compile model.
Modern languages each ship their own package ecosystem: Python (wrapping
C&#x2F;C++&#x2F;CUDA via NumPy and PyTorch), JavaScript (linking to C libraries), Go,
Rust, and vcpkg (for C&#x2F;C++). Most of it is written for desktop&#x2F;server, not
cross-compilation. That puts the cross-compile burden squarely on embedded
developers, and maintaining recipes for thousands of packages has been a steady
drain on the Yocto community. Yocto compounds this by blocking network access
during the build, so language package tooling doesn’t work without complex
&lt;code&gt;do_fetch&lt;&#x2F;code&gt; integration. That’s useful when you must control every source, but
unnecessary friction for many projects.&lt;&#x2F;p&gt;
&lt;p&gt;Each of these solutions trades one problem for another. Building everything from
source in Yocto means long builds, heavy memory use, and powerful workstations.
A stock binary distro like Debian starts development faster but lacks the
tooling to integrate the custom parts. And vendor BSPs frozen on a 4-year-old
Yocto make it hard to integrate modern software at all.&lt;&#x2F;p&gt;
&lt;p&gt;We could go on, but the cause is structural. Talented teams working hard still
hit this, because the problem is inherently difficult and the software keeps
getting harder to build.&lt;&#x2F;p&gt;
&lt;p&gt;To summarize, three things have changed:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Products never stop moving.&lt;&#x2F;strong&gt; Edge devices now behave like cloud systems:
continuous OTA updates, not a multi-year freeze.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Software outgrew cross-compilation.&lt;&#x2F;strong&gt; Every modern language brings its own
package ecosystem that doesn’t always cross-compile cleanly.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The old tradeoffs got sharper.&lt;&#x2F;strong&gt; Build-from-source is slow and heavy; stock
distros lack custom tooling; BSPs freeze you in time.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The old model is good. The real question is whether it still fits the product
you’re building and the team you have.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;small-teams-have-different-problems-not-smaller-ones&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#small-teams-have-different-problems-not-smaller-ones&quot; aria-label=&quot;Permalink to this section&quot;&gt;Small teams have different problems, not smaller ones&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I’ve been talking to a lot of people building products, and keep hearing a
consistent message. First, the ground has shifted: both the products and the way
we have to put them together. Second, what works for a big team doesn’t always
work for a small one.&lt;&#x2F;p&gt;
&lt;p&gt;Small teams and startups need to build and ship. They often don’t have the
resources to sustain multi-year development cycles. They don’t have dedicated
build or platform engineers experienced in creating complex build infrastructure
and debugging hard build problems. Simplicity and ease of build&#x2F;deployment often
matter more than binary-reproducible builds or building everything from scratch.
Easily deploying the latest open-source releases is frequently required to
leverage new technologies.&lt;&#x2F;p&gt;
&lt;p&gt;These teams are often hampered by three things: vendor BSPs that lock them into
old versions of Yocto, frustrating debug cycles where a critical component won’t
build, and the heavy effort of back-porting needed components into a system
frozen in time. A large organization can hire dedicated experts and throw
resources at these problems. A small organization does not have this luxury.&lt;&#x2F;p&gt;
&lt;p&gt;To be clear, small != hobbyist. These are often startups or industrial products
produced at moderate scale (100’s to 1000’s of units) that sit between the
one-off maker projects and consumer scale mass production.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-new-opportunity&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-new-opportunity&quot; aria-label=&quot;Permalink to this section&quot;&gt;The new opportunity&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Buildroot and OpenEmbedded were created in an era when ARM-based computers were
slow, and cross-compiling software on powerful x86 workstations was the only
practical option. When we were building a limited set of C&#x2F;C++-based
applications, these systems worked great. However, several things have changed
in recent times:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Application development is moving to modern languages (Python, JS, Go, Rust,
Zig). These languages have their own package ecosystems, caching, etc.&lt;&#x2F;li&gt;
&lt;li&gt;The hardware story has flipped. We now have fast ARM computers (AWS Graviton,
Hetzner CAX) available for building and are no longer constrained to x86
workstations.&lt;&#x2F;li&gt;
&lt;li&gt;AI has emerged as a powerful tool for creating software, including build
systems.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We need to leverage these change agents and rethink the world of connected
products. The key shift is this: stop borrowing only the &lt;em&gt;technology&lt;&#x2F;em&gt; of modern
ecosystems, and start borrowing their &lt;em&gt;process&lt;&#x2F;em&gt; too. When we adopt Rust or
Python and take the language but force it into the old build process, it’s a bit
like running a train on a paved road. The win comes from adopting how those
ecosystems build, package, and cache, not just what they produce.&lt;&#x2F;p&gt;
&lt;p&gt;We now have an opportunity to rethink embedded Linux build systems. For me, this
got personal. It hit me recently — if I’m going to keep doing this for another
20 years, I want something different, something that better fits the problems my
customers and I are actually trying to solve, instead of fighting the tools.&lt;&#x2F;p&gt;
&lt;p&gt;So I’ve been experimenting. Over the past couple of months I’ve been building
real pieces of this in the open, and the early results have been encouraging:
software that used to mean a day of fighting cross-compilation now goes from
idea to running on target hardware in minutes, using the same tooling on my
laptop and in CI. It’s rough and early, but it’s enough to convince me this
approach is worth pursuing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-if&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-if&quot; aria-label=&quot;Permalink to this section&quot;&gt;What if …&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;… we could:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Get to market faster.&lt;&#x2F;strong&gt; Shorten the path from idea to a working product.
&lt;ul&gt;
&lt;li&gt;Takes an idea to running on target hardware in seconds to minutes, not days
or weeks.&lt;&#x2F;li&gt;
&lt;li&gt;Doesn’t require cross-compilation.&lt;&#x2F;li&gt;
&lt;li&gt;Leverages modern language ecosystems (Python, JavaScript, Rust, Go, Zig,
pkgbuild, etc.).&lt;&#x2F;li&gt;
&lt;li&gt;Caches builds so no piece of software is built twice.&lt;&#x2F;li&gt;
&lt;li&gt;Provides the convenience of pre-built packages from mainstream distributions
with the tooling benefits of Yocto.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Do more with a small team.&lt;&#x2F;strong&gt; One toolset the whole team (and AI) can use, so
you don’t need dedicated build specialists.
&lt;ul&gt;
&lt;li&gt;Provides one build system for applications and system software: the same
tooling on laptop, cloud CI, and build farms.&lt;&#x2F;li&gt;
&lt;li&gt;Is easy for humans and AI to understand.&lt;&#x2F;li&gt;
&lt;li&gt;Includes tooling that works well with AI agents.&lt;&#x2F;li&gt;
&lt;li&gt;Leverages AI to do most of the low-level work.&lt;&#x2F;li&gt;
&lt;li&gt;Provides error messages that clearly point to the problem.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Keep products current and supportable in the field.&lt;&#x2F;strong&gt; Stay on modern
software and maintain devices over their whole life.
&lt;ul&gt;
&lt;li&gt;Tracks current software versions easily, without being held back by vendor
BSPs.&lt;&#x2F;li&gt;
&lt;li&gt;Scales from system to application to CI with consistent tooling throughout.&lt;&#x2F;li&gt;
&lt;li&gt;Deploys updates to fielded devices easily.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(These problems seem universal, but they hit small teams disproportionately
hard, since those teams rarely have dedicated resources to solve them.)&lt;&#x2F;p&gt;
&lt;p&gt;This is what I am experimenting with in this
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;&quot;&gt;next-generation Embedded Linux build system&lt;&#x2F;a&gt;. A few
examples of how this tool makes development easier:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;first-walkthrough-videos&#x2F;&quot;&gt;Alpine&lt;&#x2F;a&gt;,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;adding-debian&#x2F;&quot;&gt;Debian&lt;&#x2F;a&gt;, and
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;adding-ubuntu&#x2F;&quot;&gt;Ubuntu&lt;&#x2F;a&gt; are all supported base
distributions that get us going quickly without rebuilding the world.&lt;&#x2F;li&gt;
&lt;li&gt;Integrate
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;pip-and-npm-on-the-target&#x2F;&quot;&gt;Python and JavaScript&lt;&#x2F;a&gt;
native package ecosystems instead of fighting them.&lt;&#x2F;li&gt;
&lt;li&gt;First-class &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;ai-integration&#x2F;&quot;&gt;AI support&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;why-a-tui&#x2F;&quot;&gt;terminal user interface (TUI)&lt;&#x2F;a&gt; is
fast, and allows us to easily monitor what is going on and drill down into
detailed information as needed.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A few key features are still missing, such as distributed caching and remote
build runners, but these are coming soon.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-old-models-still-have-their-place&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-old-models-still-have-their-place&quot; aria-label=&quot;Permalink to this section&quot;&gt;The old models still have their place&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;None of this means the old models are going away, or should. For deeply embedded
regulated products (compliance-certified, bit-reproducible, built entirely from
source, and intentionally frozen for years), Yocto is battle-tested and remains
the right tool. It does exactly what those products need, and it does it well.&lt;&#x2F;p&gt;
&lt;p&gt;We’ve seen this pattern before. Alpine Linux didn’t replace Debian. It answered
a different need: minimal, container-friendly images. Both distributions still
ship today, serving different points in the design space. Nobody frames it as a
competition; they’re simply shaped for different jobs.&lt;&#x2F;p&gt;
&lt;p&gt;The same is true here. Dynamic, connected, frequently updated devices built with
modern languages are a different job, and they deserve a tool built for that
job.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;so-is-it-time&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#so-is-it-time&quot; aria-label=&quot;Permalink to this section&quot;&gt;So, is it time?&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;For a real and growing class of teams and products, I think the answer is yes.
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;&quot;&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; build&lt;&#x2F;a&gt; is an early experiment exploring what
that could look like. It’s pre-1.0 and developed in the open, rough edges and
all. It’s a bet that this is a problem worth solving, and an invitation to work
out the shape of the solution together.&lt;&#x2F;p&gt;
&lt;p&gt;It depends on you: the teams building products and the vendors that support
them. Provide feedback. What am I missing? Test it out and let me know how it
works. &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;&quot;&gt;Sign up&lt;&#x2F;a&gt; for my newsletter. Tell your vendors you
need something like this. Like&#x2F;watch the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;yoebuild&#x2F;yoe&quot;&gt;GitHub repo&lt;&#x2F;a&gt;. Share it with someone who might
be interested. Contribute improvements. Fund development or infrastructure. Many
small teams need this, and these small companies form a significant portion of
the global economy (the long tail). Startups are where a lot of innovation
happens. And if a community emerges who can leverage modern AI tools, it will
happen. The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;yoebuild&#x2F;yoe&#x2F;releases&quot;&gt;progress in the past two months&lt;&#x2F;a&gt;
demonstrates this is possible.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>End-to-End Testing Across the Whole Matrix</title>
        <published>2026-06-09T00:00:00+00:00</published>
        <updated>2026-06-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/e2e-testing/"/>
        <id>https://yoebuild.org/blog/e2e-testing/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/e2e-testing/">&lt;p&gt;The last few posts have been about reach: a
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;adding-debian&#x2F;&quot;&gt;Debian backend&lt;&#x2F;a&gt;, then
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;adding-ubuntu&#x2F;&quot;&gt;Ubuntu almost for free&lt;&#x2F;a&gt;, so a &lt;code&gt;[yoe]&lt;&#x2F;code&gt;
project can now build Alpine, Debian, and Ubuntu side by side. Reach is only
half the story, though — the other half is keeping all of it working as the code
moves underneath it. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;7_fVlZcF5Pk&quot;&gt;latest video&lt;&#x2F;a&gt; walks
through how &lt;code&gt;[yoe]&lt;&#x2F;code&gt; does that: a nightly end-to-end test that builds the whole
matrix, boots each image, and proves you can log in.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;six-builds-one-job&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#six-builds-one-job&quot; aria-label=&quot;Permalink to this section&quot;&gt;Six builds, one job&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The matrix is two axes — architecture and distro. ARM and x86, crossed with
Alpine, Debian, and Ubuntu, makes six images. Each one runs the same job: build
the image, sync the modules, verify the artifacts are there, then boot it under
QEMU and confirm SSH works.&lt;&#x2F;p&gt;
&lt;p&gt;That last step is the one that matters. Networking and SSH are the difference
between a device you can work on and a brick you have to reflash — so the test
doesn’t just check that the image boots, it checks that you can get &lt;em&gt;into&lt;&#x2F;em&gt; it.
The builds are quick: most distros finish in around ten minutes, with Alpine the
outlier at about thirty because it builds the kernel from source rather than
booting a stock one. They run every night in GitHub Actions, against the same
CLI build path you’d run by hand.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-ssh-works-actually-tests&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-ssh-works-actually-tests&quot; aria-label=&quot;Permalink to this section&quot;&gt;What “SSH works” actually tests&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;yoe boot-test&lt;&#x2F;code&gt; launches the image under QEMU and watches the console for the
login prompt — the same boot you’d see from &lt;code&gt;yoe run&lt;&#x2F;code&gt;. Once the prompt appears,
it doesn’t type credentials at the console; it opens an actual SSH connection
into the running image.&lt;&#x2F;p&gt;
&lt;p&gt;That single SSH handshake exercises a surprising amount of the stack at once:
the kernel booted, init brought up its services, the network came up and got an
address, &lt;code&gt;sshd&lt;&#x2F;code&gt; started and bound, and authentication succeeded.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;where-it-stands&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#where-it-stands&quot; aria-label=&quot;Permalink to this section&quot;&gt;Where it stands&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;As &lt;code&gt;[yoe]&lt;&#x2F;code&gt; grows across distros and architectures, the surface area that can
quietly break grows with it. A nightly end-to-end test across the whole matrix
is how the project keeps the basics honest: every supported combination still
boots, still networks, still lets you in. The next steps build on the same
foundation — more cells in the matrix as more boards come online, and moving
past QEMU onto real hardware, where the boot test earns its keep.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;get-involved&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#get-involved&quot; aria-label=&quot;Permalink to this section&quot;&gt;Get involved&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The full set of walkthroughs is on the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt;. A few ways to go further:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Try a build&lt;&#x2F;strong&gt; — the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;&quot;&gt;Getting Started guide&lt;&#x2F;a&gt;
covers install and your first image.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Star and watch the repo&lt;&#x2F;strong&gt; — star it and click Watch to follow progress on
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;yoebuild&#x2F;yoe&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Subscribe to the newsletter&lt;&#x2F;strong&gt; — occasional progress notes; the email signup
is at the foot of every page on &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;&quot;&gt;yoebuild.org&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Add a machine or image&lt;&#x2F;strong&gt; — the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;ai-skills.html&quot;&gt;&lt;code&gt;&#x2F;new-machine&lt;&#x2F;code&gt; and &lt;code&gt;&#x2F;new-module&lt;&#x2F;code&gt; AI skills&lt;&#x2F;a&gt;
scaffold support for new boards and distros.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Open a discussion&lt;&#x2F;strong&gt; — questions, ideas, or a board you’d like ported next go
in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;GitHub Discussions&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Send a note&lt;&#x2F;strong&gt; — reach the team at
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20video%20feedback&quot;&gt;info@yoebuild.org&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Adding Ubuntu — almost for free</title>
        <published>2026-06-08T00:00:00+00:00</published>
        <updated>2026-06-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/adding-ubuntu/"/>
        <id>https://yoebuild.org/blog/adding-ubuntu/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/adding-ubuntu/">&lt;p&gt;Standing up the Debian backend was real work — &lt;code&gt;mmdebstrap&lt;&#x2F;code&gt; rootfs assembly,
&lt;code&gt;.deb&lt;&#x2F;code&gt; packaging, on-device apt, a glibc toolchain alongside the musl one. Adding
Ubuntu on top of that was almost free. The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;VeKhu03FqBE&quot;&gt;latest video&lt;&#x2F;a&gt; walks through it, and the headline
is how little there was to do: Ubuntu is apt, so it rides the same machinery, and
a &lt;code&gt;[yoe]&lt;&#x2F;code&gt; project can now build Alpine, Debian, and Ubuntu images side by side.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;one-backend-a-family-of-distros&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#one-backend-a-family-of-distros&quot; aria-label=&quot;Permalink to this section&quot;&gt;One backend, a family of distros&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The interesting part isn’t Ubuntu itself — it’s what Ubuntu proves. The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;adding-debian&#x2F;&quot;&gt;Debian work&lt;&#x2F;a&gt; built out the apt
plumbing: the &lt;code&gt;mmdebstrap&lt;&#x2F;code&gt; assembly pass, the &lt;code&gt;.deb&lt;&#x2F;code&gt; packaging path, the apt feed
resolver, the on-device package manager. None of that is Debian-specific. It’s
apt-family machinery, and Ubuntu is the first test of whether it generalizes.&lt;&#x2F;p&gt;
&lt;p&gt;It does. The Ubuntu module is thin — what differs from Debian is the feed
identity, the suite (&lt;code&gt;[yoe]&lt;&#x2F;code&gt; pins Ubuntu’s Resolute Raccoon &#x2F; 26.04 LTS), and the
mirror. The packaging mechanism, the dependency model, the rootfs assembly are
all shared. The clearest sign of that is in the code itself: the old
&lt;code&gt;debian_feed&lt;&#x2F;code&gt; class generalized into an &lt;code&gt;apt_feed&lt;&#x2F;code&gt; class, with Debian and Ubuntu
as two configurations of it rather than two implementations. That’s the bet
paying off — the second backend wasn’t “Debian support,” it was “apt support,”
and the marginal cost of the next distro in the family turns out to be small.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-one-place-they-diverge-zstd&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-one-place-they-diverge-zstd&quot; aria-label=&quot;Permalink to this section&quot;&gt;The one place they diverge: zstd&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Not quite zero, though. Ubuntu compresses its &lt;code&gt;.deb&lt;&#x2F;code&gt; payloads with zstd where
Debian leans on xz, and that surfaced a bug in the packaging path — the kind of
detail that stays hidden until a second distro in the same family exercises it.
Once fixed, the rest fell into line. A useful reminder that “almost the same” is
where the sharp edges live, and that a second consumer of shared code is the
cheapest way to find them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;three-distros-one-project&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#three-distros-one-project&quot; aria-label=&quot;Permalink to this section&quot;&gt;Three distros, one project&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;In the demo, switching from Debian to Ubuntu is a settings change — pick the
distro, pick the dev image, build. Underneath, all three bases now coexist in a
single project: a &lt;code&gt;yoe build-distro&lt;&#x2F;code&gt; against Alpine, Debian, and Ubuntu each
resolves and builds from cache, and the build tree keeps a separate directory and
package feed per distro. The Debian and Ubuntu feeds look nearly identical — which
is exactly the point. You choose the base image by image, and the build system
assembles whichever one the workload asks for.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mixing-our-own-source-into-an-ubuntu-base&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#mixing-our-own-source-into-an-ubuntu-base&quot; aria-label=&quot;Permalink to this section&quot;&gt;Mixing our own source into an Ubuntu base&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;One deliberate stress test in the video: rather than pull &lt;code&gt;bash&lt;&#x2F;code&gt;, &lt;code&gt;coreutils&lt;&#x2F;code&gt;,
&lt;code&gt;ca-certificates&lt;&#x2F;code&gt;, and &lt;code&gt;file&lt;&#x2F;code&gt; straight from Ubuntu’s feeds, this build still
compiles them from &lt;code&gt;[yoe]&lt;&#x2F;code&gt;’s own source units — against Ubuntu’s libraries, in
the same per-unit sandbox the rest of the system uses. Each unit builds under
&lt;code&gt;bwrap&lt;&#x2F;code&gt; against a sysroot hard-linked with only its declared dependencies, so it
sees Ubuntu’s headers and shared libraries and nothing from the host. It’s the
isolation model &lt;code&gt;[yoe]&lt;&#x2F;code&gt; borrows from Yocto, pointed at an Ubuntu base.&lt;&#x2F;p&gt;
&lt;p&gt;You wouldn’t ship it this way — for a production image you’d pin those packages to
Ubuntu’s own binaries and let the distro maintain them. The point of building them
from source here is to exercise the whole mechanism end to end: our source
packages compiling cleanly against an apt-family base, with the dependency
resolution and sandboxing doing their jobs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;where-it-stands&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#where-it-stands&quot; aria-label=&quot;Permalink to this section&quot;&gt;Where it stands&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Honest status: the base image boots in QEMU on Ubuntu’s own stock kernel, and the
foundation is solid enough to build and run a development image. It’s &lt;code&gt;main&lt;&#x2F;code&gt; only
for now — a little over 6,000 packages — with universe, where most of Ubuntu’s
catalog actually lives, still to be wired in.&lt;&#x2F;p&gt;
&lt;p&gt;It’s also big. Building the same development image on each backend, against the
same &lt;code&gt;qemu-x86_64&lt;&#x2F;code&gt; target, the assembled rootfs comes out to:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Backend&lt;&#x2F;th&gt;&lt;th&gt;Dev-image rootfs&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Alpine&lt;&#x2F;td&gt;&lt;td&gt;~230 MB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Debian&lt;&#x2F;td&gt;&lt;td&gt;~390 MB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Ubuntu&lt;&#x2F;td&gt;&lt;td&gt;~1,130 MB&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;That Ubuntu figure looks alarming next to the others, but it’s mostly low-hanging
fruit. Two directories account for the bulk of it: &lt;code&gt;linux-firmware&lt;&#x2F;code&gt; ships &lt;strong&gt;677
MB&lt;&#x2F;strong&gt; of vendor blobs for every device the distro might ever boot on, and the
stock kernel’s module tree adds another &lt;strong&gt;154 MB&lt;&#x2F;strong&gt; — together about 70% of the
image. A real device needs the firmware and modules for its own silicon, not the
entire catalog, so trimming &lt;code&gt;linux-firmware&lt;&#x2F;code&gt; to the target’s blobs and swapping
the distro kernel for a tailored build cuts the image roughly in half before
touching anything else. Locales, docs, and man pages are easy wins on top of
that. It’s the same
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;blog&#x2F;adding-debian&#x2F;&quot;&gt;size story Debian tells&lt;&#x2F;a&gt; — most of the
weight is stock-distribution generality, and most of it comes off once you know
the target.&lt;&#x2F;p&gt;
&lt;p&gt;The encouraging result is the one the video opens with: supporting another
distribution in this family was not a lot of work. The next focus is moving past
QEMU onto real hardware, and trading the stock distro kernel for a custom one —
which is where embedded Linux gets interesting.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;get-involved&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#get-involved&quot; aria-label=&quot;Permalink to this section&quot;&gt;Get involved&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The full set of walkthroughs is on the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt;. A few ways to go further:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Try a build&lt;&#x2F;strong&gt; — the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;&quot;&gt;Getting Started guide&lt;&#x2F;a&gt;
covers install and your first image.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Star and watch the repo&lt;&#x2F;strong&gt; — star it and click Watch to follow progress on
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;yoebuild&#x2F;yoe&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Subscribe to the newsletter&lt;&#x2F;strong&gt; — occasional progress notes; the email signup
is at the foot of every page on &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;&quot;&gt;yoebuild.org&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Add a machine or image&lt;&#x2F;strong&gt; — the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;ai-skills.html&quot;&gt;&lt;code&gt;&#x2F;new-machine&lt;&#x2F;code&gt; and &lt;code&gt;&#x2F;new-module&lt;&#x2F;code&gt; AI skills&lt;&#x2F;a&gt;
scaffold support for new boards and distros.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Open a discussion&lt;&#x2F;strong&gt; — questions, ideas, or a board you’d like ported next go
in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;GitHub Discussions&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Send a note&lt;&#x2F;strong&gt; — reach the team at
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20Ubuntu%20feedback&quot;&gt;info@yoebuild.org&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Adding Debian — and what it weighs</title>
        <published>2026-06-03T00:00:00+00:00</published>
        <updated>2026-06-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/adding-debian/"/>
        <id>https://yoebuild.org/blog/adding-debian/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/adding-debian/">&lt;p&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; started Alpine-first: musl, busybox, OpenRC, and &lt;code&gt;apk&lt;&#x2F;code&gt;. That stack is
small, fast, and clean to wrap, and it remains the default for new projects. But
not every workload fits it. Some binaries are built for glibc and never ported
to musl — CUDA, vendor camera and radio drivers, a lot of enterprise software.
Some teams already run a Debian&#x2F;Ubuntu-based fleet and want their edge devices
to match it. And the apt ecosystem is vast.&lt;&#x2F;p&gt;
&lt;p&gt;So &lt;code&gt;[yoe]&lt;&#x2F;code&gt; now has a second backend: Debian. The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;16pxjZaw-Wo&quot;&gt;latest video&lt;&#x2F;a&gt; walks through it. The same project
can build Alpine and Debian images side by side, choosing the distro per image.
A unit’s source build runs in whichever toolchain the consuming image needs —
musl for an Alpine image, glibc for a Debian one — and produces a libc-correct
binary either way. You pick the platform the workload requires, image by image.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-same-machinery-a-much-bigger-feed&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-same-machinery-a-much-bigger-feed&quot; aria-label=&quot;Permalink to this section&quot;&gt;The same machinery, a much bigger feed&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Under the hood, the Debian backend reuses the unit model Alpine already runs on.
&lt;code&gt;[yoe]&lt;&#x2F;code&gt; targets Trixie, Debian’s current stable release, and Debian main alone
exposes nearly 69,000 packages — against roughly 25,000 in Alpine’s &lt;code&gt;main&lt;&#x2F;code&gt; and
&lt;code&gt;community&lt;&#x2F;code&gt; repos combined. Rather than ingest all of that up front, &lt;code&gt;[yoe]&lt;&#x2F;code&gt;
parses the package index files on startup and materializes units on demand,
exactly as it does for Alpine. Even against a feed that size, the TUI still
comes up in about a second.&lt;&#x2F;p&gt;
&lt;p&gt;The one place the two worlds diverge is naming. The same library often goes by a
different package name on each base — Python is &lt;code&gt;python3&lt;&#x2F;code&gt; on Alpine but
&lt;code&gt;python3.11&lt;&#x2F;code&gt; on Debian — so a unit now carries per-distro build and runtime
dependencies, and the build system resolves the right ones for the image it’s
assembling. Some source packages needed adjusting to compile cleanly against
either base, but once that’s done a single unit builds on both. Picking a
platform is then just a project setting: flip the default distro between Alpine
and Debian and rebuild.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;choose-per-image-pay-only-where-you-need-it&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#choose-per-image-pay-only-where-you-need-it&quot; aria-label=&quot;Permalink to this section&quot;&gt;Choose per image, pay only where you need it&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; lets you reach for the base distribution without committing the whole
project to it. If you don’t have a hard reason for Debian — a glibc-only
library, a vendor binary, an existing Debian fleet — Alpine keeps the image
small and the defaults work. If you do, Debian’s plumbing is there: feeds
resolve, packages mirror, the rootfs assembles in a single &lt;code&gt;mmdebstrap&lt;&#x2F;code&gt; pass,
and the project’s own repo emits a signed index.&lt;&#x2F;p&gt;
&lt;p&gt;The pattern this enables is mixing the two in one project — a glibc Debian host
image running vendor agents and a container runtime, with small musl Alpine
application containers deployed inside it. The host pays for compatibility where
it needs it; the workloads stay lean. You spend the extra megabytes exactly
once, exactly where they earn their place, instead of across the whole device.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-tradeoff-is-size&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-tradeoff-is-size&quot; aria-label=&quot;Permalink to this section&quot;&gt;The tradeoff is size&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Debian buys compatibility, and it costs space. To measure that honestly, we
built the same minimal image on each backend: the smallest thing that boots and
accepts an SSH login, with no extra developer tooling on either side. Just a
kernel, an init system, libc, a shell, the package manager, &lt;code&gt;sshd&lt;&#x2F;code&gt;, DHCP
networking, and a login user. Same job, same &lt;code&gt;qemu-x86_64&lt;&#x2F;code&gt; target.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Backend&lt;&#x2F;th&gt;&lt;th&gt;Packages available&lt;&#x2F;th&gt;&lt;th&gt;Minimal &lt;code&gt;ssh-image&lt;&#x2F;code&gt; rootfs&lt;&#x2F;th&gt;&lt;th&gt;Dev image assembly&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Alpine&lt;&#x2F;td&gt;&lt;td&gt;~25,000&lt;&#x2F;td&gt;&lt;td&gt;85 MB&lt;&#x2F;td&gt;&lt;td&gt;~10 s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Debian&lt;&#x2F;td&gt;&lt;td&gt;~69,000&lt;&#x2F;td&gt;&lt;td&gt;405 MB&lt;&#x2F;td&gt;&lt;td&gt;~100 s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Debian’s draw is the catalog — about 69,000 packages in &lt;code&gt;main&lt;&#x2F;code&gt;, against Alpine’s
~25,000 across &lt;code&gt;main&lt;&#x2F;code&gt; and &lt;code&gt;community&lt;&#x2F;code&gt;. The cost is size and time: roughly 4.8×
on disk — the apples-to-apples platform floor for a real device you can log into
— and close to 10× in assembly. The build-time column is the cached
image-assembly step for the dev image, a notch up from this minimal one; the
sections below break down where each gap comes from.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;where-the-difference-comes-from&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#where-the-difference-comes-from&quot; aria-label=&quot;Permalink to this section&quot;&gt;Where the difference comes from&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Two things, and most of it is the kernel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The kernel.&lt;&#x2F;strong&gt; Most of the gap is the stock &lt;code&gt;linux-image-amd64&lt;&#x2F;code&gt; package — its
module tree alone is about 107 MB, because a distribution kernel ships a driver
for every machine it might ever run on. Alpine here boots a kernel &lt;code&gt;[yoe]&lt;&#x2F;code&gt; built
from source, tailored to the target, so its modules are a few megabytes rather
than a hundred-plus. This part of the gap isn’t really “Debian vs Alpine” — it’s
“stock distribution kernel vs tailored build,” and a production Debian image on
&lt;code&gt;[yoe]&lt;&#x2F;code&gt; can swap in a tailored kernel too. Out of the box, though, the distro
kernel brings everything.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The userland.&lt;&#x2F;strong&gt; The remainder is the platform itself: glibc and its multiarch
libraries, systemd and NetworkManager, the full apt and dpkg stack, complete
coreutils instead of busybox applets, locales, udev rules. musl plus busybox
plus OpenRC is simply a lighter foundation, and on a device that difference
compounds.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;size-isn-t-the-only-difference-assembly-is-heavier-too&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#size-isn-t-the-only-difference-assembly-is-heavier-too&quot; aria-label=&quot;Permalink to this section&quot;&gt;Size isn’t the only difference — assembly is heavier too&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The two images are also assembled differently, and it comes down to what a
package &lt;em&gt;does&lt;&#x2F;em&gt; when it installs.&lt;&#x2F;p&gt;
&lt;p&gt;Assembling the Alpine image is essentially one step: &lt;code&gt;apk&lt;&#x2F;code&gt; extracts the packages
into the root filesystem, resolves their dependencies, and checks for file
conflicts. Alpine packages are largely self-contained — the install-time logic
is minimal, mostly busybox wiring up its own applet symlinks. Few moving parts,
and it’s fast.&lt;&#x2F;p&gt;
&lt;p&gt;A Debian &lt;code&gt;.deb&lt;&#x2F;code&gt; carries maintainer scripts — &lt;code&gt;preinst&lt;&#x2F;code&gt;, &lt;code&gt;postinst&lt;&#x2F;code&gt; — that have
to run to finish the install: creating users, enabling systemd services, running
&lt;code&gt;ldconfig&lt;&#x2F;code&gt;, registering alternatives. So &lt;code&gt;[yoe]&lt;&#x2F;code&gt; assembles the Debian rootfs
with &lt;code&gt;mmdebstrap&lt;&#x2F;code&gt; driving &lt;code&gt;apt&lt;&#x2F;code&gt; and &lt;code&gt;dpkg&lt;&#x2F;code&gt;, then runs every package’s scripts to
reach a fully configured state. And because those scripts assume a complete base
system is already in place, assembly carries ordering subtleties the Alpine path
never hits. A concrete one: &lt;code&gt;openssh-server&lt;&#x2F;code&gt;’s post-install reaches for &lt;code&gt;awk&lt;&#x2F;code&gt;
before the package that provides it has been configured, so the assembler
pre-stages the &lt;code&gt;awk&lt;&#x2F;code&gt; alternative ahead of time to keep the script from failing.
For a foreign architecture, all of those scripts run under QEMU emulation as
well.&lt;&#x2F;p&gt;
&lt;p&gt;None of this is a knock on Debian — that maintainer-script model is exactly what
makes the broad apt ecosystem drop in and &lt;em&gt;just work&lt;&#x2F;em&gt;, users and services
configured the way the package author intended. It’s the same tradeoff as the
size: the richness that earns Debian its place is also what makes it heavier to
assemble. Alpine does less at install time, so there’s less to do at build time.&lt;&#x2F;p&gt;
&lt;p&gt;It shows up on the clock, too. With every dependency package already built and
cached — so the timer captures only the image-assembly step, not the source
builds behind it — reassembling the dev image (a working image with editors and
diagnostics, a notch up from the minimal one measured above) on the same
&lt;code&gt;qemu-x86_64&lt;&#x2F;code&gt; target takes about &lt;strong&gt;10 seconds on Alpine and roughly 100 on
Debian&lt;&#x2F;strong&gt;: close to a 10× gap. Alpine’s side is a single &lt;code&gt;apk&lt;&#x2F;code&gt; extract; Debian’s
is &lt;code&gt;mmdebstrap&lt;&#x2F;code&gt; plus &lt;code&gt;dpkg&lt;&#x2F;code&gt; configuring every package and running its maintainer
scripts, under QEMU for a foreign architecture. The Debian time also wanders
more from run to run (90–120 s), because it leans on apt and dpkg doing real
work rather than a near-deterministic unpack.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;where-it-stands&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#where-it-stands&quot; aria-label=&quot;Permalink to this section&quot;&gt;Where it stands&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Debian support is experimental but real: the image measured above boots and
accepts SSH, so it’s a device you can log into and work on, not a paper target.
The build path is solid and the size numbers are measurements, not estimates.
There’s still plenty to harden, and honest comparisons — like this one — are how
we keep the tradeoffs in view as it matures.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s next&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Hardening the Debian path from experimental toward production — tailoring the
kernel down from the stock one, and proving it out across more targets. The
&lt;a href=&quot;&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt; has the full walkthrough set.&lt;&#x2F;p&gt;
&lt;p&gt;If you have a workload that needs glibc, we’d love to hear how it goes —
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;open a discussion&lt;&#x2F;a&gt; or send a
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20Debian%20feedback&quot;&gt;note&lt;&#x2F;a&gt;. To
follow &lt;code&gt;[yoe]&lt;&#x2F;code&gt; as it grows,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;yoebuild&#x2F;yoe&quot;&gt;star and watch the repo&lt;&#x2F;a&gt; and
&lt;a href=&quot;&#x2F;atom.xml&quot;&gt;subscribe for updates&lt;&#x2F;a&gt; — there’s an email signup at the foot of
every page, too.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>It&#x27;s Not About Competition</title>
        <published>2026-06-02T00:00:00+00:00</published>
        <updated>2026-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/its-not-about-competition/"/>
        <id>https://yoebuild.org/blog/its-not-about-competition/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/its-not-about-competition/">&lt;p&gt;Thinking competitively comes naturally - our society trains us for it. There
must always be a winner and a loser. So with the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;&quot;&gt;Next Gen Embedded Linux&lt;&#x2F;a&gt; project, it is tempting to
assume something new can only succeed if Yocto loses. That is not what I am
seeing. The market keeps expanding and growing. Yocto is established and will
continue to serve teams that need to build everything from source, that care
deeply about binary reproducibility, and so on. Alongside them, a growing
segment of companies lacks the resources to maintain a Yocto build system. I
keep seeing small teams with different priorities: they want a simpler way to
bring advanced technology to their products. They want to lean on existing
package ecosystems while keeping the tools to customize and maintain what they
ship.&lt;&#x2F;p&gt;
&lt;p&gt;The Debian and Alpine Linux distributions offer a useful parallel. Alpine did
not replace Debian; it met a different need - a lightweight base for building
containers. Both keep growing because the market and its needs keep expanding.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;its-not-about-competition.png&quot; alt=&quot;It’s not about competition&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fast Binary Packages from the APK Index</title>
        <published>2026-05-29T00:00:00+00:00</published>
        <updated>2026-05-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/binary-packages-from-the-index/"/>
        <id>https://yoebuild.org/blog/binary-packages-from-the-index/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/binary-packages-from-the-index/">&lt;p&gt;The &lt;a href=&quot;&#x2F;blog&#x2F;qt-support&#x2F;&quot;&gt;Qt post&lt;&#x2F;a&gt; mentioned that &lt;code&gt;[yoe]&lt;&#x2F;code&gt; pulls packages from
Alpine and presents the prebuilt binaries as virtual units. A
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;YNsT4HzYza4&quot;&gt;new video&lt;&#x2F;a&gt; digs into how that works now, because
the mechanism recently changed in a way that’s worth explaining: instead of
generating a file per package up front, &lt;code&gt;[yoe]&lt;&#x2F;code&gt; reads Alpine’s package index
directly and builds units on demand.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-old-way-a-file-per-package&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-old-way-a-file-per-package&quot; aria-label=&quot;Permalink to this section&quot;&gt;The old way: a file per package&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The previous approach was to keep an &lt;code&gt;alpine&#x2F;units&lt;&#x2F;code&gt; folder full of autogenerated
files, each one wrapping a single Alpine package. &lt;code&gt;main&lt;&#x2F;code&gt; had over 2,000 of them.
Scripts generated and updated the set. The community repo was handled more
lazily — it has over 10,000 packages, and generating a wrapper file for every
one wasn’t worth it, so those were generated only as needed.&lt;&#x2F;p&gt;
&lt;p&gt;This worked. But it meant carrying thousands of generated artifacts in the
module and keeping them in sync with upstream.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;parse-the-index-instead&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#parse-the-index-instead&quot; aria-label=&quot;Permalink to this section&quot;&gt;Parse the index instead&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Alpine already ships an APK index that contains exactly the information those
wrapper files were duplicating — each package’s metadata and its dependencies.
So the question became: why generate the files at all? Parse the index, and
construct a virtual unit for any Alpine package directly from it.&lt;&#x2F;p&gt;
&lt;p&gt;That’s the change. The Alpine module now carries just a handful of files — the
APK indexes themselves. &lt;code&gt;main&lt;&#x2F;code&gt; is about 2.2 MB per architecture and lists
roughly 5,000 packages; &lt;code&gt;community&lt;&#x2F;code&gt; is about 8.7 MB and lists nearly 20,000. The
index is dense but simple: a flat list of packages, what each one is, and what
it depends on. Everything needed to construct a unit is already in there, so
there’s nothing to generate and keep in sync.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;only-what-an-image-needs&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#only-what-an-image-needs&quot; aria-label=&quot;Permalink to this section&quot;&gt;Only what an image needs&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;There’s one more wrinkle that keeps this fast. Alpine offers around 25,000
packages across both feeds, but &lt;code&gt;[yoe]&lt;&#x2F;code&gt; shows only a few hundred units — in the
demo, 363. It doesn’t materialize a unit for every package in the index. On
startup it scans all the images, walks their dependencies recursively, and
generates virtual units only for the packages those images actually reference.&lt;&#x2F;p&gt;
&lt;p&gt;Adding a package is then just adding its name to an image. &lt;code&gt;[yoe]&lt;&#x2F;code&gt; notices the
reference, wraps the package, signs it with its key, and serves it from the
&lt;code&gt;[yoe]&lt;&#x2F;code&gt; feed automatically. You get access to the entire distribution without
paying to enumerate it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-it-matters&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#why-it-matters&quot; aria-label=&quot;Permalink to this section&quot;&gt;Why it matters&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This is the difference between a tool that knows about 25,000 packages and one
that drags 25,000 packages around. The app starts fast and stays responsive
because it holds exactly the information that images need and nothing more. The
full Alpine catalog is one image edit away, but it costs nothing until you reach
for it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s next&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Possibly Debian as an additional package source alongside Alpine. The
&lt;a href=&quot;&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt; has the full walkthrough set. If you’ve got thoughts on
how &lt;code&gt;[yoe]&lt;&#x2F;code&gt; consumes packages,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;open a discussion&lt;&#x2F;a&gt; or send a
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20packages%20feedback&quot;&gt;note&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Qt Support in [yoe]</title>
        <published>2026-05-29T00:00:00+00:00</published>
        <updated>2026-05-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/qt-support/"/>
        <id>https://yoebuild.org/blog/qt-support/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/qt-support/">&lt;p&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; can now build and run a Qt application, shown in a short
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;AOq5aZc9Ohw&quot;&gt;demo video&lt;&#x2F;a&gt;. Qt is worth supporting because it’s
the mainstay graphical toolkit for embedded native apps — if your device has a
display and you want a polished interface, Qt is very often the answer. But the
toolkit is just the occasion. The parts worth talking about are how those
dependencies get into a build, and where the graphical app actually runs while
you develop it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wrapping-binaries-instead-of-building-them&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#wrapping-binaries-instead-of-building-them&quot; aria-label=&quot;Permalink to this section&quot;&gt;Wrapping binaries instead of building them&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;A Qt app pulls in a pile of dependencies: &lt;code&gt;qtdeclarative&lt;&#x2F;code&gt;, &lt;code&gt;qtbase&lt;&#x2F;code&gt;, X11, fonts.
In a traditional embedded build you’d own a recipe for each — fetch source,
patch it, compile it. That’s where a lot of the cost and fragility of building
embedded Linux lives.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; takes a different path: it pulls these packages straight from the Alpine
community repo (and hopefully Debian will be an option soon) and presents the
prebuilt binaries as virtual units. You figure out which Alpine package you
need, and the build system pulls it into your feed and wraps its assets
automatically. No custom recipes, no source builds for the toolkit itself.&lt;&#x2F;p&gt;
&lt;p&gt;This is the same mechanism behind the
&lt;a href=&quot;&#x2F;blog&#x2F;running-on-beagle-play&#x2F;&quot;&gt;Python tooling for the Beagle Play BSP&lt;&#x2F;a&gt; and
&lt;a href=&quot;&#x2F;blog&#x2F;pip-and-npm-on-the-target&#x2F;&quot;&gt;pip and npm on the target&lt;&#x2F;a&gt; — a flat list of
&lt;code&gt;pkg&lt;&#x2F;code&gt;-style dependencies that resolve against a maintained binary distribution.
Adding a graphical toolkit ends up looking like adding any other dependency:
name the packages, rebuild. The leverage is in not reinventing a package set
that Alpine or Debian already maintains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;qemu-as-a-first-class-development-target&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#qemu-as-a-first-class-development-target&quot; aria-label=&quot;Permalink to this section&quot;&gt;QEMU as a first-class development target&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;QEMU is a really useful tool that I hadn’t used much before. I would
develop apps natively, and then build an image for embedded targets, but QEMU
sits between these domains and allows you to quickly and efficiently develop
your image build system. &lt;code&gt;[yoe]&lt;&#x2F;code&gt; makes running on QEMU easy.&lt;&#x2F;p&gt;
&lt;p&gt;In this development cycle support was added for enabling the QEMU display,
setting the memory allocated, and configuring the network port mapping from the
QEMU instance to the host.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s next&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;More toolkit and application coverage, and more targets to run it on. The
&lt;a href=&quot;&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt; has the full walkthrough set. If there’s an app or
framework you’d like to see running under &lt;code&gt;[yoe]&lt;&#x2F;code&gt;,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;open a discussion&lt;&#x2F;a&gt; or send a
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20Qt%20feedback&quot;&gt;note&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>[yoe] Is Now Self-Hosting</title>
        <published>2026-05-28T00:00:00+00:00</published>
        <updated>2026-05-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/self-hosting/"/>
        <id>https://yoebuild.org/blog/self-hosting/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/self-hosting/">&lt;p&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; can now build itself. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;7KT3dWuFrx8&quot;&gt;latest video&lt;&#x2F;a&gt;
walks through a short proof: build a &lt;code&gt;selfhost-image&lt;&#x2F;code&gt; with &lt;code&gt;[yoe]&lt;&#x2F;code&gt;, boot it in
QEMU, SSH in, and run &lt;code&gt;[yoe]&lt;&#x2F;code&gt; to build another image. The demo runs two levels
deep — host workstation, a QEMU instance built by &lt;code&gt;[yoe]&lt;&#x2F;code&gt;, and another &lt;code&gt;[yoe]&lt;&#x2F;code&gt;
build running inside that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-in-the-image&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-in-the-image&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s in the image&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;selfhost-image&lt;&#x2F;code&gt; carries everything needed to develop with &lt;code&gt;[yoe]&lt;&#x2F;code&gt; on the
target: the &lt;code&gt;yoe&lt;&#x2F;code&gt; CLI, Docker with &lt;code&gt;buildx&lt;&#x2F;code&gt; and &lt;code&gt;containerd&lt;&#x2F;code&gt;, the Go
toolchain, &lt;code&gt;git&lt;&#x2F;code&gt;, &lt;code&gt;bubblewrap&lt;&#x2F;code&gt; for sandboxing, and the developer toolkit —
Helix, Yazi, Zellij. A first-boot service grows the rootfs to fill the
storage device.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;two-levels-deep&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#two-levels-deep&quot; aria-label=&quot;Permalink to this section&quot;&gt;Two levels deep&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The video runs &lt;code&gt;[yoe]&lt;&#x2F;code&gt; inside a QEMU instance that &lt;code&gt;[yoe]&lt;&#x2F;code&gt; built. SSH in from
another tab — the terminal behaves better than the QEMU console — and the
inner &lt;code&gt;base-image&lt;&#x2F;code&gt; build is already complete. Running the result needs a
port remap to avoid colliding with the outer QEMU and a memory cap below the
host’s 4 GB. KVM is not available in the nested setup, so the inner boot is
a bit slower, but it boots and runs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-it-matters&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#why-it-matters&quot; aria-label=&quot;Permalink to this section&quot;&gt;Why it matters&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The interesting case is not nested QEMU. It’s a Raspberry Pi 5 with an NVMe
HAT acting as a standalone &lt;code&gt;[yoe]&lt;&#x2F;code&gt; build host. Builds run natively on ARM64
— no QEMU user-mode emulation in the loop — and right now that is the
fastest way to build an ARM image with &lt;code&gt;[yoe]&lt;&#x2F;code&gt;. It is also a step toward a
build farm of cheap ARM nodes.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;selfhost.html&quot;&gt;self-host docs&lt;&#x2F;a&gt; cover the
hardware: Pi 5 with 8 GB of RAM (16 GB if you want concurrent kernel or LLVM
builds), NVMe via PCIe HAT for 10–20× the throughput of microSD, and a 27 W
USB-PD supply to drive it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s next&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;V1 of &lt;code&gt;selfhost-image&lt;&#x2F;code&gt; is single-arch, with no A&#x2F;B partitioning or headless
install yet. The &lt;a href=&quot;&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt; has the full walkthrough set. If
you’d like to see this run on different hardware or in a build-farm
configuration,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;open a discussion&lt;&#x2F;a&gt; or send a
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20self-host%20feedback&quot;&gt;note&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running [yoe] on a Beagle Play</title>
        <published>2026-05-21T00:00:00+00:00</published>
        <updated>2026-05-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/running-on-beagle-play/"/>
        <id>https://yoebuild.org/blog/running-on-beagle-play/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/running-on-beagle-play/">&lt;p&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; now boots a Beagle Play. The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;pL3ze_LuJPc&quot;&gt;latest video&lt;&#x2F;a&gt; walks through building the image,
flashing the SD card, and watching the TI AM625 step through its four-stage
boot. But the more interesting story is how the BSP got written: I pointed
Claude Code at the existing &lt;code&gt;meta-ti&lt;&#x2F;code&gt; Yocto layer, asked it to “create machine
support for a Beagle Play,” and most of it landed in one shot.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-in-the-video&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-in-the-video&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s in the video&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;yoe update&lt;&#x2F;code&gt; and &lt;code&gt;yoe sync&lt;&#x2F;code&gt; to refresh the modules, then &lt;code&gt;yoe&lt;&#x2F;code&gt; to open the TUI.
Pick &lt;code&gt;beagleplay&lt;&#x2F;code&gt; from the machine list, pick the development image, press &lt;code&gt;F&lt;&#x2F;code&gt;
to flash. &lt;code&gt;[yoe]&lt;&#x2F;code&gt; figures out which block devices are removable so you can’t
accidentally write to your workstation’s main disk, remembers the device you
used last time, and writes the SD card.&lt;&#x2F;p&gt;
&lt;p&gt;Hold the user button down while powering on the board and it boots from SD
instead of the on-board eMMC — useful so an old eMMC bootloader can’t sneak into
the chain. The serial console then shows the boot stepping through its stages.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;four-stages-of-bootloader&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#four-stages-of-bootloader&quot; aria-label=&quot;Permalink to this section&quot;&gt;Four stages of bootloader&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The AM625 is not a simple part. The on-chip ROM brings up a 32-bit R5 core and
loads a first-stage SPL onto it. That hands control to the 64-bit A53 cores,
which load a second SPL, then U-Boot, then the kernel. So &lt;code&gt;[yoe]&lt;&#x2F;code&gt; needs two
U-Boot binaries (one 32-bit, one 64-bit), an extra 32-bit ARM toolchain
alongside the default 64-bit one, and a pile of Python build-time tools that the
TI build scripts call out to.&lt;&#x2F;p&gt;
&lt;p&gt;Those Python tools come straight from Alpine packages — no custom recipes, no
source builds. Hitting &lt;code&gt;e&lt;&#x2F;code&gt; on a unit pops you into your editor, and the
dependency list reads as a flat enumeration of &lt;code&gt;py3-*&lt;&#x2F;code&gt; packages.&lt;&#x2F;p&gt;
&lt;p&gt;The build itself runs in a &lt;code&gt;bwrap&lt;&#x2F;code&gt; sandbox against a per-unit sysroot.
Dependencies are hard-linked in, so it’s fast, and the unit only sees what it
declared — nothing leaks from a sibling. That sandbox is what turns “add another
&lt;code&gt;py3-*&lt;&#x2F;code&gt; and rebuild” into a safe operation instead of a debugging adventure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-part-that-mattered&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-part-that-mattered&quot; aria-label=&quot;Permalink to this section&quot;&gt;The part that mattered&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; rests on a bet: that an AI agent can take a Yocto BSP from a vendor’s
layer and reshape it into a &lt;code&gt;[yoe]&lt;&#x2F;code&gt; module quickly. If that bet doesn’t hold,
the project doesn’t work — every new SoC becomes a multi-week porting job, and
the productivity case collapses.&lt;&#x2F;p&gt;
&lt;p&gt;The Beagle Play is the first real test. It’s not a Raspberry Pi clone with a
mainline kernel and a one-line config. It’s a current-generation TI part with
vendor-specific firmware, a 32-bit SPL stage, and a custom toolchain
requirement. Claude wrote most of it from a single prompt. The remaining work
was iterating on missing Python dependencies — a build would fail, the error
named a missing tool, the fix was another Alpine package. A handful of cycles
later, the image booted.&lt;&#x2F;p&gt;
&lt;p&gt;That’s the kind of porting loop the project needs to be cheap, and right now it
looks like it is.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s next&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;More BSPs. The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;machine-beagleplay.html&quot;&gt;Beagle Play machine docs&lt;&#x2F;a&gt;
cover how to use this one, and the &lt;a href=&quot;&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt; has the full
walkthrough set. If there’s a board you’d like to see ported next,
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;open a discussion&lt;&#x2F;a&gt; or send a
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20BSP%20feedback&quot;&gt;note&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why the Build Tool Is a TUI</title>
        <published>2026-05-19T00:00:00+00:00</published>
        <updated>2026-05-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/why-a-tui/"/>
        <id>https://yoebuild.org/blog/why-a-tui/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/why-a-tui/">&lt;p&gt;A terminal UI looks primitive next to a web app or a native desktop app, and
those alternatives are genuinely more capable. So why does &lt;code&gt;[yoe]&lt;&#x2F;code&gt; use a TUI?
The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;ZGTyt-Dvo3g&quot;&gt;latest video&lt;&#x2F;a&gt; walks through the reasoning,
and it comes down to one thing: most of the work already happens in the
terminal, and a TUI build tool sits right next to it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;we-already-live-here&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#we-already-live-here&quot; aria-label=&quot;Permalink to this section&quot;&gt;We already live here&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Open a developer’s terminal and look at what’s running. An editor — Helix or Vim
— for finding files and making changes. A file manager like
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yazi-rs.github.io&#x2F;&quot;&gt;Yazi&lt;&#x2F;a&gt; for moving through build directories.
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jesseduffield&#x2F;lazygit&quot;&gt;lazygit&lt;&#x2F;a&gt; for the day-to-day git work.
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zellij.dev&#x2F;&quot;&gt;Zellij&lt;&#x2F;a&gt; as a multiplexer, holding saved sessions that you
can reattach from another machine — the demo is recorded from a laptop attached
to a workstation session — split into named tabs and panes. &lt;code&gt;ripgrep&lt;&#x2F;code&gt; for
searching the tree.&lt;&#x2F;p&gt;
&lt;p&gt;These tools are fast, keyboard-driven, and composable. They are where the work
happens. A build tool that opens a separate window asks you to leave that
environment every time you switch between building the system and changing the
code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;proximity-is-the-feature&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#proximity-is-the-feature&quot; aria-label=&quot;Permalink to this section&quot;&gt;Proximity is the feature&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Because &lt;code&gt;[yoe]&lt;&#x2F;code&gt; is a TUI, it starts up inside that same environment. Highlight a
unit and press &lt;code&gt;e&lt;&#x2F;code&gt;, and you land in the same editor you use for everything else
— not a built-in editor that almost works, but &lt;em&gt;your&lt;&#x2F;em&gt; editor. Press &lt;code&gt;$&lt;&#x2F;code&gt; and you
drop into a shell in that unit’s build directory, where &lt;code&gt;yazi&lt;&#x2F;code&gt;, &lt;code&gt;rg&lt;&#x2F;code&gt;, and the
rest of your toolkit are already waiting.&lt;&#x2F;p&gt;
&lt;p&gt;A TUI is not the most powerful interface for any single one of these jobs. A
native app could draw a richer view of any one of them. But the TUI inherits an
effectively unbounded set of powerful, programmer-focused tools for free, and
the toolkit &lt;code&gt;[yoe]&lt;&#x2F;code&gt; is built on makes wiring up to them straightforward. The
build tool stops being a destination you visit and becomes one more pane in the
environment you never left.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;speed-and-hands-on-the-keyboard&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#speed-and-hands-on-the-keyboard&quot; aria-label=&quot;Permalink to this section&quot;&gt;Speed, and hands on the keyboard&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The terminal tools share another trait: you drive them from the keyboard.
Switching units, opening an editor, shelling in, searching — each is a
keystroke, not a trip to the mouse to hunt for the right window. Hands stay on
the keyboard, and the loop between &lt;em&gt;I want to change this&lt;&#x2F;em&gt; and &lt;em&gt;the change is
made&lt;&#x2F;em&gt; stays short.&lt;&#x2F;p&gt;
&lt;p&gt;That is the whole argument. A TUI is a constrained surface — characters on a
screen, no pixels to spare on chrome. The constraint buys speed, keyboard
control, and a clean seam between the build tool and every other tool a
developer already trusts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-this-matters&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#why-this-matters&quot; aria-label=&quot;Permalink to this section&quot;&gt;Why this matters&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The first goal in
&lt;a href=&quot;&#x2F;blog&#x2F;next-gen-embedded-linux&#x2F;&quot;&gt;What a Modern Embedded Linux Build System Could Look Like&lt;&#x2F;a&gt;
was to shrink the loop between an idea and a running image. A lot of that loop
is the friction of moving between tools. Choosing a TUI removes a category of
that friction by refusing to pull you out of the environment where the rest of
the work already lives.&lt;&#x2F;p&gt;
&lt;p&gt;The full set of walkthroughs is on the &lt;a href=&quot;&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt;. What part of the
workflow would you like to see next?
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;Open a discussion&lt;&#x2F;a&gt; or send a
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20video%20feedback&quot;&gt;note&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Editing a Unit&#x27;s Source Without Leaving the Build</title>
        <published>2026-05-15T00:00:00+00:00</published>
        <updated>2026-05-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/unit-source-edit-workflow/"/>
        <id>https://yoebuild.org/blog/unit-source-edit-workflow/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/unit-source-edit-workflow/">&lt;p&gt;Editing the source of a unit is one of the most common things you do while
building an embedded Linux system. You hit a bug in an application, you need a
patch in the kernel, you want to try a change before it lands upstream. In most
build systems that means dropping out of the tool, cloning the repo somewhere
else, wiring up a patch or a local override, and rebuilding. The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;PgBKVJ3XZzU&quot;&gt;latest walkthrough&lt;&#x2F;a&gt; shows &lt;code&gt;[yoe]&lt;&#x2F;code&gt; doing the whole
loop in place.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pinned-by-default-development-on-demand&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#pinned-by-default-development-on-demand&quot; aria-label=&quot;Permalink to this section&quot;&gt;Pinned by default, development on demand&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Every unit pins to a release tag by default and checks out over HTTPS for
convenience. That is the right default for a reproducible build, but it is the
wrong shape for making a change: the source lives in &lt;code&gt;[yoe]&lt;&#x2F;code&gt;’s download cache,
and you can’t push a fix back to a cache.&lt;&#x2F;p&gt;
&lt;p&gt;Pressing the dev-mode key switches the unit over. &lt;code&gt;[yoe]&lt;&#x2F;code&gt; re-points the checkout
at the upstream repository, optionally swaps the HTTPS remote for the SSH URL
most of us push through, and asks how much history you want. A shallow clone of
100 commits is plenty for a quick change — and for something like the Linux
kernel, skipping the full history saves a large download. Shell into the source
directory and you land on the upstream branch, connected to the remote you can
actually push to.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-build-follows-the-source&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-build-follows-the-source&quot; aria-label=&quot;Permalink to this section&quot;&gt;The build follows the source&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Once a unit is in development mode, the cache key comes from a &lt;code&gt;git diff&lt;&#x2F;code&gt; of the
working tree rather than the pinned tag. Change a line and the cache invalidates
on its own — no manual flag, no stale artifact. The unit’s status moves from
pinned to &lt;code&gt;dev modified&lt;&#x2F;code&gt; to &lt;code&gt;dev dirty&lt;&#x2F;code&gt; as you switch modes and accumulate
uncommitted changes, so the state is always visible at a glance.&lt;&#x2F;p&gt;
&lt;p&gt;From there the loop is short: build the unit, deploy it with a single key to the
target you last deployed to, and watch the change land on the target instance.
Because &lt;code&gt;[yoe]&lt;&#x2F;code&gt; is built to run several sessions at once, the build and the
running target sit side by side while you iterate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pinning-the-change-back&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#pinning-the-change-back&quot; aria-label=&quot;Permalink to this section&quot;&gt;Pinning the change back&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;When a change is worth keeping, commit it in the source tree — the status drops
out of &lt;code&gt;dev dirty&lt;&#x2F;code&gt; — and pin the recipe to the new commit. The pin command
writes the current &lt;code&gt;HEAD&lt;&#x2F;code&gt; back into the unit’s tag field, preferring a real tag
over a raw hash when one exists at that commit. The unit is reproducible again,
now at your change, and the next build is back to a clean cached state.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-this-matters&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#why-this-matters&quot; aria-label=&quot;Permalink to this section&quot;&gt;Why this matters&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Two goals from &lt;a href=&quot;&#x2F;blog&#x2F;hello-yoe&#x2F;&quot;&gt;Hello, [yoe]&lt;&#x2F;a&gt; and
&lt;a href=&quot;&#x2F;blog&#x2F;next-gen-embedded-linux&#x2F;&quot;&gt;What a Modern Embedded Linux Build System Could Look Like&lt;&#x2F;a&gt;
were to shrink the idea-to-running-image loop and to keep the application
development experience tightly coupled to the system build. This workflow is
that idea applied to source: one tool, one screen, and a clean switch between a
pinned release and a live checkout for any unit — without the extra layers other
build systems put between you and the code.&lt;&#x2F;p&gt;
&lt;p&gt;What part of the development loop would you like to see demoed next?
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;Open a discussion&lt;&#x2F;a&gt; or send a
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20video%20feedback&quot;&gt;note&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>When LTS fits — and when it doesn&#x27;t</title>
        <published>2026-05-14T00:00:00+00:00</published>
        <updated>2026-05-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/when-lts-fits/"/>
        <id>https://yoebuild.org/blog/when-lts-fits/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/when-lts-fits/">&lt;p&gt;LTS stands for Long-Term Support, which refers to software versions that receive
updates, bug fixes, and security patches for an extended period, typically aimed
at providing stability and reliability. For deeply embedded, single-purpose
systems, or locked-down enterprise laptops where users are not allowed
to install software, LTS makes sense.&lt;&#x2F;p&gt;
&lt;p&gt;For dynamic software systems (the browser is a good example), the only path is
forward. It’s hard to predict exactly what pages
need loading tomorrow, where the user will go next, what problems will occur,
what security issues need patching, what new features need supporting, etc. Edge
systems are trending in that direction. They are capable, expandable platforms
whose future needs are hard to predict.&lt;&#x2F;p&gt;
&lt;p&gt;Trying to keep an operating system pinned to an LTS release while continuously
evolving everything on top is a bit like freezing a creature’s skeleton while
expecting the rest of its body to grow and adapt around it. The structure may be
stable, but over time the muscles, organs, and connective tissue stop fitting
cleanly. Eventually, the mismatch creates friction, limits movement, and makes
further growth harder instead of easier.&lt;&#x2F;p&gt;
&lt;p&gt;When implementing an embedded OS, it’s important to decide: is this 1) a
traditional static embedded system, or 2) a dynamic edge system? These are different
problems and require different tool-sets. &lt;code&gt;[yoe]&lt;&#x2F;code&gt; is being built for the
second case — see &lt;a href=&quot;&#x2F;blog&#x2F;next-gen-embedded-linux&#x2F;&quot;&gt;What a Modern Embedded Linux Build System Could Look Like&lt;&#x2F;a&gt;
for where that’s headed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;when-lts-fits.png&quot; alt=&quot;When LTS fits&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Pip and Npm Belong on the Target too</title>
        <published>2026-05-13T00:00:00+00:00</published>
        <updated>2026-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/pip-and-npm-on-the-target/"/>
        <id>https://yoebuild.org/blog/pip-and-npm-on-the-target/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/pip-and-npm-on-the-target/">&lt;p&gt;Application developers reach for &lt;code&gt;pip install&lt;&#x2F;code&gt; or &lt;code&gt;npm install&lt;&#x2F;code&gt; without
thinking. The moment that code needs to land on an embedded Linux target, the
same one-line dependency install usually becomes a hand-written recipe per
package. That’s the friction the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;c2G9NdEi_p4&quot;&gt;third walkthrough&lt;&#x2F;a&gt; aims to remove.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-idea&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#the-idea&quot; aria-label=&quot;Permalink to this section&quot;&gt;The idea&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Let the language’s own package manager do the resolution. Capture its output.
Ship it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; now has units for three runtimes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;python.html&quot;&gt;Python&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; — a virtual-environment
class creates a venv named after the unit, runs &lt;code&gt;pip install&lt;&#x2F;code&gt;, and packages
the resulting venv as an &lt;code&gt;.apk&lt;&#x2F;code&gt; that the target installs directly. Each
application gets its own venv, so dependencies stay isolated.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;nodejs.html&quot;&gt;Node.js&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; — &lt;code&gt;npm install&lt;&#x2F;code&gt; runs at
build time, and &lt;code&gt;node_modules&#x2F;&lt;&#x2F;code&gt; rides along with the app in the same package.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.yoebuild.org&#x2F;bun.html&quot;&gt;Bun&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; — same flow as Node, but with
the lighter-weight Zig-based runtime. Worth a look if you want a smaller
footprint than full Node on the target.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The unit author writes the same dependency manifest they’d write on their laptop
— &lt;code&gt;requirements.txt&lt;&#x2F;code&gt;, &lt;code&gt;package.json&lt;&#x2F;code&gt;. The build system handles the rest,
including pulling in any development dependencies — compilers, headers, native
build tools — that pip or npm need to compile packages with C or Rust
extensions. Those tools live in the build environment, not on the target.&lt;&#x2F;p&gt;
&lt;p&gt;Python in particular benefits from the wheel ecosystem: pip caches built wheels
extensively, and most of PyPI is now distributed as prebuilt wheels for common
architectures. &lt;code&gt;[yoe]&lt;&#x2F;code&gt; is set up to leverage those caches rather than rebuild
from source on every run, which keeps Python builds fast even when the
dependency graph is large.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-this-matters&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#why-this-matters&quot; aria-label=&quot;Permalink to this section&quot;&gt;Why this matters&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Two of the goals in &lt;a href=&quot;&#x2F;blog&#x2F;hello-yoe&#x2F;&quot;&gt;Hello, [yoe]&lt;&#x2F;a&gt; and
&lt;a href=&quot;&#x2F;blog&#x2F;next-gen-embedded-linux&#x2F;&quot;&gt;What a Modern Embedded Linux Build System Could Look Like&lt;&#x2F;a&gt;
were: don’t reinvent dependency resolution, and don’t force application
developers to learn a second packaging system to ship what they already wrote.
This is what that looks like in practice — pip, npm, and bun composed in rather
than replaced.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s next&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Rust and Zig units are queued up next, along with Python ML workloads where the
dependency graph gets a lot more interesting. The
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PL3XJli5z9VFd5c0xlrFZkqm_N0dOeWhPP&quot;&gt;YouTube playlist&lt;&#x2F;a&gt;
is the place to subscribe for new walkthroughs as features land.&lt;&#x2F;p&gt;
&lt;p&gt;What development workflow would you like to see demoed next?
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;Open a discussion&lt;&#x2F;a&gt; or send a
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20video%20feedback&quot;&gt;note&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>First Walkthroughs: Overview and Package Deploy</title>
        <published>2026-05-12T00:00:00+00:00</published>
        <updated>2026-05-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/first-walkthrough-videos/"/>
        <id>https://yoebuild.org/blog/first-walkthrough-videos/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/first-walkthrough-videos/">&lt;p&gt;A build system is easier to evaluate when you can watch it in motion. The first
two walkthroughs are up on the &lt;a href=&quot;&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt;, and they cover the parts
of &lt;code&gt;[yoe]&lt;&#x2F;code&gt; that are most different from what you’d expect coming from Yocto or
Buildroot.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;video-1-overview&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#video-1-overview&quot; aria-label=&quot;Permalink to this section&quot;&gt;Video 1 — Overview&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;A tour of the build system end-to-end: &lt;code&gt;yoe init&lt;&#x2F;code&gt; to scaffold a project, the
TUI with its live progress bar, background builds, search, and inline status —
all in one screen. Then &lt;code&gt;yoe run&lt;&#x2F;code&gt; to boot the resulting image in QEMU. The aim
is to show the full idea-to-running-image loop without an SDK install, a
cross-toolchain, or generated shell scripts to read through.&lt;&#x2F;p&gt;
&lt;p&gt;If you’ve only seen the
&lt;a href=&quot;&#x2F;blog&#x2F;next-gen-embedded-linux&#x2F;&quot;&gt;earlier post&lt;&#x2F;a&gt;, this is the version where the
claims become concrete.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;video-2-deploying-packages&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#video-2-deploying-packages&quot; aria-label=&quot;Permalink to this section&quot;&gt;Video 2 — Deploying packages&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The iteration loop, zoomed in. Once an image is running, the interesting
question is how fast you can change a package on the target and try the new
version. This video walks through building a package, resolving its
dependencies, and pushing the result to a live target in a single step — no
full image rebuild, no manual &lt;code&gt;scp&lt;&#x2F;code&gt; dance.&lt;&#x2F;p&gt;
&lt;p&gt;This is the part of the experience that most rewards the design decisions in
&lt;a href=&quot;&#x2F;blog&#x2F;hello-yoe&#x2F;&quot;&gt;Hello, [yoe]&lt;&#x2F;a&gt;: one binary, language-native package managers
composed in, and content-addressed &lt;code&gt;.apk&lt;&#x2F;code&gt; outputs that the target can install
directly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Permalink to this section&quot;&gt;What’s next&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;More videos are planned as features land — Docker on the target, Go and Rust
units, BSP authoring, and the AI-assisted workflows. The full playlist lives on
the &lt;a href=&quot;&#x2F;videos&#x2F;&quot;&gt;Videos page&lt;&#x2F;a&gt;, and the YouTube
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PL3XJli5z9VFd5c0xlrFZkqm_N0dOeWhPP&quot;&gt;playlist&lt;&#x2F;a&gt;
is the place to subscribe if you’d like a ping when new ones go up.&lt;&#x2F;p&gt;
&lt;p&gt;Feedback is welcome — what would you want to see demoed next?
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;orgs&#x2F;yoebuild&#x2F;discussions&quot;&gt;Open a discussion&lt;&#x2F;a&gt; or send a
&lt;a href=&quot;mailto:info@yoebuild.org?subject=%5Byoe%5D%20video%20feedback&quot;&gt;note&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What a Modern Embedded Linux Build System Could Look Like</title>
        <published>2026-05-11T00:00:00+00:00</published>
        <updated>2026-05-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/next-gen-embedded-linux/"/>
        <id>https://yoebuild.org/blog/next-gen-embedded-linux/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/next-gen-embedded-linux/">&lt;p&gt;Seven weeks ago we &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoebuild.org&#x2F;&quot;&gt;started experimenting&lt;&#x2F;a&gt; to find out.
The result is a tool that builds QEMU and Raspberry Pi images today, with Docker
support working. The goals driving the project, and where each one stands so
far:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Drastically improve developer productivity&lt;&#x2F;strong&gt; — shrink the loop between an
idea and a running image. Today: one binary, no SDK to install.
&lt;code&gt;yoe init &amp;amp;&amp;amp; yoe&lt;&#x2F;code&gt; opens a TUI with a live build progress bar, and &lt;code&gt;yoe run&lt;&#x2F;code&gt;
boots the image in QEMU. Background builds, search, and inline status sit in
one screen.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Easily integrate complex workloads&lt;&#x2F;strong&gt; — let modern languages keep their own
package managers, and let containers ride along. Today: Go modules build
end-to-end, and Docker runs on the resulting image. Rust, Zig, and Python ML
come next.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Scale to build anything&lt;&#x2F;strong&gt; — one tool, one mental model from small images to
distributed systems. Today: two modules (&lt;code&gt;module-core&lt;&#x2F;code&gt;, &lt;code&gt;module-rpi&lt;&#x2F;code&gt;)
covering x86_64 QEMU and Raspberry Pi, with QEMU user-mode emulation building
ARM64 on x86 — no cross-toolchain. Zephyr, AI workloads, distributed builds,
and farm-scale caching are still ahead.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There is a long way to go, and the risks are real. But seven weeks in — 38
releases, a working build flow — the path forward feels solid.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;yoe-build.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hello, [yoe]</title>
        <published>2026-05-02T00:00:00+00:00</published>
        <updated>2026-05-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://yoebuild.org/blog/hello-yoe/"/>
        <id>https://yoebuild.org/blog/hello-yoe/</id>
        
        <content type="html" xml:base="https://yoebuild.org/blog/hello-yoe/">&lt;p&gt;After years of maintaining and shipping products with the
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yoedistro.org&#x2F;&quot;&gt;Yoe Distribution&lt;&#x2F;a&gt;, we kept running into the same
friction — much of it inherited from how embedded Linux has historically been
built. We started fresh, kept the lessons that mattered most, and built the
tool we always wanted to use.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-we-kept&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-we-kept&quot; aria-label=&quot;Permalink to this section&quot;&gt;What we kept&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Machine abstraction and image composition.&lt;&#x2F;strong&gt; Yocto got a lot right here.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Module composition.&lt;&#x2F;strong&gt; Pulling units directly from GitHub URLs scales naturally to vendor BSPs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Tracking upstream closely.&lt;&#x2F;strong&gt; The cloud has been doing this for a decade.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;what-we-dropped&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-we-dropped&quot; aria-label=&quot;Permalink to this section&quot;&gt;What we dropped&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cross-compilation as the default.&lt;&#x2F;strong&gt; Modern ARM and RISC-V boards build
natively at full speed. Cloud CI runs arm64 cheaper than ever. QEMU user-mode
emulation covers the rest.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The SDK boundary.&lt;&#x2F;strong&gt; One Go binary builds the kernel, the rootfs, and the
application — no frozen sysroot, no drift between teams, one shared view of
the build.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Reinventing dependency resolution.&lt;&#x2F;strong&gt; Cargo, Go modules, pip, and npm
already solved this. &lt;code&gt;[yoe]&lt;&#x2F;code&gt; composes with them instead of replacing them.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Generated shell scripts.&lt;&#x2F;strong&gt; When something fails, you read the code you
wrote — not a stack trace deep in machine-generated output.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;what-we-re-betting-on&quot;&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#what-we-re-betting-on&quot; aria-label=&quot;Permalink to this section&quot;&gt;What we’re betting on&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI as a first-class interface.&lt;&#x2F;strong&gt; Starlark units, queryable graphs,
structured logs. An assistant that understands the system can take the
cognitive load of “which knob, and why” off the developer.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;One tool, three interfaces.&lt;&#x2F;strong&gt; AI conversation, interactive TUI, traditional
CLI — same engine, same commands. Use whichever fits the moment.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Functional equivalence over bit-for-bit reproducibility.&lt;&#x2F;strong&gt; Hermetic builds
and content-addressed input hashing, without the years-long effort required
for bit-perfect reproducibility.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;[yoe]&lt;&#x2F;code&gt; is pre-1.0 and moving fast. Take it for a spin and let us know how it
goes — we’d love to hear what works for you and what doesn’t.&lt;&#x2F;p&gt;
&lt;p&gt;The opportunity is here … come build the future of embedded Linux with us.&lt;&#x2F;p&gt;
&lt;p&gt;— Cliff Brake&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
