esp-idf-template: the cargo new that actually builds for an ESP32
A "Hello, world!" template of a Rust binary crate for the ESP-IDF framework.
At a glance
- What is it?
- esp-idf-template is a cargo-generate template that gives you a Rust binary crate wired to the ESP-IDF framework, with target triples per microcontroller, a choice of ESP-IDF versions and optional Wokwi or dev container support. It fits a Rust developer starting a firmware project, and it inherits the community effort caveats the README spells out.
- Who is it for?
- esp-idf-template fits a Rust developer who wants a working ESP-IDF firmware crate on the first build rather than a hand-assembled toolchain, and who will pick a stable ESP-IDF tag rather than master. It is the wrong choice for a team that needs the hardware-in-the-loop tests the esp-idf crates currently lack, for a project that must track the newest ESP-IDF release day one, or for a build that has to work on Windows without the WSL2 route the README documents.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 32 days ago.
- What is it written in?
- Mainly CMake, 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
A cargo new that produces something that compiles for the chip
The template exists to solve one specific and very common failure. Running cargo new gives you a crate that builds for your desktop, not for an ESP32, and turning it into firmware that links against the ESP-IDF framework takes more than a target flag: you need the build script, the sys crate bindings, the linker configuration and the right target triple.
The README describes the result plainly: this is the crate you get when running cargo new, but augmented with extra configuration so that it does build for the ESP32 family with ESP-IDF and, by default, with STD support. That last clause matters more than it looks. Rust firmware on a microcontroller usually means no standard library, and the template defaults to having it, which is the more comfortable starting point for people who want to write application code rather than fight the allocator.
The mechanism is cargo-generate, a general purpose project generator for Rust. You point it at a GitHub repository and a template name, and it asks you a set of questions and writes a project. The template is hosted as a GitHub repository, so it is also something you can fork and adjust for your own organisation.
The audience is a Rust developer starting a firmware project on an Espressif microcontroller, and the topics list confirms the scope with a single tag, cargo-generate, which is honest about what this repository is: not a framework, but a starting point for one.
The licence is dual, with LICENSE-APACHE and LICENSE-MIT files at the repository root, and the last push was on 2026-09-21 with the repository not archived.
Generating the project and the questions it asks
The generation step is one command, and the README asks you to make sure you have installed the prerequisites first:
cargo generate esp-rs/esp-idf-template cargoThe prompts it then asks are worth walking through, because each one changes the output.
The first is the Project Name, which is the name of the crate. The second asks which MCU to target, listing SoC models such as esp32, esp32s2 and esp32c3. The third asks whether to configure advanced template options, and answering false skips the rest and uses their defaults.
If you answer true, you are asked for the ESP-IDF version, as a branch or tag. The list offers v6.1, v6.0.3, v5.5.5, v5.4.4 and v5.3.6, each marked as stable, plus master, which is marked unstable. The README is unusually direct about master: please do not choose the master ESP IDF version unless you really have a very good reason to, because building against ESP-IDF master is not officially supported and can break any time.
Two further options are then offered. One asks whether to configure the project to support Wokwi simulation with the Wokwi VS Code extension. The other asks whether to configure the project to use dev containers, for VS Code Dev Containers and for GitHub Codespaces. The dev container option is described as also allowing flashing from the container using web flash, and as coming with the Wokwi extension already installed.
One subtlety sits above all of these. A note says that if you have set IDF_PATH, the specified ESP IDF SDK will be used instead regardless of what version you selected in the prompt, and that esp-idf-sys will just ignore IDF_TOOLS_PATH. So on a machine with a system-wide ESP-IDF, the version question in the generator is answered by your environment rather than by you, and that is worth knowing before you spend time choosing a tag.
Target triples differ per architecture, and the table is the thing to memorise
The reason the template has to ask which MCU you are targeting is that ESP-IDF supports two instruction set architectures, and the Rust target triple changes with them. The README tabulates eight of them.
The Xtensa chips, the original ESP32, the ESP32-S2 and the ESP32-S3, use xtensa targets: xtensa-esp32-espidf, xtensa-esp32s2-espidf and xtensa-esp32s3-espidf.
The RISC-V chips use riscv targets, and here the table shows why asking the question matters. The ESP32-C2 and the ESP32-C3 share riscv32imc-esp-espidf, the ESP32-C6 and the ESP32-H2 share riscv32imac-esp-espidf, and the ESP32-P4 uses riscv32imafc-esp-espidf. Two chips sharing a target is not an error in the table, it reflects that the instruction set extension matches, though the C6 and H2 also share a target despite differing peripherals, which means the chip-specific configuration still has to be handled elsewhere in the project.
The same partitioning explains why the project description says the ESP32 family rather than naming a chip. The template is not a single firmware target, it is a set of them, and the generated project carries the one you chose.
This is also the point where a Rust developer hits the first real difference from desktop Rust. The target triple has an espidf suffix rather than a bare architecture, because the Rust standard library for these targets is the esp-idf one, and that is the piece that lets a crate with STD support link against the ESP-IDF C libraries.
Build, flash and monitor: three commands
After generation, the workflow is short enough to state in full.
Build, from the project directory:
cd <your-project-name>
cargo buildFlash, from the root of the generated project:
espflash flash target/<mcu-target>/debug/<your-project-name>The README replaces the two placeholders for you, telling you to substitute the name of the generated project and to use your chosen MCU target in the path. The path structure is worth noting: the binary lands under a target directory named after the chip, in a debug profile, so the flash command is a direct pointer at the build artefact rather than something espflash has to search for.
The flash tool is friendly about hardware. The README says espflash will print a list of the recognized USB ports for you to select the desired port if it detects multiple boards. You can also add the --monitor argument to open a serial monitor after flashing, and the README links the espflash README for more on its usage.
Monitoring on its own is a separate command:
espflash monitor /dev/ttyUSB0You replace the device path with the port where the board is connected, and if you do not specify any USB port, cargo-espflash or espflash prints the list of recognized ports for you to pick from.
The expected output is included in the README as a sample boot log, from the chip's reset banner through the CPU start lines and the heap and flash detection lines. It is a useful sanity check for a first run, since a build that produced no output at all is the failure people hit first, and the README also links a Wokwi project so you can simulate the board without hardware at all.
The community effort caveat is the most useful paragraph in the README
Before the workflow, the README has a section titled Community Effort, and it is the most important content for anyone making a decision.
It states that all the esp-idf-* crates are a community effort, in that Espressif puts little to no paid developer time into them. It then draws a contrast: ESP-IDF itself is very popular and well tested, while the esp-idf-* crates might be a bit lagging behind the latest stable ESP-IDF version, are currently missing HIL tests, and need more documentation.
Three separate limitations, and they are different in kind. Lagging behind the latest stable version is a schedule problem, and it is one the version selection in the generator partly addresses, since you can pin to a specific tag. Missing HIL tests is a confidence problem, and it applies to the hardware-in-the-loop layer of the stack rather than to the template itself. Needing more documentation is an adoption cost that you pay while learning the API.
The distinction between the framework and the Rust bindings is the one to hold on to. The C framework is Espressif's product, tested and supported. The Rust layer is volunteers' work on top of it, and the README is clear that Espressif does not fund it.
For a hobbyist or a prototype, this is a reasonable trade. For a product with a maintenance commitment, the missing HIL tests and the documentation gap are the two things to raise with whoever owns the risk, because neither is fixed by choosing a different version number in the generator prompt.
The other three project shapes, and what the template does not cover
The README points to three alternatives depending on how you want to mix Rust with the rest of ESP-IDF, and it is worth understanding what each is because the template is not the only entry point.
The first is the traditional ESP-IDF idf.py CMake project, with instructions in a separate README-cmake file. In that shape, C and C++ live in the ESP-IDF project structure and Rust is pulled in as a component, rather than Rust owning the build. There is a second file, README-cmake-details, which suggests the CMake path has more detail to it.
The second is PlatformIO, with instructions in a README-pio file, for people who want the PlatformIO workflow rather than idf.py.
The third is development on Windows or WSL2, with instructions in a section of the main README. This is not an alternative project shape but an environment note, and it points to the Linux environment path that ESP-IDF development is documented around.
What the template does not cover is worth stating too. The repository root holds the cargo and cmake directories, the three README variants, a CHANGELOG.md, and the two licence files. There is no firmware beyond a Hello World, no example of using the peripherals, no driver layer and no application structure. The generated project is a starting point that compiles, links and flashes, and everything above that is yours to build.
The two extra directories, cargo and cmake, are the parts of the template that are not Rust source at all. They carry the cargo-generate configuration, which is what makes the prompts appear and the conditional files get rendered, and the CMake glue for the mixed-language path. The primary language of the repository is listed as CMake rather than Rust for exactly that reason.
Where esp-idf-template is the wrong tool
The first wrong-tool case is a team that needs hardware-in-the-loop testing. The README says the esp-idf crates are currently missing HIL tests, and HIL is exactly what catches the class of bug where firmware builds, flashes, and behaves incorrectly on real silicon. A project shipping to customers and relying on that layer is taking a risk the README names.
The second is a project that must use the newest ESP-IDF release. The template's version list stops at v6.1 with v6.0.3, v5.5.5, v5.4.4 and v5.3.6 below it, and master is explicitly not supported. If Espressif has released something newer than the newest stable tag in that list, you are building against an older framework or against an unsupported branch.
The third is a team that already has its own ESP-IDF build pipeline. The template assumes it owns the build configuration. If your organisation standardises on idf.py or PlatformIO with its own component layout, the CMake and PlatformIO routes exist in the same repository, but the value of the template drops to a set of prompts and a set of working configuration snippets.
The fourth is a Windows-only team without appetite for WSL2. The README has a section on WSL2 on Windows, which tells you the supported path is a Linux environment, either native or through WSL2. A Windows-only toolchain is not offered.
The fifth is anyone who expects a library. This is a project template. It generates one binary crate with a Hello World, and the Rust API it exposes comes from the esp-idf crates, which are separate projects. Judging the template on the API surface means judging a different repository.
The practical summary is that the template removes the setup friction and the setup is exactly where the risk lives. The generated project proves your toolchain, your flash path and your serial monitor work. Everything after that is standard embedded Rust work.
Editorial conclusion
esp-idf-template fits a Rust developer who wants a working ESP-IDF firmware crate on the first build rather than a hand-assembled toolchain, and who will pick a stable ESP-IDF tag rather than master. It is the wrong choice for a team that needs the hardware-in-the-loop tests the esp-idf crates currently lack, for a project that must track the newest ESP-IDF release day one, or for a build that has to work on Windows without the WSL2 route the README documents. Before generating a project, install the prerequisites the README asks for, choose a stable ESP-IDF version from the list rather than master, and note that setting IDF_PATH makes your local SDK override the version you selected.
Frequently asked questions
How do I generate a new Rust ESP-IDF project with esp-idf-template?
Run cargo generate esp-rs/esp-idf-template cargo, then answer the prompts for the project name, the target MCU, and whether to configure advanced options.
Which ESP-IDF versions can esp-idf-template use?
The prompt offers v6.1, v6.0.3, v5.5.5, v5.4.4 and v5.3.6 as stable, plus master, which the README warns is unstable and not officially supported.
How do I flash a project generated by esp-idf-template?
From the root of the generated project run espflash flash target/<mcu-target>/debug/<your-project-name>, replacing the placeholders with your MCU target and project name, and adding --monitor to open a serial monitor afterwards.
What are the known limitations of the esp-idf Rust crates?
The README says the esp-idf-* crates are a community effort that might lag behind the latest stable ESP-IDF version, are currently missing HIL tests, and need more documentation.
Can I develop Rust and C/C++ together with esp-idf-template?
Yes, in two other shapes the README points to, a traditional ESP-IDF idf.py CMake project with instructions in README-cmake.md, and a PlatformIO project with instructions in README-pio.md.
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/esp-rs-esp-idf-template)Was this useful?