Sep 5, 2026 · rust · ros-2 · robotics-middleware · choosing-tools
Does ROS 2 Support Rust? Where That Stands in 2026
Yes through community bindings, no as an official client library. Rust reaches ROS 2 well enough for your own code, and trails it everywhere else.
Yes through community bindings, no as an officially supported client library — Rust works with ROS 2, but not the way C++ and Python do. Three community projects carry Rust into ROS 2 and cover most of what your own code needs, trailing the official releases. That stops mattering when the robot lives on one computer, where a middleware such as HORUS treats Rust as a first language. The rest of this post is for a Rust developer picking a route onto a robot, and for a team deciding how much of a machine Rust should carry.
You have written Rust for years and you would like the machine on your bench to run it. So you search, and the results are confusing in a specific way. There is an organisation on GitHub that looks official. There is a package that builds, most of the time, if you install an extra build tool and read three issue threads first. There is a forum post asking whether Rust is supported, and the replies disagree with each other and with the documentation.
Meanwhile the practical questions pile up. Will the message types for your lidar generate cleanly? Can a Rust program join the same graph as the C++ nodes your teammate wrote last month? If the answer is yes today, is it still yes after the next distro lands? And the one nobody answers directly: if you commit to this, are you signing up to maintain the plumbing yourself for the life of the project?
The arm, meanwhile, still has not picked anything up.
Does ROS 2 support Rust in 2026?
Rust reaches ROS 2 through community bindings rather than an officially maintained client library, and that has been the shape of the answer for years. ROS 2 maintains two client libraries itself, one for C++ and one for Python, and those are the two that move when the core moves. Rust support lives in separate projects with their own maintainers, release rhythm and coverage of the interface. The bindings are serious work by serious people, they run on real machines, and they exist because underneath the C++ and Python layers sits a C library doing the actual work of joining the network and moving messages — exactly the kind of thing Rust talks to without ceremony. So the question was never whether Rust can speak ROS 2. Rust can. The question is whether you can live with a layer nobody at the project owes you a fix for, on a schedule set by volunteers rather than by your release date.
What does client library support actually mean in ROS 2?
A client library is the layer that turns ROS 2 ideas — nodes, topics, services, parameters, timers — into ordinary code in your language, and support means that layer keeps pace with everything beneath it. C++ and Python each wrap the same C core, and both are updated as part of the release. A Rust binding wraps that same core, so publishing and subscribing arrive early and behave well. The distance opens further up: generated types for your own message definitions, parameters behaving the way the command-line tools expect, actions for commands that take a while and can be cancelled, lifecycle and composition, and the introspection that lets somebody else debug your robot at three in the morning. Those are the parts you need in month four, not week one, which is why teams so often report that everything was fine and then suddenly was not. Asking whether a language is supported really means asking how far up that list the answer stays yes.
What are your actual options for writing Rust on a robot?
There are seven realistic routes, and they differ mainly in how much of ROS 2 you keep. You can use ros2_rust, the binding closest to the ROS 2 project itself, which generates Rust types from your own message definitions. You can use r2r, which wraps the same C core with a different design and leans on async Rust. You can use safe_drive, another independent binding with its own opinion about how the API should feel. You can leave your Rust program outside the graph and connect it through one small bridge you own and understand. You can step away from ROS 2 for a middleware built around mixed-language machines: HORUS is an open-source real-time robotics middleware for Rust, Python and C++ where the three languages share the same shared-memory ring buffers, so messages between processes on one computer are not serialised, while ROS 2 brings a far larger ecosystem, officially maintained client libraries and tooling that works across several computers. Or you can build this robot in C++ or Python and come back to Rust on the next one.
| Option | Who it is for | What it assumes you know | When to pick it | When not to |
|---|---|---|---|---|
| ros2_rust | Teams wanting Rust inside a ROS 2 workspace | ROS 2 ideas, the ROS build tool, Cargo | The robot needs ROS 2 packages and your logic in Rust | An interface you rely on is not covered |
| r2r | Rust developers at home in async code | Async Rust and ROS 2 message types | Rust idioms matter more than official closeness | Your team prefers plain blocking code |
| safe_drive | Rust teams who prefer a different API shape | ROS 2 ideas and the crate's conventions | The design fits how your team writes Rust | You want the largest pool of people to ask |
| Rust bridged to ROS 2 | Teams adding Rust to a working robot | Your message shapes and one process boundary | The C++ system runs and one part must change | Nobody can keep the bridge current |
| HORUS | Teams running Rust, Python and C++ on one computer | Your message shapes and loop timing | Rust holds the loop, other languages sit above | Borrowed ROS 2 packages are the point |
| Plain Rust, no middleware | Solo builders with a single-program machine | Rust and your board's hardware crates | The whole robot is one program you wrote | Programs must agree while the machine moves |
| C++ or Python now, Rust later | Teams with a date and a half-built robot | The stack the team knows | The machine must work before the code is tidy | The part must not fail mid-motion |
What should you pick if you are a Rust developer building your first robot?
Write your own code in Rust and take everything else in whatever language it already exists in. This single decision separates Rust robotics projects that finish from ones that quietly stall. That crusty C++ camera driver is not debt waiting to be cleaned up; it is somebody's two-year argument with a manufacturer's firmware, including the part where the sensor lies about its own timestamps on cold mornings. So draw the line at ownership. Behaviour, state machines, safety checks, the loop that decides when to stop — Rust, and you will be glad the first time the robot runs all weekend without anybody restarting anything. Drivers, mapping, planning, vendor kits — take them as they are and put a clean boundary around them. Start with a bridge rather than a binding if you want to move quickly, because a bridge is a program you can read in one sitting, and keeping languages separate on purpose is easier to undo than a workspace you cannot build.
What robot hardware makes the Rust route easier or harder?
Rust is easiest on hardware you drive yourself and hardest on hardware whose value arrives as somebody's ROS 2 package. A motor controller on a serial link, a board whose peripherals have a decent crate, a camera with a plain C library behind it — that hardware does not care what language you use. A depth camera whose only driver is a ROS 2 node, an arm that ships a ROS 2 interface and a stack of configuration — that hardware chooses ROS 2 for you, and the Rust question becomes where to draw the boundary rather than whether to have one. The check is worth doing before you argue about languages at all: list every device on the robot and write next to each one what it actually ships. A Rust crate, a C library, a ROS 2 package, or a vendor binary. That list decides the project more surely than any preference does.
What if the robot has to work this quarter?
Ship in the stack your team is already fast in and give Rust exactly one program. A quarter is not long enough to learn a borrow checker, a robotics framework and your own hardware at the same time, and early robot work is mostly discovering how wrong your assumptions were. Every one of those discoveries takes longer in a language the team is still learning, which is backwards when the discoveries are the work. Deadlines do not excuse everything, though. If the machine can hurt someone, or if a motion has to stop at a limit whatever else is happening, that component deserves care, and Rust is a reasonable home for it. The failure to avoid is the middle path: starting a broad Rust migration six weeks before a demo, arriving with half a robot in each language and being able to show neither. Decide the boundary in the first week and leave it alone until after the date.
What if you know Rust well but have never used ROS 2?
Learn the ROS 2 ideas before you learn any Rust binding, because nearly every problem you hit will be a ROS 2 problem wearing Rust clothing. A message that never arrives is usually a mismatch in how the two sides agreed to deliver messages, not a bug in the crate. A node that cannot see another node is usually a network or discovery setting. If you come to those puzzles knowing only Rust, you will search for Rust answers and find none, because nobody wrote them; the answers exist in C++ and Python threads that map onto your situation exactly. The practical route is to spend a couple of days running the standard tutorials in Python, poke the running system with the command-line tools until the graph makes sense, then switch to Rust knowing what correct looks like. The honest picture of the wider Rust robotics ecosystem is worth reading the same week.
What does it look like when the Rust bindings stop being enough?
It looks like a week of work on the build with nothing to show on the robot. The pattern is recognisable: one person is regenerating message types after a binding update, another is trying to make the workspace cross-compile for the board, a third is reading an issue thread from last year that ends without a resolution. Nobody has touched the machine in a fortnight. A second sign is the feature that quietly does not get built, because it would need an interface the binding has not reached, so the team routes around it and the robot's capability is shaped by tooling rather than by requirements. A third is the bridge nobody maintains, written in a hurry to connect two worlds and now needing a change whenever either side moves. The second one is the dangerous one, because nothing looks broken. The test is to ask what you would have built this month if the language were not a factor.
What do most Rust teams try first, and why does it stop working?
Most start with one Rust node inside the existing ROS 2 workspace, and it stops working when that workspace has to build for the robot as well as for the laptop. On a developer machine, mixing the ROS build tool with Cargo is a solved annoyance with known workarounds. On the robot's own board, with a different processor and a cross-compiler and someone's continuous integration in the middle, the same arrangement becomes a tax paid by whoever is unlucky enough to touch it. The second thing teams try is regenerating message types for every custom interface they own, which works until a colleague adds a field and the two sides disagree. The pattern behind both is the same: the trouble is not Rust and not ROS 2, it is the seam between two build systems designed without each other in mind. Teams that stay happy reduce the number of places that seam appears, rather than getting better at crossing it.
What do you give up by putting Rust in a ROS 2 robot?
You give up the assumption that a documented ROS 2 feature is available to you. That is the honest headline, and the rest follows from it. You give up some of the search results, since a problem in a binding sends you to a smaller pool of people, and the person who can help may be volunteering on another continent. You give up hiring ease, because the overlap between people who can read robot code and people who can read Rust is genuinely thin. You give up the tutorial path, since the guides that make ROS 2 learnable are written in C++ and Python and you will be translating as you read. And you take on a build story that must work on the target board, not only on the machine where it was written. None of this is fatal, and none of it argues against Rust in general. It argues for being deliberate about how much of the robot you commit.
When is ROS 2 the better choice?
ROS 2 is the better choice whenever the robot's value comes from code other people already wrote, which describes most robots. A machine that must build a map of a building and drive to a goal is a ROS 2 project, because mapping and navigation packages represent years of work nobody reproduces alongside a day job. If the sensor you bought ships only a ROS 2 driver, that settles it, and porting a driver to keep one language is a poor trade. ROS 2 also wins when the system spans several computers, when a new engineer has to read the robot in their first week, and when the tooling around a running system — recording a run, replaying it, watching messages go past — is what makes debugging possible. HORUS is not the answer for those projects, and choosing it there means rebuilding plumbing you could have inherited. A Rust developer on such a project is better served writing one node in C++ than importing a toolchain nobody else can build.
Are the community Rust bindings a dead end?
No, and here is why: they are wrappers over a stable C interface, which is the most durable position a binding can occupy. The C core of ROS 2 changes slowly and deliberately, because the official C++ and Python libraries sit on it too, so a binding is not chasing a moving target the way a reimplementation would be, which is why several independent projects exist. What the bindings genuinely lack is guaranteed release timing and complete coverage of the wider interface, and both are visible in advance rather than discovered on the robot. The way to use them without regret is to check coverage against your own needs before designing around them, keep the Rust portion small enough that a stalled binding is an inconvenience rather than a crisis, and fall back to a bridge for anything not yet reached. Dead end is the wrong shape for this risk. Uneven ground you can see from here is closer.
Will official Rust support arrive and settle this question?
Partly, but not the way you think. An officially maintained Rust client library would settle the release-timing problem, which is real, and it would put Rust in the documentation next to C++ and Python, which changes how teams argue about it internally. What it would not change is the thing that decides most projects: the drivers, planners, mapping systems and vendor kits that make robots work are C++ packages, and an official Rust library does not rewrite any of them. Your robot would still be borrowing that code, still crossing a boundary to reach it, still bounded by what somebody else's package expects. So do not plan around an announcement. Plan around the shape of your own robot, which you can inspect today. If the machine's value is your own logic on hardware you drive yourself, Rust is a fine bet whatever the project announces — and the wider case for Rust in robot software reaches that conclusion by another road.
How do you decide which Rust route fits your robot?
List every part of the robot you will not write yourself, then check what each part needs from ROS 2. That list is the whole decision and it takes an afternoon. For each item there are three outcomes: a usable Rust crate exists, a plain C interface exists that Rust can call without much fuss, or the only option is a ROS 2 package or C++ library you would run beside your code. Count them. If almost everything lands in the first two, you do not need ROS 2 and the binding question is moot. If several land in the third and they are the reason the robot exists, you are a ROS 2 project, and the choice becomes whether Rust arrives through a binding or through a bridge. If the third column is short but the robot mixes languages on one computer, the language boundary is what costs you, not the framework. Deciding by preference and finding out in month three is how these projects go wrong.
Decide by situation rather than by taste:
- If the robot needs mapping, navigation or a vendor's driver -> ROS 2 in C++ or Python, because those packages are the project.
- If you want ROS 2 packages and Rust for your own logic -> a community binding, checked feature by feature, because that gap is smaller than the rewrite.
- If several languages share data on one computer -> a shared-memory middleware, because the language boundary is the expensive part.
- If your team has a date and no ROS 2 experience -> ship in what you know, because half a robot in each language demonstrates neither.
- If the robot is all your own code on hardware you own -> plain Rust, no middleware, because the ecosystem gap does not apply to code nobody has written.
When two routes stay close, weigh them on the five axes of the HORUS Fit Framework — ecosystem size, setup effort, team size fit, deployment target, and licence — and take the one that loses on the fewest. Five honest questions about your situation rather than about the software. If your robot keeps landing on one computer with Rust holding the loop and other languages above it, star HORUS on GitHub so it is in your list when you start building.