# FluidNC: Grbl's gcode contract on an ESP32, with a web UI and a YAML machine file

> The interesting decision is that you never compile it. You flash a release, upload a config.yaml describing your machine, and drive it from a browser. Everything else follows from that.

**bdring/FluidNC** — The next generation of motion control firmware

- Repository: https://github.com/bdring/FluidNC
- Stars: 2,576 · Forks: 651
- Language: C++
- License: NOASSERTION
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/bdring-fluidnc

## No compile step is the whole design

The README's Machine Definition Method section is the part to read twice. There is no need to compile the firmware: you use an installation script to upload the latest release, then create a config file describing your machine and upload that text file to the flash on the ESP32 over USB/serial or WiFi.

That inverts the usual embedded workflow. On stock Grbl you edit firmware source, set compile-time defines per axis and per stepper driver, and rebuild for each machine. On FluidNC the machine description is data, and it lives on the device. Multiple config files can be stored on the ESP32, with `config.yaml` as the default and a `$Config/Filename=<myOtherConfig.yaml>` setting to switch between them, which is how one board serves a laser in the morning and a router in the afternoon.

The consequence for a builder is worth stating plainly. You can change pin assignments, axis directions, steps per millimetre and limits from a text file over WiFi, which removes the compile-flash cycle from almost every adjustment. The cost is that a malformed config file is now a runtime failure rather than a build error, which is exactly why the project has invested in the tooling described below.

## Config file validation, including tools built for AI assistants

The README acknowledges the failure mode directly: writing a config file by hand, or with help from an AI assistant, can be error-prone given how many sections and fields FluidNC supports. The answer is a `tools/` directory holding a formal spec, a JSON Schema, a command-line validator, and an MCP server.

An MCP server is an unusual thing to find in a CNC firmware repository and it is a strong signal about who writes these files now. Rather than asking a model to guess at field names, the validator gives it a machine-readable contract to check against, and the schema serves the same purpose for editors with completion. If you are configuring this machine with an assistant rather than by hand, that validator is the difference between a working config and an afternoon of debugging.

The example configuration material reinforces the same point. `example_configs/` sits at the repository root alongside `examples/`, which contains `Parameters_List_Documentation.md`, `Parameters_List_Wiki_Section.md`, a `gcode_conditionals_test.nc` file and an `http_command/` directory. Generated parameter documentation from the source of truth is how a firmware with this many settings keeps its wiki honest, and v4.1.1 added a validator marker for it, annotated config items in the source with `@tuning` and `@default_note`, and fixed a ParallelDelta config documentation typo.

## Grbl compatibility means your sender still works

The intent stated in the README is to maintain as much Grbl compatibility as possible, and it is 100% compatible with day to day operation of running gcode with a sender. There is no change to the Grbl gcode send and response protocol, and all Grbl gcode is supported.

That is a deliberately narrow and practical compatibility claim. It means the layer your gcode sender speaks is unchanged, which is the part that would otherwise break every sender on the market. What did change is the settings surface: most of the `$` settings are replaced by readable items in the config file. So `$I` style introspection moves to a config schema, and a sender that reads settings for its own display will see something different from stock Grbl.

The credit line matters here too. The README credits Grbl itself to Sungeon (Sonny) Jeon, with the author saying he has used Grbl on many projects, and the WiFi and WebUI is based on the ESP3D-WEBUI project. FluidNC is a fork-lineage project in the most literal sense: Grbl's protocol, an ESP32 runtime, and a web front end borrowed from another community project.

Tool support is broader than the original, which is the practical gain. The README says it handles machine types including multiple tool types such as laser plus spindle or a tool changer, and v4.1.0 added unipolar motor support, VFD improvements, and TMC driver improvements mainly related to stallguard.

## WebUI3 over WiFi, plus telnet and an HTTP command interface

FluidNC includes a built-in browser-based Web UI, named in the README as Esp32_WebUI, so you control the machine from a PC, phone or tablet on the same WiFi network. That is the feature that most changes day to day operation, since a sender is no longer the only way in.

v4.1.0 lists WebUI3 tablet improvements among its features, specifically single step mode support and a visualizer that handles nested files, parameters and expressions. v4.1.1 updated the bundled WebUI to fix the tablet visualizer's probe-argument parsing, which is the kind of fix that only comes from someone actually driving a tablet on a real machine.

Telnet is there too, and v4.1.0 lists telnet improvements along with a fix for the telnet channel becoming unresponsive after connecting, on both esp32 and rp2040 targets. The repository also documents an HTTP command interface in `HTTP_Command_Guide.md` and `ASYNCWEB_API_USAGE.md`, with an `examples/http_command/` directory, which suggests machine state can be read and driven programmatically without a gcode sender at all.

The security question follows from the feature set. A device with WiFi, a web UI and telnet, controlling a machine with a spindle, is reachable by anything on that network. The README does not document authentication for the WebUI in the sections shown, which is a gap worth resolving on your own network before connecting a real spindle.

## Release history reads like a firmware hardening effort

The release notes are the best available evidence of what this project is actually doing, and they are mostly about failure modes rather than features.

