What is Xacro? URDF macros explained

Xacro is the XML macro language that makes URDF maintainable: properties, math expressions, macros, and includes that expand into plain URDF — here's how it works and how to expand it without ROS.

By Rahul Rajelli · updated 2026-07-10 · RSS

Xacro (XML Macros) is a preprocessor for URDF. You write a parameterized template; the xacro processor expands it into plain URDF that simulators consume. It exists because raw URDF has no variables, no math, and no reuse — and real robots are full of repetition.

The problem it solves

A four-wheeled robot in raw URDF means writing four nearly identical wheel links and four nearly identical joints — around 100 lines of copy-paste where changing the wheel radius means editing eight places, and computing the inertia of a cylinder means doing m·r²/2 on a calculator and pasting the result. In xacro that's one macro and four one-line instantiations:

<xacro:property name="wheel_radius" value="0.1"/>
<xacro:property name="wheel_mass" value="0.5"/>

<xacro:macro name="wheel" params="prefix x y">
  <link name="${prefix}_wheel">
    <inertial>
      <mass value="${wheel_mass}"/>
      <inertia ixx="${wheel_mass*wheel_radius*wheel_radius/2}" ... />
    </inertial>
  </link>
  <joint name="${prefix}_axle" type="continuous">
    <origin xyz="${x} ${y} 0"/>
    ...
  </joint>
</xacro:macro>

<xacro:wheel prefix="front_left"  x="0.2"  y="0.15"/>
<xacro:wheel prefix="front_right" x="0.2"  y="-0.15"/>

The feature set

FeatureSyntaxWhat it does
Properties<xacro:property name="w" value="0.2"/>Named constants, usable anywhere
Expressions${mass*len*len/12}Python-style math — pi, trig, arithmetic — evaluated at expansion
Macros<xacro:macro name="m" params="a b:=1 *block">Reusable fragments with required, defaulted, and block parameters
Conditionals<xacro:if value="$(arg use_gripper)">Build variants (with/without sensor, arm, gripper) from one file
Arguments<xacro:arg name="x" default="true"/> + $(arg x)Values injected at expansion time, e.g. from a launch file
Includes<xacro:include filename="materials.xacro"/>Split a robot across files: materials, sensors, subassemblies

How expansion works — and how to do it without ROS

The reference processor ships as a ROS package: xacro robot.xacro > robot.urdf. That's fine on a ROS machine, but many consumers of the expanded URDF — MuJoCo importers, Isaac Sim, CI runners, web viewers — live on machines with no ROS installed, which historically meant Docker containers just to expand one file.

The free Xacro → URDF converter runs the expansion entirely in your browser: properties, math, macros, conditionals, args, and multi-file includes (select the included files together with the main one). Constructs that genuinely can't resolve outside ROS — like $(find package) — are reported as explicit warnings, never silently dropped.

Good xacro hygiene