Open-source project
p2r3/bareiron avatar
p2r3/bareiron

bareiron: a Minecraft server small enough for an ESP32

Minimalist Minecraft server for memory-restrictive embedded systems

4,444 stars266 forksCGPL-3.0

At a glance

What is it?
A C implementation of the Minecraft 1.21.8 server that trades vanilla fidelity for a small memory footprint, configured entirely at compile time. Worth a look on microcontroller-class hardware, wrong for anyone who wants chunk-faithful behaviour out of the box.
Who is it for?
Adopt bareiron if you want a Minecraft server on an ESP32 or another microcontroller and can accept a reduced feature set, a vanilla-only client and a compile-time-only configuration workflow. Do not adopt it if you need Fabric clients, vanilla-exact block behaviour, or settings you can change while the server runs.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 84 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • p2r3/bareiron4,444 ★ · +44
Star history
Repository2026-09-232026-11-14
p2r3/bareiron4.4k4.4k

44 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The priority list is written into the source

Memory usage comes first, performance second, features third, and the README states plainly that compliance with vanilla Minecraft is "not guaranteed, nor is it a goal of the project." That sentence tells you what kind of server this is before you read a line of code. It targets very weak devices such as the ESP32, where a normal Java server is not a candidate at all, and it accepts protocol differences as the price of fitting.

The version it speaks is Minecraft 1.21.8, protocol 772. On PC x86_64 you can grab the latest build binary and run it directly, but the file is a Cosmopolitan polyglot, so the same executable runs on Windows, Linux and possibly Mac despite the .exe extension. There is a warning worth reading before you plan a community around it: only the vanilla client is officially supported, and issues have been reported with Fabric or similar clients. This is a single-player-on-a-chip or a handful-of-friends setup, not a public server.

Compiling starts with a vanilla server jar, not with the source

This is the part that surprises people. Before gcc ever sees the code, you have to produce registry data from a genuine Minecraft server. On Linux the extract_registries.sh script automates it. Otherwise the manual path is: create a folder called notchian in the repository root, drop a Minecraft server JAR into it, run the data generator described in the linked wiki page using the second command with the --all flag to dump every registry, and then run build_registries.js with bun, node or deno. None of the C code means much without that generated data, so treat the registry dump as a prerequisite rather than an optional extra.

On Linux, the README says to install gcc and run ./build.sh.

The Windows paths differ enough to matter. MSYS2's MINGW64 shell gives you a native Windows binary via pacman -Sy mingw-w64-x86_64-gcc, the MSYS shell gives you one linked against MSYS2 with pacman -Sy gcc, and WSL lets you build and run the Linux binary from Windows. Cross-compiling for Windows 95 and 98 is a real, supported target, reached by swapping the package for mingw-w64-cross-gcc and passing a flag to the build script.

build.sh and the --9x cross compile

Once the registries exist, every platform funnels through a single shell script. Linux is the shortest form:

bash
./build.sh

The 32-bit target that keeps Windows 9x compatibility takes an argument rather than a different script:

bash
./build.sh --9x

For the native Windows toolchain, the pacman line installs the compiler and then the same script runs from the project directory:

bash
pacman -Sy mingw-w64-x86_64-gcc
./build.sh

Microcontrollers take a different route entirely. You set up a PlatformIO project on the ESP-IDF framework, explicitly not Arduino, and clone the repository on top of it. The README also points at raising the clock speed and enabling compiler optimisations for better performance. How you set the clock is left to you, which tells you how little of this is hand-held.

Every knob lives in include/globals.h, at compile time

There is no config file and no command line. The server's default settings cannot be reconfigured without compiling from source, and that applies to the ready-made PC binary too. Most options are in include/globals.h, including WiFi credentials for embedded builds, while MOTD and starting time of day sit in src/globals.c. Anything else means reading the C.

The three options the README singles out are the interesting ones, because each trades something for something. BROADCAST_ALL_MOVEMENT and SCALE_MOVEMENT_UPDATES_TO_PLAYER_COUNT control position broadcasting, which can saturate a narrow link on a slow MCU; commenting both out ties movement to the tickrate instead, and if that looks too choppy you lower TIME_BETWEEN_TICKS at the cost of more compute. ALLOW_CHESTS and DO_FLUID_FLOW exist because chests and water are named sources of crashes, so you switch off the feature rather than debug it. VISITED_HISTORY controls how often chunks regenerate, and the arithmetic given for it is worth trusting: raising it to 64 costs 240 extra bytes per allocated player.

