HORUS/blog

Sep 5, 2026 · ros2 · alternatives · middleware · robotics-stack

ROS 2 Alternatives in 2026: 11 Options and Who Each One Suits

ROS 2 is still the right default for most robots in 2026, and the alternatives win in one narrow case. Here is which option suits which builder.

ROS 2 is still the right default for most robots in 2026, while HORUS, Zenoh, eCAL, iceoryx2 and dora-rs each suit narrower jobs. The reason is coverage rather than quality: ROS 2 brings drivers, navigation, mapping and a hiring pool, and replacing that costs more than a leaner messaging layer returns. That flips when one machine runs one loop that cannot be late. The rest of this post is for someone picking a foundation now: a first robot, a rewrite, or a prototype that has outgrown its own shape.

You are probably here because something did not go the way the tutorial said it would. Maybe the robot behaves on the bench and stutters on the floor, and nobody can say why. Maybe the camera and the motor loop live in different programs, and the pictures arrive after the decision was already made. Maybe a whole weekend went into build errors and none of that weekend went into the robot. Or maybe nothing is broken yet, you are simply about to start, and every thread you read says either that ROS 2 is the only serious answer or that everyone serious has quietly left.

Both of those things are said by people describing their own robot, not yours. A warehouse fleet, a research arm, a delivery drone and a hobby rover have almost nothing in common except that programs have to pass messages to each other. The question only has an answer once you say which of those you are building, how many people are building it, and what happens when a message shows up late.

Should I replace ROS 2, or fix what is actually broken?

Most teams should stay where they are and fix the one thing that hurts, because a middleware swap also throws out the parts that were quietly working. The urge to replace usually arrives after a bad week: an arm that jerks at the same point in every run, a build that breaks when a colleague updates a package, a log showing the command going out long after the sensor reading came in. Those are three separate problems and only one of them is about messaging. A jerking arm is often a control gain or a thread that lost its turn. A broken build is packaging. A late command is the case where the transport is a genuine suspect, and even then only if the message crossed from one program into another. Before you shop for a replacement, watch one bad run closely enough to name the moment it went wrong. Teams that skip that step tend to come out the far side of a rewrite with the same robot, the same stutter, and fewer packages to fix it with.

What does robotics middleware actually do?

Middleware carries messages between the programs on a robot so that those programs never have to know about each other. The camera driver produces images. The perception code wants images. The controller wants what perception decided, and the motor driver wants what the controller decided. Middleware sits in the middle: each piece becomes a separate program that can start, stop and crash on its own, while they still exchange data by name instead of by pointer. That sounds like a small job until you see what comes attached to it. A middleware also decides how programs find each other at startup, what happens to a message when the receiver is busy, whether a program that joins late sees the last value or nothing at all, and how you record a run so you can replay it at your desk on Monday. Most of the differences between the options below are differences in those four answers rather than in the carrying of bytes. When somebody calls a framework heavy, they usually mean it made choices there that their robot did not need.

What are the real alternatives to ROS 2 in 2026?

Eleven names come up again and again, and they are not substitutes for one another. ROS 2 is the baseline, with the largest package collection and the most people who already know the vocabulary. HORUS is an open-source real-time middleware for Rust, Python and C++ where all three languages share the same shared-memory ring buffers, so messages are not serialised between programs on one machine; the licence is Apache-2.0 and the project is validated in simulation rather than across a deployed fleet. Zenoh carries data between machines and over links that drop. eCAL comes out of vehicle work and takes recording and replay seriously. iceoryx2 is shared-memory transport on its own, meant to be built on top of. dora-rs arranges a robot as a dataflow graph. LCM is an older messaging library with good log tools and few surprises. Cyclone DDS and Fast DDS can be used directly, without ROS 2 above them. MQTT suits telemetry to a server. gRPC suits robots whose important conversations are with a backend. The eleventh option is no middleware at all: one program, ordinary function calls, threads you own.

How do these options compare side by side?

The column that decides the question is usually the last one rather than the first. Most builders read a comparison looking for the row that sounds best, which is how a robot ends up on a stack chosen for reasons that never applied to it. Read this one backwards instead: find the rows whose "when not to" describes your situation, cross them out, and look at what survives. Two other habits help. Treat the middle column as a hiring question rather than a taste question, because a stack nobody on the team can debug at midnight is a stack you do not really have. And notice that several rows are not competitors at all, since a transport and a framework solve different halves of the problem and are sometimes used together. If two rows survive your crossing-out, the tie-breaker is almost never technical: pick the one whose documentation answers the awkward question you already have.

