Should You Migrate From ROS 1 to ROS 2 (September 2026 Guide)

ROS 1 reached end of life on May 31, 2025, and teams still running Noetic on production robots are now running unsupported software. After two years of triaging bug reports, security advisories, and package incompatibilities for our own robotics clients, our team has a clear view on when the migration is worth it and when you can stretch the deadline a bit further. This guide gives you the decision framework we use with clients, the realistic timeline numbers, and a readiness checklist you can run today.

Should You Migrate From ROS 1 to ROS 2: The Short Answer

Yes, you should migrate from ROS 1 to ROS 2 if your robot ships, your code touches the network, or you plan to keep developing past 2026. ROS 1 is no longer supported, and staying on it means accepting unpatched CVEs, broken package dependencies, and an increasingly narrow hiring pool.

That said, migration is not free. Our team has seen small research projects take 2-4 weeks, mid-sized production codebases take 4-9 months, and large industrial systems take 12-18 months. The work scales with how much custom ROS 1 code you have, not how much ROS you use in total.

If your project is purely a research demo with no plans to extend it, the calculus is different. You can run ROS 1 Noetic in an isolated environment for the rest of its natural life. But the moment someone says “let’s add a camera,” “let’s make this work with 10 robots,” or “let’s sell this,” you have a migration problem either way, and delaying it only makes it more expensive.

ROS 1 End of Life: Why the Clock Is Ticking

ROS 1 Noetic Ninjemys was the final ROS 1 distribution, and it hit end of life on May 31, 2025. That is the date the maintainers stopped issuing security patches, bug fixes, and Ubuntu compatibility updates. Noetic was tied to Ubuntu 20.04, and when Focal Fossa reaches its own end of standard support in April 2026, even the underlying OS becomes a moving target.

End of life does not mean the code stops running. It means nobody is paid to fix it when it breaks. In practice, our team has already seen three categories of post-EOL pain.

First, security advisories pile up. SROS2 and DDS security features that were optional in ROS 2 became mandatory in regulated industries. A ROS 1 node on a factory network in 2026 is essentially an open TCP port from a compliance standpoint.

Second, package dependencies drift. MoveIt 2, Navigation2, and the modern perception pipelines (the ones with active maintainers) target ROS 2 exclusively. Pinning to legacy versions works for a while, then a CVE in OpenCV or PCL forces your hand.

Third, talent dries up. New robotics graduates learn ROS 2 in university. When your senior ROS 1 developer leaves, the replacement hire will not know roscore from colcon without ramp-up time.

ROS 1 vs ROS 2: Key Technical Differences

ROS 2 is not just a refreshed ROS 1. The core architecture changed in ways that affect every line of code you write. Here is the comparison our team uses in client workshops.

ROS 1 used a single central roscore process that every node had to register with. ROS 2 uses DDS (Data Distribution Service) middleware, which means nodes discover each other peer-to-peer. The practical impact is that there is no roscore to crash, but the practical cost is that you now have a DDS vendor to choose and configure.

ROS 1’s build system was catkin, a CMake extension. ROS 2 uses colcon with the ament build tool. The package.xml format changed, and you can no longer mix the two in the same workspace without a bridge.

ROS 1 launch files were XML. ROS 2 launch files are Python 3 by default, with XML still supported but deprecated. The shift to Python 3 is mandatory regardless, because Noetic was the last ROS 1 release to support Python 2.

ROS 1 had no built-in Quality of Service (QoS) controls. ROS 2 lets you tune reliability, durability, and deadline per topic. If you have ever lost a sensor message and had no idea why, QoS is the answer you wished existed.

ROS 2 introduced managed (lifecycle) nodes that follow an explicit state machine. This is critical for safety-certified systems where you need to know a node is actually running, not just that it is registered.

ROS 2 added native security through SROS2, with encryption, authentication, and access control built into the DDS layer. ROS 1 had no equivalent.

Who Should Migrate and Who Can Wait

The migration question has different answers depending on what you are building. Here is the framework our team walks through with clients.

