# Droidspaces: a sub-400KB C runtime that boots real init systems on Android

> Droidspaces compiles one static musl binary against Linux namespaces and runs it unchanged on Android, Linux desktop and bare ramdisks. The repository language is Kotlin, but the runtime that does the work is C.

**ravindu644/Droidspaces-OSS** — A lightweight, LXC-like container runtime for Android and Linux. Run full Linux distributions natively with zero performance penalty

- Repository: https://github.com/ravindu644/Droidspaces-OSS
- Website: https://www.droidspaces.org
- Stars: 2,279 · Forks: 222
- Language: Kotlin
- License: GPL-3.0
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/ravindu644-droidspaces-oss

## One static musl binary across five architectures

The claim that defines Droidspaces is that it has no runtime dependencies at all. The README states it is statically compiled against musl libc, under 400KB per platform, and that the same binary covers `aarch64`, `armhf`, `x86_64`, `x86` and `riscv64`. That last part is what makes it unusual: one artifact per architecture, no glibc version negotiation, no Termux prefix, and therefore something that can run in places a normal dynamically linked binary cannot.

The environments the README names are the reason this design exists. Beyond Android and Linux desktop it explicitly targets Android recovery and ramdisk environments, where there is no package manager and no userspace conventions to speak of. If the kernel offers namespaces, the binary has what it needs.

The build system confirms the shape. Version is scraped out of a header rather than hardcoded in the Makefile:

```make
VERSION := $(shell grep "DS_VERSION" $(SRC_DIR)/include/droidspace.h | awk '{print $$3}' | tr -d '"')
```

The default compiler is plain `cc`, and parallel job count falls back through `nproc` and `sysctl -n hw.logicalcpu` to 4. There is a `V ?= 0` switch that turns full compiler commands into kernel-style short logs, which is a small sign of what the build is for: phones, where you watch a compile rather than wait for it.

## The runtime is C, the app is Kotlin, and GitHub only reports one language

GitHub reports Kotlin as the primary language for this repository. The Makefile at the root is a C build, and the source list is unambiguous about what the runtime consists of: `src/main.c`, `src/mount.c`, `src/cgroup.c`, `src/seccomp.c`, `src/pid.c`, `src/boot.c`, `src/container.c`, plus a `net/` directory holding `network.c`, `iptables.c`, `netlink.c` and `dhcp.c`, and an `android/` directory for platform-specific code.

Both facts are correct and they describe different halves of the project. The `Android/` directory at the top level holds the graphical application, and the README's screenshot gallery is entirely of that app: a home screen, a containers tab, a configuration menu, a systemd management screen, a user picker and a requirements checker. A Kotlin Android app is enough volume in bytes to become the reported primary language even though none of that code touches namespaces.

The practical consequence for a reader is that language badges tell you nothing about where to patch a bug. A mount namespace bug lives in `src/mount.c`; a container configuration bug in the Kotlin UI is a different repository's worth of reading. The tree also carries `DESIGN.md`, `AGENTS.md` and `CLAUDE.md` at the root, which is unusual for a project of this size and suggests the maintainers treat the split as something that needs writing down.

## Namespaces plus a real init system, not a chroot

Most Android Linux environments are chroots: a root filesystem copied or mounted in, with a package manager and no isolation. Droidspaces is built on Linux namespaces instead, and the README's navigation treats isolation as a headline feature rather than a footnote, including a dedicated Security & Isolation Philosophy section and a screenshot demonstrating isolated mounts.

What separates it further is the init system support. The README lists systemd, OpenRC, runit and s6, and the app gallery shows a systemd services screen with its own management view. Running real units rather than a supervision loop bolted onto a shell matters if you are moving software that expects to be started, restarted and queried as a unit.

The C source list explains how much of Linux this reimplements. `cgroup.c` and `seccomp.c` are process-control concerns that a chroot never has to deal with. `net/netlink.c` and `net/dhcp.c` mean networking is configured rather than assumed, and `pid.c` and `monitor.c` cover process lifecycle and health. `boot.c` and `init/` at the top level are what make the container look like a machine rather than a large shared directory.

The v6.6.0 release added journald inspection of units, so systemd is integrated at the level of reading logs, not only starting services.

## Kernel requirements are the real constraint, not the binary

The README's requirements section is the part worth reading before anything else, and it is not a formality. It separates Android rooting requirements, known quirks, and kernel requirements into Non-GKI legacy kernels and GKI modern kernels, which reflects the fact that Android kernel configuration varies by vendor and by generation.

Namespaces are the dependency. If the kernel was built without the namespace flags Droidspaces needs, the binary will not run no matter how portable it is, and the recovery and ramdisk environments the README advertises are precisely the cases where kernel configuration is least predictable. The mitigation the project offers is `Documentation/community-supported-devices.md`, a growing list of phones known to work, which is the file to consult before buying hardware for this.

