Sep 5, 2026 · robotics-middleware · solo-builders · small-teams · ros-2
Best Robotics Middleware for Solo Builders and Two-Person Teams
For one or two people the best robotics middleware is usually ROS 2, unless the robot is one computer running one loop and nobody has time to maintain a stack.
For one or two people the best middleware is the smallest one that covers what you will not write yourself — usually ROS 2, sometimes HORUS. A small team's binding constraint is upkeep rather than capability: every layer you configure is a layer you keep configuring, and there is no spare person to do it. The verdict flips the moment your robot needs drivers, planners or a simulator that only one ecosystem has. This post is for people making the choice once, at the start, who will not get a cheap second chance to change it.
You have four evenings a week and a robot that mostly sits on the table. The first weekend went to installing the stack, the second to a build error nobody else seems to have, the third to discovering the tutorial was written for a version that is not the version in your terminal. Meanwhile the robot has moved twice. When you describe this, people tell you it is normal, which is true and unhelpful. The version two people hit is worse: you have slightly different machines, the setup instructions live in one person's head, and the robot only runs on the laptop that has been through six months of undocumented fixes. Every time either of you touches the environment, something unrelated stops working, and the person who did not touch it loses an evening finding out why. Nobody is doing anything wrong. There is simply more surface than two people can hold in their heads, and most of that surface belongs to a framework adopted in week one because every tutorial used it. The question underneath all of this is not which tool is most capable. The question is which tool you will still be running in a year.
What is the best middleware if it is only me, or me and one other person?
The best one is whichever covers the parts of your robot you were never going to write, and nothing beyond that. For most small teams the answer is ROS 2, because the parts they were not going to write are sensor drivers, a navigation stack, a mapping stack and a simulator, and one ecosystem has all four sitting there already. The exception is the robot that is really one computer running one loop — a desk arm, a balancing machine, a camera-to-motor pipeline, a test rig — where the drivers are two libraries you install with a package manager and the planner is code you were going to write anyway. In that shape a full framework contributes packaging and charges you upkeep, and a smaller stack, or none, comes out ahead. The way to tell them apart takes five minutes: write down the list of things you will not write yourself. If the list is long and specific, take the ecosystem and accept the upkeep. If the list is short and vague, take the small option and spend the saved evenings on the robot.
What is robotics middleware, and which part of my robot does it replace?
Middleware is the part that moves messages between the pieces of your robot and decides what happens when a piece is slow, missing or dead. In practice it also brings three things sold alongside: a way to start and stop programs together, a way to look at what is flowing while the robot runs, and a catalogue of components other people already wrote. Those are separable, and for a small team the distinction is the entire decision. The message-passing part is genuinely small — a few concepts, a day to learn. The catalogue is enormous, and the catalogue is the reason ROS 2 dominates. If your robot needs a lidar driver, a costmap, a path planner and a simulator that speaks the same message types, the catalogue is worth more than any property of the transport underneath. If your robot needs none of those, you are paying the catalogue's upkeep for a catalogue you never open, and the small message-passing part is all you actually wanted. Worth naming separately: watching messages while the robot moves, and recording a run to replay at your desk, is the part small teams miss most when they go without a middleware.
What do small teams try first, and why does it stop working?
Most small teams start with one program: a Python script with a couple of threads and a queue between them. That works far longer than anyone admits, and it is the right first move. It stops working at four predictable moments. A second language arrives, usually a C++ driver from a sensor vendor or a Rust loop you wrote for timing, and now the queue in your script cannot reach it. One part starts blocking another, so a slow image handler makes the wheels stutter. A crash in any component takes the whole robot down, including the part that was supposed to stop the motors. And you want to see what happened during the run that went wrong, which means recording every message, which nobody wants to write by hand. Teams that push past those four moments without changing anything end up building a private middleware by accident: a socket here, a shared file there, a supervisor script nobody understands. That is more expensive than choosing one on purpose, and it comes with no tools at all.
What are the actual choices a one- or two-person team picks between?
There are five families, and the honest shortlist is shorter than the internet suggests. First, a full framework: ROS 2, which brings the message layer, the build system, the package catalogue and the tooling as one decision. Second, a single-machine message layer such as HORUS, where Rust, Python and C++ share the same shared-memory ring buffers so messages are not serialised between processes on that computer, which suits a mixed-language robot that lives on one board. Third, a general message library of the ZeroMQ or LCM sort, where you get sockets and delivery and define every message contract, supervision policy and tool yourself. Fourth, a broker such as MQTT, which is excellent for telemetry to a dashboard or a phone and wrong for anything the robot waits on. Fifth, no middleware: one program, one language, threads and queues. Alongside those sit two special cases most teams meet eventually — the platform vendor's own SDK if you bought a robot rather than built one, and a firmware-side stack if a microcontroller holds the tight timing.
Which of these fits which kind of small team?
The one that fits is the one whose assumptions match the robot you are actually building, not the robot you might build later.
| Option | Who it is for | What it assumes you know | When to pick it | When not to |
|---|---|---|---|---|
| ROS 2, full distribution | Teams needing drivers, navigation and simulation | Linux packaging, its build tool, its message model | The robot is a mobile base with common sensors | Nobody has evenings spare for upkeep |
| ROS 2, trimmed to a few packages | Teams wanting one or two ecosystem pieces | Which packages you truly use | You need a planner or a driver, not the whole stack | You end up rebuilding the rest anyway |
| HORUS | One-machine robots mixing Rust, Python and C++ | One of those languages, and life outside the ROS package set | Sensing, control and actuation share a computer | You need ROS drivers, or a graph spanning machines |
| A general message library | Builders happy defining their own contracts | Sockets, message shapes, process supervision | The parts are few and the shapes are stable | You would rebuild tools that already exist |
| A broker for telemetry | Robots reporting to a dashboard or phone | Topics, retained messages, running a broker | The traffic is status and human commands | Something on the robot waits for it |
| No middleware, one program | Early prototypes in a single language | Threads and queues in that language | The whole robot fits in one program | A second language or a crash boundary appears |
| The platform vendor's SDK | Teams on a bought robot | Whatever model the vendor chose | The platform is the robot | You expect to change hardware later |
| A firmware-side stack | Robots with a real-time board underneath | Embedded build tooling | The tight timing lives on a microcontroller | The board can stay dumb and the computer smart |
Two rows together is a normal answer: a small stack on the robot, and a broker or bridge carrying status to a human.
What should I pick if I am the only person who will ever maintain this?
Pick the one you could reinstall from a blank machine in a single evening. That test sounds unrelated to robotics and it predicts more than any feature comparison, because the failure mode of a solo project is not choosing the wrong tool — it is arriving at a machine that no longer builds, six months after the last time you touched it, with no memory of how the working version came to work. Write the setup down as a script before you commit to anything. If the script is twenty lines you understand, the choice is fine. If you cannot write it at all, the choice is already too big for one person. The second test is what happens when you disappear for three months and come back. A small stack with fifteen concepts is still in your head. A framework with a hundred is not, and you will spend the first week of your return relearning the tool rather than the robot. Neither test says anything about which middleware is better. Both say a great deal about which one you will still be using.
What if my robot is one small computer rather than several?
Then most of what a networked framework does for you is being paid for and not used. A framework that distributes a graph across machines carries the machinery for discovery, for network transports, for deciding what happens when a remote peer vanishes — and if every component lives on one board, none of those cases can occur. This describes far more robots than people expect: desk arms, camera-to-motor pipelines, balancing machines, test rigs, most competition robots, and a good share of research prototypes. The important question is whether that stays true. If a second computer is coming — a workstation doing perception, a base station collecting logs — then a framework designed for that is worth adopting now, and picking something single-machine means a migration later. If nothing is coming, a single-machine stack removes the whole category of network problems, which is not a small gift. Anyone who has watched a ROS 2 graph fall apart the moment the cable comes out knows how much time that category can consume.
What if I have a demo in six weeks?
Use whatever is already running today, and freeze it. Six weeks is not enough time to change foundations and still have a robot at the end, and the version of this decision that ends badly is always the one made under a deadline. If nothing is running yet, pick by what you will not write: if the demo needs mapping and navigation, take the ecosystem that has them and accept every rough edge; if the demo needs one arm to pick one object, take the smallest thing that moves messages and write the rest. Then stop evaluating. The hours you spend comparing options after the choice is made are hours the robot does not get, and no middleware decision has ever been the reason a demo succeeded. What does decide demos is whether the robot stops safely when something goes wrong, whether you can restart it in ten seconds in front of an audience, and whether the person watching can tell what it is doing. Spend the six weeks there.
What if I know Python but have never written C++ or Rust?
Stay in Python until Python is the thing stopping you, which is later than most people assume. Sensor reading, coordination, planning at human speeds, dashboards, logging, most of a hobby robot: Python handles all of it and you will move faster than in any other language you do not yet know. Python stops being enough at a recognisable point — when the loop that holds a wheel speed or keeps an arm from hitting the table starts missing its moment because the language paused to collect garbage. That is the moment to move one part, not the whole robot, into a compiled language. This is exactly why a middleware where Python and a compiled language read the same buffers is useful to a small team: the fast part gets rewritten and everything else stays where it is. A comparison of what a small graph looks like in plain Python is a reasonable way to see how much ceremony a framework adds before you commit to one.
What do I give up by choosing the smaller option?
You give up the catalogue, and the catalogue is the real product. No lidar driver waiting for you, no navigation stack, no arm planner, no simulator that already speaks your message types, no visualiser that discovers topics on its own, no recording tool with a decade of use behind it. You also give up the thing that is hardest to price: strangers who have already had your problem. Search a ROS 2 error and you land on a thread from someone who solved it in 2019. Search an error from a smaller project and you land on the source code. For a solo builder that is sometimes fine and occasionally fatal, and which one depends entirely on whether your hard problems are framework problems or robot problems. The last thing you give up is handover. A project built on the standard stack can be picked up by someone new; a project built on your own arrangement of parts is a project only you can maintain, which matters more than expected the first time you want help.
When is ROS 2 the better choice?
ROS 2 is the better choice for any robot whose value comes from the parts other people already built. A mobile base with a lidar that must map a building and navigate it: ROS 2, without hesitation, because writing that stack yourself is a multi-year project and it exists today. A robot arm using an established motion planner. Anything you want to test in a simulator that already speaks the same message types. Anything a collaborator, a student or a contractor will touch, because the standard stack is the one they will already know. Anything spanning two machines by design, since HORUS is a single-machine middleware and shared memory stops at the edge of the computer. And anything where your loops run at a rate that makes messaging cost irrelevant, which covers a great many working robots. In all those cases the ecosystem is the deciding factor and nothing else comes close. Choosing a smaller stack there costs you a year and buys you a property you did not need. Even fusing an IMU with wheel odometry is easier when the filter, the message types and the visualiser already agree.
Is a two-person team too small to need middleware at all?
No, and here is why: the alternative is not "no middleware", it is a middleware you wrote by accident and cannot debug. Two people build two components, then three, then five. One of them must not stall when another is slow. One must keep running when another crashes, especially if that one commands the motors. Both of you eventually want to record a run and replay it at your desks, because reproducing a failure on hardware is slow and reproducing it from a recording is not. Every one of those is a middleware feature, and every team that avoids choosing one implements all of them badly over the following year — a socket here, a file there, a supervisor script that only the person who wrote it can modify. The accidental version fails in a particular way. One of you renames a field, the other component keeps reading the old shape, and nothing complains until the robot does something inexplicable on a Saturday. Declared message types turn that into an error at startup. The real question is never whether you need message passing between components. The question is only whether you need the large catalogue that usually comes attached to it.
Will picking something other than ROS 2 leave me with nobody to ask when I am stuck?
Partly, but not the way you think. You do lose the enormous archive of solved problems, and that is a genuine cost — but count which of your problems it would have solved. For a small team most hard problems are robot problems: a motor that does not do what the datasheet claims, a camera mount that flexes, a controller that oscillates on carpet and not on tile. No forum has your robot. The framework questions you lose help with are real, though, and they cluster in one place: drivers and integration. If a lidar vendor ships a ROS 2 driver and nothing else, choosing something else means you write that driver, and no amount of community goodwill changes it. So the honest version is that a smaller stack costs you help exactly where the ecosystem was the point, and costs you almost nothing where it was not. There is a cheap way to check first: take your parts list, search each sensor and actuator by name, and see whether what comes back is a maintained driver or a forum post from someone still asking. That answer is about your robot, and it beats any general argument about community size.
How do I decide this in an afternoon?
Write three lists and let them choose for you. First, what you will not write yourself — drivers, mapping, navigation, planning, simulation. Second, how many computers will run your code when the robot works, today and a year out. Third, how many languages your robot will contain. Then read them together. A long first list means take the ecosystem, whatever the other two say, because rebuilding it is a project of its own. A short first list plus one computer means take a small stack and keep the evenings. A short first list plus several computers means you want a networked message layer without the catalogue, and that is a smaller field than either extreme. More than one language on one computer is the case where sharing memory across languages earns its place. If the lists disagree, weight the first one hardest, because the catalogue is the only item on this page that takes years to replace.
A short version, by situation:
- If you are one person building a mobile base with a lidar -> ROS 2, because the navigation and mapping you need already exist and rewriting them is a year you do not have.
- If you are two people on a desk-sized robot that lives on one computer -> a small single-machine stack, because upkeep is your scarcest resource and none of the network machinery applies.
- If your robot mixes a compiled control loop with Python glue -> a middleware where both languages read the same buffers, because the alternative is a bridge you maintain forever.
- If you are prototyping in one language and it still fits in one program -> no middleware yet, because adding one before the boundaries exist is a cost with no return.
- If a collaborator or a contractor will touch the code -> ROS 2, because the stack they already know is worth more than any property of a smaller one.
When you want to compare options rather than symptoms, the HORUS Fit Framework lines them up on five things that are not numbers: ecosystem size, setup effort, team size fit, deployment target, and licence. For a team of one or two, setup effort and team size fit outrank everything else, and licence quietly removes several options before you start.
HORUS is open source under Apache-2.0 and the repository is linked below. Star it so it is in your list when you start building.