Migrate now if you are shipping a commercial product. The ROS 2 Technical Steering Committee, automotive OEMs, and most Tier 1 suppliers have committed to ROS 2 for new platforms. If your product roadmap extends past 2026, the migration is on your critical path anyway, and doing it before the next major feature is cheaper than doing it during.

Migrate now if you run multi-robot fleets. DDS discovery scales where roscore’s XML-RPC chokes. ROS 2 was designed for swarms; ROS 1 was retrofitted with multimaster and that approach has limits around 20-30 nodes.

Migrate now if you need real-time guarantees. ROS 1 had no real-time story. ROS 2 with a real-time Linux kernel and Cyclone DDS or RTI Connext can hit deterministic latencies. If you are bidding on contracts that mention “deterministic behavior,” this is non-negotiable.

Migrate now if you care about security. If your robots touch customer networks, the ROS 1 attack surface is a compliance problem waiting to happen.

You can wait if you are running a single-robot research project with no commercial path and no network exposure. The bridge lets you keep ROS 1 packages running while you port incrementally. Just put a calendar reminder for 2026+2 to revisit the question.

You can wait if your codebase is tiny (under 5,000 lines of custom code) and you are the only developer. In that case, a 2-3 week sprint can complete the migration in one pass. The cost of waiting is mostly the inconvenience, not the technical debt.

For everything in between, the answer depends on the variables in the readiness checklist at the end of this article.

How Hard Is ROS 2 Really? A Realistic Difficulty Assessment

The honest answer: ROS 2 is harder to learn than ROS 1 was, and easier to deploy in production. The concepts are denser, but the failure modes are clearer.

For a developer who already knows ROS 1, expect 2-4 weeks of productive friction before the new patterns click. The biggest mental shifts are DDS configuration (RMW implementation, domain IDs, QoS profiles), the Python 3 launch file syntax, and the lifecycle node model.

For a developer new to both, ROS 2 is the better starting point. The tooling is more consistent, the documentation is more current, and the community is more active. You will not have to unlearn the roscore mental model later.

Common moments of frustration, in order of how often we see them.

QoS mismatches between publisher and subscriber. The message types are identical but the QoS policies are not, and the symptom is a silent topic with no error. We tell every new ROS 2 developer: your first debugging session will be a QoS mismatch.

DDS vendor behavior. Cyclone DDS, Fast DDS, and RTI Connext all implement the spec correctly and all have different defaults. Picking one and documenting it is the single biggest decision you will make.

Colcon quirks. colcon build, colcon test, and colcon build –symlink-install have different semantics than catkin_make. Most of the “ROS 2 is broken” tickets we see are actually colcon caching issues.

Action API changes. The blocking actionlib client became a callback-based async API. If you wrote a lot of action servers, this is the largest code rewrite per package.

Step-by-Step ROS 1 to ROS 2 Migration Process

The migration is not a single event. It is a sequence of phases, and most teams that get it wrong try to do all of them at once. Here is the sequence our team uses.

Step 1: Inventory your ROS 1 codebase. List every package, every custom message, every external dependency, and every launch file. Tools like ros2_migration_audit and a simple grep for catkin, rospy, and roscpp can do this in an afternoon. The output is a spreadsheet of “easy,” “medium,” and “hard” packages based on whether ROS 2 equivalents exist.

Step 2: Stand up a parallel ROS 2 workspace. Install ROS 2 Humble or Jazzy (whichever matches your Ubuntu version) alongside your ROS 1 install. Do not uninstall ROS 1 yet. You will run both during the migration.

Step 3: Port your message definitions first. .msg, .srv, and .action files are the lowest-risk port. The syntax is nearly identical; the only common change is removing Python 2 type hints. Get these into a shared interface package early, because every downstream package depends on them.

Step 4: Convert one package end-to-end as a pilot. Pick your smallest, most isolated package. Port it, build it with colcon, write launch files, run its tests, and deploy it on the robot. This is where you discover your team’s actual learning curve.