The app also has a requirements checker screen that runs system checks in real time, so an install can tell you what is missing rather than failing later at container boot. That is a small design decision with real value on a device where the failure mode is otherwise an opaque error.

Two release notes from v6.6.0 belong in this section because they are security behaviour, not features. The build refuses to bind mount the host root into a container, and the app now greys out that folder picker at host root for bind mounts. Two separate commits for one restriction suggests it was found after the fact.

## Docker and Podman compatibility arrived as a flag

The v6.6.0 changelog ends with a feature line that says `--allow-sandboxing` for unprivileged Docker, Podman and comparable runtimes, and a companion documentation commit to describe the flag in one place. That is worth reading closely, because sandboxing in this context means something narrower than it does in the OCI world.

Droidspaces is not a container image format and does not try to be one. It is a runtime that hands a distribution an init system. Running it inside an unprivileged Docker or Podman sandbox means the outer runtime has already taken the namespace primitives Droidspaces wants to use itself, which is why the capability has to be explicitly granted rather than assumed.

The same release added support for accepting split-tunnel VPN routing tables as a pinned upstream, which is the networking counterpart. Android is a phone, and phones route through VPNs in ways a desktop host rarely does, so both flags come from the same pressure: running on the device people actually carry.

For display, audio and desktop use the README points to its own documentation rather than describing modes inline, and the related search traffic around this project clusters on Ubuntu chroot, Termux and Android chroot comparisons. That traffic is a fair summary of the question people arrive with, and chroot is the thing this project is not.

## Licensing is GPL-3.0, and the build carries a variant

The license is GPL-3.0 according to GitHub's metadata, the README badge points at a GPLv3 LICENSE file, and the Makefile header declares `SPDX-License-Identifier: GPL-3.0-or-later`. Those are consistent in family and not identical in wording, and the practical difference between GPL-3.0 and GPL-3.0-or-later is the patent grant, so it is worth reading the LICENSE file rather than trusting the badge or the metadata field.

Distribution is per-architecture static binaries, which makes redistribution straightforward and linking obligations straightforward with it. For a project whose stated purpose is running complete Linux distributions, GPL-3.0 is the unsurprising choice.

The repository is not archived and the last push was on 2026-09-28, with v6.6.0 released on 2026-09-21 and v6.5.5 a fortnight earlier on 2026-09-08. Release notes are a plain commit list, which makes them easy to audit and also easy to skim past; the substantive entries are the ones with a scope prefix like `feat(journald)` or `app: fix(security)`, and there are several of both in v6.6.0 alone.

Translations run through Weblate, with Arabic listed among the recent ones and a translation progress badge in the README. For an app whose first-run experience depends on someone understanding why a device failed a requirements check, that is a meaningful part of the project rather than a badge.

## Conclusion

Droidspaces is a good fit when the goal is a real Linux userspace on a phone, including a working init system rather than a Termux-shaped approximation, because the runtime is small, statically linked and built around namespaces rather than a compatibility shim. It is the wrong tool for unrooted Android, for anyone expecting Docker's image and networking model, and for workloads that assume cgroup and mount behaviour identical to a desktop host. Start from `make` in `src/`, read `Documentation/community-supported-devices.md` for a phone that is known to work, and treat the Kotlin-versus-C split as two projects in one repository rather than one codebase.

## FAQ

### Is Droidspaces the same thing as an Ubuntu chroot on Android?

No. A chroot only changes the root directory and shares the host's process and network namespaces. Droidspaces is built on Linux namespaces, with source files for mounts, cgroups, seccomp and netlink in `src/`, and it runs a full init system such as systemd or OpenRC inside the container.

### Do I need root or a custom kernel to run Droidspaces on Android?

The README's requirements section covers rooting requirements separately from kernel requirements and splits kernel needs into non-GKI legacy and GKI modern cases, which suggests both matter depending on the device. The community-supported-devices document lists phones known to work, and the app has a requirements checker that reports which system checks fail.

### What init systems can Droidspaces run inside a container?

The README names systemd, OpenRC, runit and s6, and the Android app includes a systemd services screen for managing units. The v6.6.0 release added journald inspection of units, so systemd logs are visible from the app as well as startable from it.

### Is the Droidspaces codebase Kotlin or C?

Both, and GitHub only reports Kotlin because the graphical app under `Android/` dominates the byte count. The runtime is C, built from `src/*.c` files including `mount.c`, `cgroup.c`, `seccomp.c` and `net/netlink.c` by a root Makefile that expects a plain `cc` compiler.

## Sources

- [License: GPL-3.0](https://github.com/ravindu644/Droidspaces-OSS/blob/main/LICENSE)
- [Project website](https://www.droidspaces.org)
- [ravindu644/Droidspaces-OSS on GitHub](https://github.com/ravindu644/Droidspaces-OSS)
- [README](https://github.com/ravindu644/Droidspaces-OSS/blob/main/README.md)
- [Releases](https://github.com/ravindu644/Droidspaces-OSS/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ravindu644-droidspaces-oss