v4.1.0, published 2026-09-12, describes itself as a large set of fixes for crashes and other problems present in v4.0.4, plus stability work through reduced baseline memory usage. Its feature list includes GCode single stepping, unipolar motor support, telnet improvements, config files allowing comments at the end of a line rather than only on their own lines, GCode clustering for optimised transfer of laser rasters, VFD improvements, TMC driver work on stallguard, and the WebUI3 tablet improvements. It also restored FatFs SD usage statistics and fixed stalls in the timed engine on both esp32 and rp2040.

v4.1.1, published 2026-09-25, is the more revealing list because it is almost entirely defensive. An unusable SD card should report rather than reboot the controller. A recursive file listing should not reset the board. A too-high stepping rate should not take the machine down. The low-memory warning should be emitted without allocating in order to emit it. An abandoned file transfer should not strand the upload file descriptor. Laser and spindle power not updating during motion is fixed as a regression from an earlier change, and soft limit alarm reporting is improved.

A firmware that decides what to do when the SD card is unreadable, or when a step rate is impossible, is a firmware that has been used on real machines. That is the strongest signal in the notes, and it is also why v4.1.0 upgrading from v4.0.4 is the sensible path rather than staying on a pre-4.1 build.

## Building, testing and the unusual corners of the tree

Building is PlatformIO based. `platformio.ini` and `platformio_override.ini` sit at the root, `packages.config` and `requirements.txt` pin the environment, and the requirements file is a single pinned line:

```text
platformio == 6.1.*
```

Packaging is scripted rather than manual: `build-release.py` and `build_merged.py` produce the release artifacts, `git-version.py` derives version strings, and `install_scripts/` holds what the README calls the installation script you use to upload the latest release. `min_littlefs.csv` in the root is a filesystem image manifest, which tells you the web UI assets are packed into a LittleFS partition on the ESP32.

The testing story is broader than most firmware repositories manage. There is `fixture_tests/`, `X86TestSupport/`, `coverage.py`, `coverage_build.py`, `CodeCoverage.cov`, `test_exceptions.cpp`, `filter_lib_test.py`, and a Visual Studio project set (`FluidNC.sln`, `UnitTests.vcxproj`) generated by `generate_vcxproj.py`, with `CodingStyle.md` and `.clang-format` defining the house style. Running unit tests on x86 alongside the embedded target is what makes the coverage number mean anything.

A few root files are working notes rather than project structure: `CHAT_HISTORY_2026-03-09.md`, `CHAT_HISTORY_2026-03-13_SIMULATOR_ENGINE.md`, `CHAT_HISTORY_2026-03-13_WEBSOCKET_SIMULATOR.md`, `WEBSOCKETPP_INTEGRATION_PLAN.md`, `CONFIG_ITEM_ISSUES.md` and `OUTPUT_SUPPRESSION_ANALYSIS.md`. They document in-progress simulator and websocket work and known config problems, which is useful colour about the project's current direction. Note that the repository reports no recognised licence identifier, so check `LICENSE` at the root directly before building on it commercially.

## Conclusion

FluidNC is the right firmware when you are building a CNC on an ESP32 and you want browser control, WiFi, and machine definition you can change without a rebuild. It is the wrong choice when your controller board is not an ESP32, or when you need the deeper community around stock Grbl on AVR and STM32. The repository is not archived and the last push was on 2026-09-27, with v4.1.1 on 2026-09-25 and v4.1.0 on 2026-09-12, and the v4.1.0 notes describe that release as a set of crash and stability fixes over v4.0.4 plus baseline memory reduction. Read `wiki.fluidnc.com/en/config/overview` before flashing anything, then run the validator from `tools/` against your config.yaml, and use the WebUI on a network you trust.

## FAQ

### What are the key differences between Grbl and FluidNC?

FluidNC is firmware for the ESP32 and is described as the next generation of firmware from the creators of Grbl_ESP32. It keeps the Grbl gcode send and response protocol unchanged and supports all Grbl gcode, so day to day sending works the same, but most `$` settings are replaced by readable items in a config file, and there is no compile step: you flash a release and upload config.yaml. It also adds a browser-based WebUI, WiFi, and hardware abstraction for tool types like laser, spindle or tool changer.

### How do I install FluidNC on an ESP32 device?

There is no need to compile the firmware. You use an installation script to upload the latest release to the ESP32, then create a config file describing your machine and upload it to the device's flash over USB/serial or WiFi. The default config filename is config.yaml, and `$Config/Filename=` switches between multiple configs stored on the ESP32. The `tools/` directory holds a JSON Schema and a command-line validator for checking that file.

### What are the commands used in FluidNC?

All Grbl gcode is supported and the gcode send and response protocol is unchanged, so an existing sender works without modification. The difference is in settings: most `$` settings have been replaced by readable items in the config file rather than being typed as commands. Configuration reference material lives at wiki.fluidnc.com, with generated parameter documentation in the repository's examples directory.

## Sources

- [bdring/FluidNC on GitHub](https://github.com/bdring/FluidNC)
- [Issues](https://github.com/bdring/FluidNC/issues)
- [README](https://github.com/bdring/FluidNC/blob/main/README.md)
- [Releases](https://github.com/bdring/FluidNC/releases)

---

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