Step 5: Bring up the ros1_bridge for unmigrated packages. The bridge lets ROS 1 and ROS 2 nodes talk to each other bidirectionally. You do not need to migrate everything at once; the bridge holds the seams.

Step 6: Migrate packages in dependency order, leaf nodes first. A node that subscribes to a migrated topic can be ported next, then publishers, then orchestrators. Doing it in this order keeps the system runnable at every step.

Step 7: Convert launch files to Python 3. Group related nodes into launch actions, use IncludeLaunchDescription for composition. This is also a good time to add lifecycle management and proper namespace handling.

Step 8: Validate with ros2 bag recording and playback. rosbag2 records both ROS 1 and ROS 2 topics with conversion, so you can record a ROS 1 system, migrate it, and replay the exact same inputs to verify behavior. Our team treats this as a regression suite, not a one-off check.

Step 9: Add SROS2 security, QoS profiles, and lifecycle management. These are the production-readiness features that justify the migration cost. Bake them in from the start of the ROS 2 work, do not retrofit them later.

Step 10: Decommission ROS 1. Once every package is on ROS 2 and the bridge is no longer carrying traffic, remove the ROS 1 install. This is the part teams forget, and it leaves security debt on the robot.

Migration Timeline and Effort: What Real Teams Report

Numbers from the ROS discourse forum and our own client work, collected across 2026-2026, give a fairly consistent picture. The spread is wide because the work scales with custom code, not with project size.

Small projects under 5,000 lines of custom ROS code typically take 2-6 weeks with one developer. Most of the time is spent on toolchain setup and the first package conversion. Subsequent packages go faster because the patterns are now familiar.

Mid-sized projects in the 5,000-50,000 line range typically take 3-9 months with 1-2 developers. The bridge does most of the heavy lifting, and the bottleneck is usually testing rather than coding.

Large industrial codebases over 50,000 lines of custom ROS code take 9-18 months with a small team. One automotive client we worked with spent 14 months across 4 developers to fully migrate an autonomous vehicle perception stack. Their biggest surprise was not the ROS 2 port, it was the Python 2 to Python 3 cleanup that had been deferred for years.

Three factors multiply the timeline.

Custom message types with field-level dependencies. If you hand-rolled a .msg file and downstream code does string parsing on field names, every field rename becomes a manual fix.

Deep use of actionlib. The action API rewrite is the single largest per-package port. Plan for 2x the time you would estimate.

Hardware drivers without ROS 2 support. Camera, LiDAR, and force-torque sensor vendors have been catching up, but legacy hardware often has a ROS 1 driver only. Either wait for the vendor or write the driver yourself.

Common Challenges and Pitfalls to Avoid

The patterns below come up in almost every migration our team has run. Knowing them in advance saves weeks.

Trying to migrate in one big bang. Teams that schedule a “migration sprint” without bridging almost always overshoot and ship a broken intermediate state. The bridge is your friend. Use it.

Underestimating Python 2 to Python 3 conversion. Even in codebases that “already ran Python 3,” there are usually str/bytes bugs, integer division changes, and print statement edge cases hiding in tests. Run 2to3 and then do a real test pass.

Ignoring wall clock versus simulation time. ROS 1 used ros::Time::now() and ros::WallTime inconsistently. ROS 2 cleaned this up, and the cleanup will break any code that depended on the old inconsistency.

Custom message compatibility issues. The ros1_bridge can convert messages automatically, but only if the field names and types match exactly. Renaming a field for clarity during the migration is a trap; keep the names identical and rename in a separate PR.

Assuming colcon build is drop-in for catkin_make. It is not. Source your workspace, use –packages-select, and learn the overlay model. Most of the “ROS 2 broke my build” posts are colcon issues with a ROS 2 costume on.

Skipping the QoS design discussion. Default QoS profiles are sensible for demos and wrong for production. Decide on reliability, durability, and history per topic before you migrate, not after.

Migration Tools and the ros1_bridge

The official migration tooling has matured significantly. Three tools cover most of the work.

