Build and deploy modules with the CLI
Scaffold a new module, iterate on it locally with hot-reload, upload it to the registry, and manage versions and cloud builds.
Find your IDs
To find the part ID for a running machine (needed for reload and restart):
viam machines list --organization=<org-id> --location=<location-id>
viam machines part list --machine=<machine-id>
To find your organization and location IDs:
viam organizations list
viam locations list
Scaffold a new module
Generate a module project with boilerplate code, a meta.json manifest, and a build script.
This command does not require authentication, so you can scaffold a module before logging in.
viam module generate
The generator walks you through an interactive prompt to choose:
- Module name
- Programming language (Python or Go)
- Namespace and visibility
- Resource type (component or service) and API
You can also pass flags to skip the interactive prompts:
viam module generate \
--name=my-sensor-module \
--language=python \
--visibility=public
Iterate during development
After making code changes, reload your module on a running machine without restarting the entire machine:
viam module reload-local --part-id=<part-id>
To reload a module from the registry (after uploading a new version):
viam module reload --part-id=<part-id>
If a reload is not sufficient, restart the module process:
viam module restart --part-id=<part-id>
Update model definitions
After adding or changing models in your module, update the model definitions in meta.json.
This command runs the module binary in a sandbox, queries it for the API-model pairs it advertises, and updates the manifest.
It also auto-detects markdown documentation files named namespace_module_model.md.
viam module update-models --binary=./bin/module
Then push the updated meta.json to the registry:
viam module update
Upload to the registry
Upload a module version for a specific platform.
The CLI validates the tarball before uploading: it checks for an executable at the declared entrypoint, verifies file permissions, and warns about platform mismatches or symlinks escaping the archive.
Pass --force to skip validation.
viam module upload \
--version=1.0.0 \
--platform=linux/amd64 \
dist/archive.tar.gz
On success, the CLI prints a link to your module in the registry:
Version successfully uploaded! you can view your changes online here: https://app.viam.com/module/my-org/my-module
Upload for multiple platforms by running the command once per platform:
viam module upload --version=1.0.0 --platform=linux/amd64 dist/archive-amd64.tar.gz
viam module upload --version=1.0.0 --platform=linux/arm64 dist/archive-arm64.tar.gz
Cloud builds
For CI/CD workflows, use cloud builds to compile your module on Viam’s build infrastructure.
Start a cloud build:
viam module build start --version=1.0.0
Build for multiple platforms in one command:
viam module build start --version=1.0.0 --platforms=linux/amd64,linux/arm64
Build from a specific git ref:
viam module build start --version=1.0.0 --ref=main
Build locally to test before pushing:
viam module build local
List recent builds (the output includes build IDs you need for build logs):
viam module build list
View build logs:
viam module build logs --build-id=<build-id>
Wait for a build to complete and stream logs:
viam module build logs --build-id=<build-id> --wait
Download a module
Download a module from the registry for local testing or inspection.
The --id flag takes the format org-namespace:module-name:
viam module download \
--id=my-org:my-sensor-module \
--version=1.0.0 \
--platform=linux/amd64 \
--destination=./downloaded-module
Create a module
If you need to register a module in the registry before uploading (for example, to reserve a name), use create:
viam module create --name=my-new-module
Most users should use viam module generate instead, which handles both creation and scaffolding.
Convert xacro files to URDF
If your module works with a robot described in xacro format (the ROS XML macro language), convert it to URDF with the CLI. The conversion runs in a Docker container with the specified ROS distribution.
viam xacro convert \
--input-file=./robot.xacro \
--output-file=./robot.urdf
If the xacro file uses <xacro:arg> tags, pass the required arguments:
viam xacro convert \
--input-file=./robot.xacro \
--output-file=./robot.urdf \
--args name:=ur20
To collapse fixed joint chains (useful when the URDF must have a single end-effector):
viam xacro convert \
--input-file=./robot.xacro \
--output-file=./robot.urdf \
--collapse-fixed-joints
By default, the conversion uses the osrf/ros:humble-desktop Docker image.
To use a different ROS distribution or a custom image:
viam xacro convert \
--input-file=./robot.xacro \
--output-file=./robot.urdf \
--docker-image=osrf/ros:jazzy-desktop
Use --dry-run to print the Docker command without running it.
Related pages
- Write a driver module for a complete guide to writing a hardware driver
- Write a logic module for writing automation and monitoring logic
- Deploy a module for deployment with GitHub Actions
- CLI reference for the complete
modulecommand reference
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!