Build and deploy modules with the CLI | Viam Documentation
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.
Prerequisites
You need the Viam CLI installed and authenticated. See Viam CLI overview for installation and authentication instructions.
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>
Copy
viam machines part list --machine=<machine-id>
Copy
To find your organization and location IDs:
viam organizations list
Copy
viam locations list
Copy
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
Copy
The generator first asks whether you want to generate a module or an app. Choose Module, then follow the interactive prompts to choose:
- Module name
- Programming language (Python, Go, or C++)
- Namespace and visibility
- Resource type (component or service) and API
To generate a hosted web application instead of a module, choose App or see Deploy a Viam application.
You can also pass flags to skip the interactive prompts:
viam module generate \
--generate-type=module \
--name=my-sensor-module \
--language=python \
--visibility=public
Copy
To add a new resource model to an existing module, use viam module add-model from within the module directory.
To add a web application to an existing Go module, use viam module add-app.
Iterate during development
After making code changes, reload your module on a running machine without restarting the entire machine. By default, the CLI builds the module in the cloud and syncs the new binary to the target:
viam module reload --part-id=<part-id>
Copy
If your development machine is also running the module (for example, developing a macOS module on the Mac that runs viam-server), use reload-local to build and reload without a cloud build:
viam module reload-local --part-id=<part-id>
Copy
If a reload is not sufficient, restart the module process:
viam module restart --part-id=<part-id>
Copy
Update model definitions
After adding or changing models in your module, update the model definitions in meta.json.
This command runs the module’s executable (binary or script) 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.
If you omit --binary, the CLI uses the entrypoint declared in meta.json:
viam module update-models
Copy
To point at a specific executable, pass --binary:
viam module update-models --binary=./bin/module
Copy
Then push the updated meta.json to the registry:
viam module update
Copy
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
Copy
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
Copy
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
Copy
viam module upload --version=1.0.0 --platform=linux/arm64 dist/archive-arm64.tar.gz
Copy
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
Copy
Build for multiple platforms in one command:
viam module build start --version=1.0.0 --platforms=linux/amd64,linux/arm64
Copy
Build from a specific git ref:
viam module build start --version=1.0.0 --ref=main
Copy
Build locally to test before pushing:
viam module build local
Copy
List recent builds (the output includes build IDs you need for build logs):
viam module build list
Copy
View build logs:
viam module build logs --id=<build-id>
Copy
Wait for a build to complete and stream logs:
viam module build logs --id=<build-id> --wait
Copy
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
Copy
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
Copy
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
Copy
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
Copy
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
Copy
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
Copy
Use --dry-run to print the Docker command without running it.