world.bin on PC, LittleFS or a raw TCP dump on the chip

On PC platforms world and player data are written to world.bin by default and nothing else is required. On microcontrollers that file has to survive a power cut, and the simple path is to set up LittleFS in PlatformIO and remove the #ifndef wrapping SYNC_WORLD_TO_DISK in globals.h. Flash writes are slow and blocking, so DISK_SYNC_BLOCKS_ON_INTERVAL is there to be enabled, and MAX_BLOCK_CHANGES may need lowering so the world fits inside whatever LittleFS partition your board has.

An SD card or another virtual file system means writing the filesystem setup routine yourself. The serializer still works, since it uses POSIX calls.

The third route is the one to read twice. Uncommenting DEV_ENABLE_BEEF_DUMPS lets any client with access push arbitrary world data over TCP. The README attaches its own warning: this system implements no security or authentication. Do not expose that port beyond a bench network.

What you give up against Minestom and vanilla

bareiron re-implements the server in C and accepts divergence from vanilla to stay small, and it is written for very weak devices such as the ESP32.

The consequence is the reduced feature set and the client caveat. Vanilla client only is the supported path, and block behaviour will not match the game everywhere. Any plan that depends on exact vanilla mechanics is the wrong plan for this codebase.

Contributing means fitting the existing style, not adding tooling

The contribution notes are unusually direct for a project this size. Open an issue and discuss with the maintainer before writing a pull request, even for something small. Match the surrounding code style even if you disagree with it, because inconsistent patches get picked apart. Test before you ask for a review.

The line that will stop most contributors sits at the end: development tooling and compilation improvements are not welcome unless you have worked in the codebase long enough to have hit a practical shortcoming there. Adding one compiler flag is not a first contribution.

The licence is GPL-3.0, and the repository is not archived. The last push was on 2026-08-22, and the latest build release is dated 2025-09-09, so the binary is older than the source.

Editorial conclusion

Adopt bareiron if you want a Minecraft server on an ESP32 or another microcontroller and can accept a reduced feature set, a vanilla-only client and a compile-time-only configuration workflow. Do not adopt it if you need Fabric clients, vanilla-exact block behaviour, or settings you can change while the server runs. Before anything else, dump the registries from a vanilla server jar into the notchian folder and run build_registries.js, because nothing in the C sources compiles without that generated data.

Frequently asked questions

What hardware can bareiron run on?

The project targets very weak devices such as the ESP32, with PlatformIO and the ESP-IDF framework as the microcontroller path. On PC it ships as a Cosmopolitan polyglot binary that runs on Windows, Linux and possibly Mac.

How do you configure a bareiron server?

Configuration happens at compile time only. Most options, including WiFi credentials for embedded builds, live in include/globals.h, with MOTD and starting time of day in src/globals.c. The server's default settings cannot be changed without building from source.

Can I connect to a bareiron server with a modded Minecraft client?

The README warns that only the vanilla client is officially supported, and that issues have been reported with Fabric or similar. Treat a modded client as unsupported rather than as a feature.

Does bareiron save world data on a microcontroller?

Not by default on ESP targets, which is what the optional non-volatile storage section is for. Set up LittleFS in PlatformIO and remove the #ifndef around SYNC_WORLD_TO_DISK, and expect to tune MAX_BLOCK_CHANGES to fit your partition.

Is the TCP world data upload in bareiron safe to expose?

Uncommenting DEV_ENABLE_BEEF_DUMPS lets a client push arbitrary world data over TCP, and the README states that this system implements no security or authentication. Anyone with access to the server can upload world data.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. p2r3/bareiron on GitHub
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/p2r3-bareiron.svg)](https://hysenlabs.com/projects/p2r3-bareiron)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/p2r3-bareiron.svg)](https://hysenlabs.com/projects/p2r3-bareiron)

Was this useful?