OptionWho it is forWhat it assumes you knowWhen to pick itWhen not to
ROS 2Teams who need drivers, navigation and mapping nowPython or C++, plus build and launch toolingYou want an ecosystem, not a messaging layerEverything runs on one box and the loop keeps missing its moment
HORUSSmall teams with one demanding loop on one machineRust, Python or C++, and your own control codePrograms in different languages must share memory without a conversion stepYou need mapping, navigation and sensor drivers supplied for you
ZenohFleets and links that cross machines or sitesNetworking ideas and your own data modelRobots talk over patchy links or to a serverEvery program already lives on one computer
eCALVehicle-style pipelines built around recordingC++ and replay workflowsRecording a run and replaying it is centralYou wanted a full robot framework
iceoryx2Engineers who want transport and nothing elseRust or C++ memory ownershipYou are building your own framework above itYou want batteries included
dora-rsPerception pipelines arranged as stagesRust or Python, and graph thinkingThe robot is a chain of processing stepsYour team needs a long support horizon
LCMResearch rigs that mainly log and replayC, C++, Java or Python basicsSimple messaging with good logs is enoughYou need discovery control, services or actions
gRPCRobots whose main conversation is with a serverProtobuf and service definitionsThe remote API matters more than the onboard loopThe tight loop is on the robot itself
No middlewareSingle-purpose machines with one authorThreads and shared state in your languageThe robot is one program and always will beA second person or a second machine joins

Which of these suits a solo builder, a startup, or a research lab?

A solo builder should take the option that comes with the most code they will never have to write, and today that is still ROS 2. One person cannot maintain a driver for every sensor, a mapping stack and a product at the same time, and the hours saved on messaging are smaller than the hours lost writing a camera driver from scratch. A startup should ask what the product actually is. If the product is a machine that must hold its loop while a human stands next to it, the messaging layer is part of the product and worth choosing deliberately. If the product is a fleet management service and the robot is a delivery mechanism, take the ecosystem and spend your scarce weeks elsewhere. A research lab has a third constraint that nobody outside the lab thinks about: someone must reproduce the run next year, possibly a student who has not arrived yet. That argues for whatever the reviewers and the neighbouring lab already read, which is usually ROS 2, unless the paper is about timing itself.

What should I run on a small board or a microcontroller?

On a microcontroller none of this applies, because a microcontroller runs firmware and talks to the rest of the robot over a small link rather than joining a message bus as an equal. The interesting case is the single-board computer, where the whole robot fits in one box and every program is a neighbour. There, discovery chatter over wifi and copies of the same image passing between programs cost you more than they would on a workstation, and shared memory pays for itself because the picture is written once and read where it lies. On a larger onboard computer with room to spare, the picture inverts: the overhead disappears into headroom you already paid for, and the ecosystem argument wins again. Two other hardware facts matter more than people expect. If your sensors only have vendor drivers written against ROS 2, that decides the question before the middleware does. And if the machine is battery-powered, work that never happens is battery you did not spend, which is a quieter argument for keeping data in one place.

What if I need something to demonstrate soon?

If the demonstration is close, choose the option where the parts you have not written yet already exist, which almost always means ROS 2. A demonstration is judged on whether the robot does the thing, not on how the messages travel, and the shortest way there is standing on somebody else's driver, somebody else's planner and somebody else's visualiser. The trap is what happens afterwards. Prototypes get shown, then funded, then shipped, and the stack chosen for a demonstration becomes the stack you support for years. That is survivable when the choice was the big ecosystem, because you can carve out the one loop that hurts later. It is much less survivable in the other direction: a demonstration built on a lean transport with no drivers tends to grow a private half-copy of the ecosystem, written by two tired people. Choose for the demonstration, but write down what you would change if it becomes a product.

What if my team only really knows Python?

Python is enough to get a robot moving on any option in the table, and it stops being enough at exactly one place: the loop that must not miss its moment. Python is superb for wiring things together, reading sensors, testing behaviour and writing the parts that run when the robot is thinking rather than acting. It becomes a liability inside a control loop, because the interpreter can pause to tidy up at a moment nobody chose, and the arm keeps moving during the pause. The practical answer for most Python teams is a split: keep the behaviour, the mission logic and the tooling in Python, and push only the innermost loop into a compiled language when the robot proves it needs one. Middleware that speaks all three languages over the same memory makes that split cheap, because moving one program to C++ or Rust does not mean rewriting the interfaces around it. If you want to see how small a Python node can be, the eight-line version of a publisher and subscriber is a useful reference point.

What do I give up by leaving ROS 2?