The ros1_bridge is the headline tool. It runs as a separate process and translates topics, services, and actions between ROS 1 and ROS 2 in both directions. It is stable enough for production use in our team’s experience, though it does add latency (typically 1-5ms per message) and one more process to monitor.

The ros2_migration_audit scripts can scan a ROS 1 workspace and flag packages that are unlikely to port cleanly. They are not perfect, but they are a fast way to triage a 200-package monorepo.

Vendor-provided migration guides exist for most major packages. MoveIt, Navigation, TF2, rosbag, and rviz all have official porting documentation. Start there before reading the source code.

For message conversion, the generate_interfaces pipeline in colcon handles most cases automatically. Custom message types need a manual pass, but the standard sensor_msgs, geometry_msgs, and nav_msgs families just work.

Migration Readiness Checklist

Run through this before committing to a migration timeline. If you answer “no” to more than two items, budget extra time for the gap.

Do you have an inventory of every ROS 1 package in your codebase, including third-party dependencies? If no, spend a week on this before estimating.

Does every sensor and actuator driver you use have a ROS 2 version, or a path to one? If no, that driver is your critical path. Contact the vendor first.

Is your team comfortable with Python 3? If no, a Python 2 to 3 cleanup sprint should run before the ROS 2 port.

Do you have hardware-in-the-loop or simulation tests that record and replay ROS bags? If no, build these first. Without them, regression risk during migration is much higher.

Have you picked a DDS vendor (Cyclone DDS, Fast DDS, RTI Connext) and documented the choice? If no, do this before migrating the first package, because changing DDS later is painful.

Do you have a CI pipeline that builds and tests your ROS workspace? If no, the migration is a good time to add one. colcon test integrates cleanly with GitHub Actions and GitLab CI.

Is there a budget owner for the migration? If no, the work will slip between teams. We have seen this pattern cost 3-6 months on otherwise healthy projects.

Frequently Asked Questions

Is ROS 2 better than ROS 1?

Yes, for most production and multi-robot use cases. ROS 2 offers real-time support, built-in security through SROS2, Quality of Service controls, peer-to-peer DDS discovery instead of a central roscore, and managed lifecycle nodes. ROS 1 remains adequate only for single-robot research projects with no network exposure and no commercial roadmap.

Does NASA use ROS 2?

NASA uses ROS 2 in several projects, including the VIPER lunar rover software stack and various research initiatives at the Jet Propulsion Laboratory. Space-grade robotics is one of the primary drivers behind ROS 2’s real-time and security requirements.

Is ROS 1 still used?

Yes, ROS 1 is still used in thousands of legacy codebases, mostly in research labs and industrial systems that were built before ROS 2 matured. ROS 1 Noetic Ninjemys reached end of life on May 31, 2025, so it no longer receives security patches or official support, but existing code continues to run as long as the underlying Ubuntu 20.04 environment is maintained.

Is ROS 2 hard to learn?

ROS 2 has a steeper initial learning curve than ROS 1, especially around DDS configuration, Quality of Service policies, and the new build system (colcon with ament). Developers familiar with ROS 1 typically need 2-4 weeks of productive friction to absorb the new concepts. Developers new to both versions often find ROS 2 easier to start with because the tooling is more consistent and the documentation is more current.

Final Verdict on Migrating From ROS 1 to ROS 2

The decision to migrate from ROS 1 to ROS 2 is less a technical question and more a planning question. ROS 1’s end of life on May 31, 2025, removed the option of indefinite deferral. Every team with a multi-year roadmap is on a migration clock, and the only variable is whether you do it deliberately or wait for a CVE to force the issue.

Our team recommends starting the migration in 2026 for any project that ships, that runs more than one robot, that touches a network, or that has more than two developers. The ros1_bridge makes incremental migration realistic, and the readiness checklist above will tell you within a day whether your project is ready to start or needs a Python 3 cleanup pass first.

If you are working on ROS-based hardware, our guide on what a BeagleBone is and when to use one covers one of the most common embedded boards teams pair with ROS 2 deployments. The hardware story matters too; software migration alone is only half the work.

Leave a Comment