Mu: a human-scale x86 computer and testable toolchain
Soul of a tiny new machine. More thorough tests → More comprehensible and rewrite-friendly software → More resilient society.
At a glance
- What is it?
- Mu is an educational computing stack that translates memory-safe programs into small x86 binaries through SubX and bare SubX. It fits individual learners and experiments, but its limited hardware support, missing networking, and custom licence make it unsuitable for production services.
- Who is it for?
- Mu is appropriate for people studying how a small operating environment, compiler, emulator, and hardware abstraction can fit together. It is a poor choice for networked applications, portable software, clusters, or production services.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Assembly, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why Mu builds a computer for one person
Mu addresses the problem of making an entire computing stack understandable. It is intended for a hobbyist who wants to run one computer, or perhaps a few, without adopting a large service-oriented software stack. Its language, compiler, emulator, bootable runtime, and hardware-facing libraries are designed to be read and modified by an individual rather than hidden behind numerous framework layers.
The central technical decision is to begin with a 32-bit x86 instruction set and seek a safe syntax with as little translation as possible. Mu is therefore closer to machine code than many application languages. The README characterizes most Mu statements as mapping to a single machine instruction and describes the resulting programs as a thin memory-safe layer. This makes the relationship between source, generated code, processor behavior, and a failing test easier to follow.
The intended users are programmers studying computer architecture, programming literacy, low-level code generation, or test design. Mu is also relevant to people who want a small environment in which syntax changes can be evaluated through executable tests. It is not aimed at clusters, mass services, compatibility with mainstream stacks, or abstract productivity. Its hardware abstraction includes a screen, keyboard, polled PS/2 mouse, and slow ATA disk, but it does not attempt to reproduce the facilities of a full desktop or server operating system.
Mu, SubX, and bare SubX translate in stages
The stack has three named layers. Mu is the type-safe and memory-safe language used at the highest level. SubX is an unsafe notation for a subset of x86 machine code. bare SubX is a more rudimentary form of SubX with less syntax sugar. Each translator used at the lower stages is itself implemented in the layer beneath it. Specifically, the repository documentation says that the Mu-to-SubX translator is written in SubX and the SubX-to-bare-SubX translator is built in bare SubX.
This self-hosted arrangement is more than a list of names. It gives the repository a layered path from readable, checked source to machine-level output. It also means the translation process itself is part of what can be inspected and tested. The emulator for Mu's supported x86 subset has a separate role: the documentation says it is useful for debugging SubX programs and for systems, such as Macs, where direct builds are unavailable or substantially slower.
Mu supports two execution environments, and their requirements differ. A top-level program produces a bootable image that runs without an operating system. The supported environment is small: a 1024x768 screen, selected keyboard combinations, a PS/2 mouse that software must poll, and a slow ATA drive. There is no hardware acceleration, virtual memory, process isolation, multitasking, or network support. Boot executes the tests and proceeds to `main` only after they pass.
By contrast, programs under `linux/` are intended to run with a Linux kernel and ordinary standard input and output. The Mu compiler itself is implemented as `linux/mu.subx`. Programs in this area commonly accept a command-line `test` argument and run tests. The `linux/` libraries are also the stated likely path for future networking work, although the repository currently says that network interaction through Linux is unresolved.
Installing Mu and launching the Game of Life
The shortest documented first use clones the repository, translates `apps/life.mu`, and launches the resulting image in QEMU's 32-bit x86 system emulator. The clone command uses SourceHut rather than GitHub, even though this repository is viewed on GitHub.
git clone https://git.sr.ht/~akkartik/mu
cd muAfter cloning, `translate` reads the Mu application and emits a bootable `code.img`. The next command starts `qemu-system-i386` with that image as the machine image.
./translate apps/life.mu
qemu-system-i386 code.imgThe first command should create `code.img`; the second opens the emulated machine running Conway's Game of Life. If the program's tests fail, the boot design prevents entry to `main`, so an application image may stop with a test failure instead of reaching its normal entry point.
Native compilation is documented for Linux and for Windows through WSL 2. For Macs and other Unix-like systems, the documented alternative is emulated translation:
./translate_emulated apps/ex2.muThe README estimates two to five minutes for this emulated translation. That command should emit `code.img`, but it is not the same tutorial path as the Game of Life example and does not launch QEMU by itself. The repository does not document package-manager installation, dependency installation flags, or a release artifact.
Testing is part of Mu's execution architecture
Tests are not merely a separate quality-assurance layer in Mu. For a top-level boot image, passing the tests is a runtime prerequisite for reaching `main`. For programs in `linux/`, a command-line argument called `test` usually triggers testing. This arrangement connects the repository's stated interest in comprehensible changes with its actual boot and development paths.
The project uses dependency injection to expose hardware through testable interfaces. According to the README, tests can run against fake hardware and make assertions against it. Repository entries such as `500fake-screen.mu` reflect that direction, although the file name alone does not establish the full API. The README also describes automated white-box testing and associates it with assertions about areas such as performance, concurrency, and fault tolerance. It does not provide a general benchmark result for those capabilities.
The intended development loop is interactive. When behavior stops making sense, the README invites the reader to change it and observe which tests break. Well-named failures are part of the project's change-safety mechanism: a breaking alteration is expected to produce a visible failure rather than silently alter output. This is useful when the user wants to understand the compiler or runtime deeply, because tests can become executable documentation for low-level behavior.
There are limits to the evidence available here. The README does not publish a coverage percentage, test runtime, hardware compatibility list, or command for running the complete suite. It also states that native hardware has not been tested for top-level programs. The repository's many numbered files indicate a test-oriented organization, but their names and layout cannot establish that every platform is covered.
Mu's x86 and hardware boundaries narrow adoption
Mu requires a 32-bit x86 processor. Portability to other processor architectures is explicitly a non-goal; the maintainer suggests that such support could exist in separate forks. This is a reasonable boundary for an educational stack that wants to expose processor instructions directly, but it excludes several common modern deployment targets unless a suitable emulator is available.
The hardware surface is smaller still. Top-level programs have rudimentary screen, keyboard, mouse, and ATA support, with no operating-system services such as networking, virtual memory, process separation, or multitasking. The mouse must be polled. Programs must therefore accommodate the supported hardware model rather than assume the drivers and concurrency facilities expected on a general-purpose computer.
Performance and efficiency are also explicit non-goals. The author argues that remaining close to machine code should keep Mu sufficiently fast and that limiting abstractions should limit memory use, but the repository material does not provide measured throughput, startup time, or memory footprint. Those statements should therefore be read as design expectations, not adoption benchmarks.
Mu is the wrong tool for a networked service, a cluster, software that must run across processor families, or a project whose priority is compatibility with mainstream libraries. It is more appropriate for an individual studying bottom-up computer construction, experimenting with compiler layers, or building one small experimental program whose tests can describe its behavior.
Mu differs from conventional compilers and hosted runtimes
A conventional hosted application generally expects an operating system for libraries, process management, and I/O. Mu reverses that emphasis. Its language is intentionally thin over x86, its translators are built in lower stack layers, and a top-level program can emit an image that boots without an operating system. The result is closer to a readable computer platform than to a conventional hosted language.
The alternative within Mu itself is the `linux/` path. Instead of booting a bare image with a small set of peripherals, a program can rely on a Linux kernel and use standard input and output. The documentation describes this directory as fairly ergonomic and includes roughly a couple of dozen example programs. It is the more natural environment when eventual network support matters, although no networking implementation is documented as present.
This distinction also explains why compatibility is not a priority. Mu does not try to preserve interfaces from mainstream stacks. The README says the goal is to move away from those stacks and that a major version bump can be appropriate when behavior changes. For an evaluator, that means compatibility with an existing ecosystem should not be part of the adoption case. The question is whether a small, inspectable machine model and its tests fit the intended experiment.
Maintenance signals and the custom LICENSE.txt
The repository is not archived, and its last push was on 2026-04-02. The README separately says that development has slowed but contributions are still welcomed. There are no GitHub releases, so the repository does not provide a release channel or versioned artifact through GitHub Releases. Its main branch and documented source workflows are therefore the concrete basis for assessing maintenance.
The license is identified as `LICENSE.txt`, a custom license that GitHub cannot classify. The available project information does not reproduce its permissions, restrictions, redistribution terms, or patent provisions. As a result, an engineer cannot determine from the repository summary whether the code may be modified or redistributed in a particular organization. This is a material adoption issue even though the license is not an activation mechanism or a usage restriction on a service.
Before incorporating Mu into a longer-lived project, the first concrete check should be `LICENSE.txt`, followed by the required hardware and emulator environment. The relevant technical checks are narrower than they would be for a hosted language: 32-bit x86 support, the small peripheral set, boot-time tests, and whether the intended program belongs in the no-OS or `linux/` environment. Those boundaries, rather than an assumed release cadence, determine whether Mu is usable.
Editorial conclusion
Mu is appropriate for people studying how a small operating environment, compiler, emulator, and hardware abstraction can fit together. It is a poor choice for networked applications, portable software, clusters, or production services. Before adoption, verify the custom LICENSE.txt terms, confirm that the required x86 hardware or emulator matches the program, and run the project tests because boot refuses to reach `main` when they fail.
Frequently asked questions
How do I install and run Mu?
Clone the SourceHut repository, run `./translate apps/life.mu` to emit `code.img`, and start it with `qemu-system-i386 code.img`. Native builds are documented for Linux and Windows through WSL 2, while other Unix-like systems use `./translate_emulated`.
Does Mu support networking and modern operating-system features?
Networking is not supported yet. Top-level programs also lack virtual memory, process separation, multitasking, and hardware acceleration, although programs under `linux/` can run with a Linux kernel.
Can I run Mu on a Mac or a processor other than x86?
Macs and other Unix-like systems are documented as using the slower emulator path, but the processor itself must still be supported by the emulated x86 environment. Native portability to other processor architectures is an explicit non-goal.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/akkartik-mu)Was this useful?