Nerves: Elixir firmware images for embedded devices
Craft and deploy bulletproof embedded software in Elixir
At a glance
- What is it?
- Nerves is a set of tooling and libraries for building small, self-contained firmware images in Elixir on top of the Erlang VM and the Linux kernel. It is aimed at Elixir developers who want to ship to boards such as the Raspberry Pi or BeagleBone without running a full embedded Linux distribution.
- Who is it for?
- Nerves suits Elixir teams whose device logic wants OTP supervision, Phoenix LiveView interfaces or Nx computation on a board, and who are willing to learn Buildroot when they need something outside the Erlang runtime. It is the wrong tool if you need a general-purpose Linux userland, a non-Erlang application, or a board with no maintained system package in the nerves-project organization.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Elixir, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What Nerves is for, and who it is aimed at
The README describes Nerves as "tooling and libraries for building small, self-contained software images" that combine the Erlang virtual machine, Linux hardware support and Elixir. The audience is specific: developers who already write Elixir and now need that code to run on a microprocessor-based board.
The design centre is not a general embedded Linux distribution. The README states plainly that Nerves "is not a Linux distribution, though, and contains little of what you would find on a typical embedded Linux system". Instead it starts the Erlang runtime as one of the first OS processes and lets Erlang and Elixir take over. That inversion is the whole point. Your supervision tree is the init system, and the Linux userland you would normally maintain shrinks to almost nothing.
Because it is Elixir, the surrounding ecosystem carries over. The README lists Phoenix and LiveView for local web interfaces, Elixir Nx for numerical computing and machine learning, Livebook for notebooks on the device, and Scenic for on-screen interfaces. It also notes Nerves "only includes what you use so your embedded software can remain small". That last sentence is the trade-off in miniature: you get a small image because nothing is included by default, including things you may later assume are there.
How the Erlang VM takes over from init
The core mechanism is that Erlinit, described in the README as a "replacement for /sbin/init that launches an Erlang/OTP Release", becomes the first process, and the OTP release becomes the operating environment. Everything above that is ordinary Elixir: applications, supervision trees, GenServers.
Images are assembled with Buildroot. The README states that if you need something from Linux, Nerves "provides a way to use most of the packages available through Buildroot". This is the escape hatch and the boundary at the same time. A C library or a system daemon can be pulled in through the Buildroot-based build platform, but it arrives as a build-time dependency of the system, not as something you install on a running device.
The work is spread across repositories on purpose. The README says the project is "spread over many repositories in order to focus on a limited scope per repository", and this one is "an entrance to Nerves and provides the core tooling and documentation". The pieces you will actually meet are Nerves.Bootstrap (the new project generator and Mix hooks), Nerves.Runtime (small runtime utilities on the device), NervesPack (initialization setup), NervesSystemBR (the Buildroot build platform) and RingLogger (a ring buffer backend for Elixir Logger with IO streaming). Hardware support lives in separate system packages such as NervesSystemRPi for the Raspberry Pi A+ and B+, NervesSystemRPi0 for the Zero and Zero W, NervesSystemBBB for BeagleBone-based boards, and NervesSystemOSD32MP1 for the Octavo OSD32MP1.
One detail worth knowing before you file a bug: this repository contains a host-side C program, the port monitor, built by the Makefile. The Makefile comments say "This code is always run on the host as opposed to nearly everything else with Nerves" and that it "explicitly references the host compiler (non-crosscompiler)". If you are cross-compiling, that is why CC_FOR_BUILD must be set; the Makefile also documents MIX_APP_PATH, CFLAGS_FOR_BUILD and LDFLAGS_FOR_BUILD as variables you can override.
Getting the core tooling and building a first image
This repository is the entrance to Nerves and carries the core tooling, but the README does not reproduce install or build commands. It points at the guides/ directory for documentation and at the Hex package manager for libraries, and it names Nerves.Bootstrap as "The Nerves new project generator and low level hooks into Mix".
What the repository does give you is the host-side build of the port monitor. The Makefile documents its own targets and variables in comments: all/install builds and installs, clean removes build products, and MIX_APP_PATH points at the build directory. The port binary lands at $(MIX_APP_PATH)/priv/port, with object files under $(MIX_APP_PATH)/obj. The default flags are visible in the file, so you can see exactly what the host compiler is asked to do.
PREFIX = $(MIX_APP_PATH)/priv
BUILD = $(MIX_APP_PATH)/obj
PORT = $(PREFIX)/port
CC_FOR_BUILD ?= $(CC)
CFLAGS_FOR_BUILD ?= -O2 -Wall -Wextra -Wno-unused-parameter
CFLAGS_FOR_BUILD += -std=c99 -D_GNU_SOURCEBecause the port monitor runs on the host rather than the target, the Makefile warns that CC_FOR_BUILD "MUST be set if crosscompiling". If your build fails while cross-compiling, that variable is the first thing to check.
For the device side, the README's Hardware table is the list of system packages to choose from: nerves_system_bbb, nerves_system_osd32mp1, nerves_system_rpi and nerves_system_rpi0. The README does not document the firmware image path or the flashing procedure, so treat guides/ as the source for those steps rather than guessing at a filename.
Where Nerves stops being the right tool
The most concrete limitation is stated by the project itself: Nerves contains little of what you would find on a typical embedded Linux system. If your product depends on a general-purpose userland, on package management at runtime, or on running a non-Erlang application as the primary workload, this is not the platform for it. You would be fighting the design rather than using it.
Board support is bounded by the system packages that exist. The README lists four officially supported hardware ports (BeagleBone-based boards, Octavo OSD32MP1, Raspberry Pi A+ and B+, Raspberry Pi Zero and Zero W) and notes that "many others exist in the community". Community systems are maintained by their respective organizations, not by the Nerves core team. That is a real support boundary: a board with a community system is a different risk profile from one on the official list.
Adding Linux components means going through Buildroot, which is a build-time activity with its own learning curve. There is no documented path in the README for installing a package onto a running device.
Finally, the repository does not state a single project-wide licence. The README carries an SPDX-License-Identifier of CC-BY-4.0 for the file itself, the Makefile is marked Apache-2.0, and the repository has LICENSES/ and REUSE.toml entries, which points to per-file licensing. Anyone evaluating Nerves for a commercial product should read those files rather than assume one licence covers everything.
Nerves compared with Buildroot and Yocto on their own
The obvious alternative is using Buildroot directly, or a Yocto-based distribution, and writing the application in C or C++ or in a language you cross-compile yourself. Nerves does not replace Buildroot: NervesSystemBR is described as the "Buildroot based build platform for Nerves Systems", so Buildroot is underneath either way.
The difference is what sits on top. In a conventional Buildroot image, you assemble a root filesystem, choose an init system, and your application is one more package in that image. In Nerves, the Erlang runtime starts as one of the first OS processes and the OTP release is the application environment. Configuration, logging, networking and process supervision are Elixir concerns rather than shell scripts and systemd units.
That difference cuts both ways. You gain OTP's supervision and runtime model, and you can reuse Phoenix, Nx or Livebook as the README lists. You lose the familiarity of a normal Linux system and the ability to drop in arbitrary prebuilt binaries without going through the Buildroot build. A team with deep Yocto experience and a C codebase will find Nerves to be a rewrite, not a migration.
Maintenance, releases and upgrade cost
The repository is not archived and the last push was on 2026-09-21. Recent releases are v1.15.0 on 2026-07-13, v1.14.3 on 2026-06-12 and v1.14.2 on 2026-05-23, so the release cadence over that period is roughly monthly. There is a CHANGELOG.md, a RELEASE.md and a compat/ directory at the top level, which is where upgrade notes and compatibility information would live; the README does not summarise them.
Upgrade cost is not only this repository. A Nerves project pins a system package, and the system package pins the Buildroot version and the kernel. Moving the Nerves version can therefore drag the system package along with it, and a system package upgrade can change the Linux side of the image. The compat/ directory exists precisely because those versions have to agree, and the README does not document rollback or downgrade procedures.
On licensing, the only facts visible in the repository are the per-file markers: the README is CC-BY-4.0, the Makefile is Apache-2.0, and there are LICENSES/ and REUSE.toml entries. No single licence identifier is stated for the project as a whole, so verify the terms of the specific system package and any Buildroot components you enable before shipping.
Editorial conclusion
Nerves suits Elixir teams whose device logic wants OTP supervision, Phoenix LiveView interfaces or Nx computation on a board, and who are willing to learn Buildroot when they need something outside the Erlang runtime. It is the wrong tool if you need a general-purpose Linux userland, a non-Erlang application, or a board with no maintained system package in the nerves-project organization. Before committing, read the guides/ directory for build requirements, confirm a Nerves system exists for your exact board, and check the repository's LICENSES/ directory and REUSE.toml for the per-file licence terms.
Frequently asked questions
What is Nerves?
Nerves is a set of tooling and libraries for building small, self-contained software images using the Erlang virtual machine, Linux hardware support and Elixir. This repository is the entrance to the project and provides the core tooling and documentation.
How do I use Nerves to start a project?
The README does not give install commands. It lists Nerves.Bootstrap as the new project generator and low level Mix hooks, and points at the guides/ directory in the repository for documentation, so start there.
Which boards does Nerves support?
The README lists officially supported ports for BeagleBone-based boards, Octavo OSD32MP1, the Raspberry Pi A+ and B+, and the Raspberry Pi Zero and Zero W. It also notes that many other ports exist in the community and are maintained by their respective organizations.
Is Nerves a Linux distribution?
No. The README states that Nerves is not a Linux distribution and contains little of what you would find on a typical embedded Linux system. It starts the Erlang runtime as one of the first OS processes and lets Erlang and Elixir take over.
Can I add Linux packages to a Nerves device?
The README says that if you need something from Linux, Nerves provides a way to use most of the packages available through Buildroot. That happens through the Buildroot-based build platform, NervesSystemBR, rather than at runtime on the device.
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/nerves-project-nerves)
Community notes