You give up other people's work, and it is a larger pile than the messaging you were trying to escape. Navigation, mapping, arm planning, transform bookkeeping, a visualiser everyone already knows, recording tools, simulator bridges, and a driver for nearly every sensor you can buy. You also give up the answer to a question you will be asked at three in the morning, because somebody has already asked it in public and somebody else has already answered. And you give up hiring shorthand: a candidate who has run a robot on ROS 2 arrives knowing what a topic is, what a transform tree does, and why the timestamps matter. Off the main road, every new hire needs a tour. None of that means staying is correct. It means the cost is not the port; the cost is the year afterwards, when a sensor vendor ships a driver you cannot use and somebody on your team has to write it. Count that before counting the messaging.

When is ROS 2 the better choice?

ROS 2 is the better choice whenever the hard part of the robot is everything except the messaging. A mobile robot that must map a building, plan around people and dock itself needs navigation more than it needs a leaner transport, and that navigation exists today, tested by thousands of machines. A lab publishing work others must reproduce needs the stack the reviewers already run. A company that plans to hire needs a stack people already know. A machine that talks to sensors from several vendors needs the drivers those vendors actually wrote. In all four cases HORUS is not the answer, and choosing it would mean spending months rebuilding what was already sitting there. There is a fifth case people forget: if your loop runs slowly enough that a late message never changes the outcome, the messaging layer is not a constraint at all, and any argument about it is theatre. If you are weighing whether to learn the ecosystem at all, that decision is worked through in the honest version of the learning question.

Is every ROS 2 alternative just an abandoned side project?

No, and here is why: several of them carry commercial products and infrastructure that would fall over if they stopped. eCAL grew inside vehicle engineering, where recording every run is a legal habit rather than a preference. Zenoh sits under real deployments and has been adopted as a transport option inside the ROS 2 world itself. The shared-memory transports come out of automotive work where a missed deadline is a safety report. Others in the list really are young, and the honest test is not the star count on a repository page. Look at whether issues get answered by someone who understands the internals, whether releases arrive on a rhythm, whether anyone other than the authors depends on it in public, and whether the documentation describes the awkward parts or only the demonstration. Then ask the question that actually decides it: if this project stopped tomorrow, could your team read the source and keep going? For a small transport the answer is often yes. For a whole framework it is usually no.

Will switching middleware fix my robot's stutter?

Partly, but not the way you think. Changing the transport removes one source of delay, which is real when a large message is packed, copied and unpacked every time it crosses between programs. But most stutters that get blamed on messaging are caused somewhere else: a thread that the operating system did not schedule when it needed to run, memory being allocated inside the loop, a log line written to a slow card, a sensor driver that waits for the next packet, or a control gain that was always going to oscillate. If you swap the middleware without finding that cause, you get a robot that stutters in a new place. The reason a swap is still sometimes worth it is subtler: when the messaging stops being a plausible suspect, the real cause becomes visible, and teams stop arguing about the transport in every meeting. Do it in that order. Find the cause first, and change the transport because you decided to, not because you were out of ideas.

How do I tell which problem I actually have?

Put a stamp on the data when it is produced and look again when it is used, then study the shape of the gap rather than its size. A gap that is steady means you have a pipeline that is longer than you thought, which is a design problem you can plan around. A gap that is mostly fine and occasionally awful means something is interrupting you, and the interruption is your real subject. A gap that grows through the run means a queue is filling somewhere and nobody is draining it. Then run the cheapest experiment there is: put the pieces that talk most into a single program temporarily and see whether the symptom disappears. If it does, the boundary between programs is your problem and a shared-memory transport is a fair answer. If it does not, the transport was never it, and you have saved yourself a rewrite. Timestamp discipline is worth building early for its own sake, and the sensor fusion walkthrough shows why late data poisons results long before it causes visible stutter.

How do I decide which one to use?

Write down five facts about your robot before you read another comparison, because those five facts eliminate most of the table on their own. How many machines must exchange data, and are they connected by a cable or by a network that sometimes is not there. How many people will maintain this, and will any of them be new. What is the one moment in the loop where being late changes what the robot does physically. Which parts do you refuse to write yourself, listed by name: drivers, mapping, planning, recording. And what licence terms does your company accept in a product you ship. With those written down, cross out every row whose "when not to" describes you, and you are usually left with two candidates rather than eleven. Then run each candidate for a week on the actual computer that will be on the robot, with the actual sensor attached, before anyone writes production code. Every comparison article, including this one, is a way to narrow the list. Nothing replaces watching your own machine miss or make its deadline.

Take the line that matches your situation:

The HORUS Fit Framework is the checklist behind those lines, and none of its five axes is a number: ecosystem size, setup effort, team size fit, deployment target, and licence. Score each candidate on all five, and the row that wins on the axis you cannot compromise is your answer, whatever the articles say.

If the shared-memory row keeps describing your robot, HORUS is open source under Apache-2.0 and worth a look before you commit. Star it so it is in your list when you start building.

Found this useful? Share it:Discuss on HNShare on X