Dora Node Hub

June 18, 2026 Β· View on GitHub

This hub contains useful pre-built nodes for Dora.

The nodes maintained in this repo (under node-hub/) are published to the Dora Hub catalog, so you can pull one into a dataflow with a single line of YAML β€” no clone, no manual path: wiring:

nodes:
  - id: detector
    hub: dora-yolo@^0.5      # resolved, pinned, and type-checked by `dora build`
    inputs:
      image: camera/image
    outputs:
      - bbox

dora build resolves the version requirement to an exact published version, pins it to a commit, and injects the node's typed input/output contracts into validation. Discover and inspect nodes with:

dora hub search yolo                 # find by name / keyword / category
dora hub info dora-yolo              # contracts + a ready-to-paste example

See the Dora Hub guide for version requirements, reproducible builds (--locked), publishing, and offline use. (The hub: feature is currently unstable.)

Publishing a node

This repo is both the node collection (node-hub/<name>/ source) and the catalog (node-index/, the published index entries). To publish a node you maintain here:

cd node-hub/my-node
dora hub init               # scaffold a dora-node.yml manifest (if needed)
dora hub publish --dry-run  # preview the exact index entry
dora hub publish            # print the entry + PR instructions (open the PR manually)

The catalog is append-only and CI-gated. See CONTRIBUTING.md for the workflow, node-index/README.md for the entry format, and node-index/POLICY.md for namespaces and ownership.

Packages

Feel free to modify this README with your own nodes so that it benefits the community.

TypeTitleDescriptionSupportDownloadsLicense
CameraKornia GST CaptureVideo Capture using Gstreamerβœ…License
CameraKornia V4L CaptureVideo stream for Linux Camerasβœ…License
CameraPyOrbbeckSDKImage and depth from Orbbeck CameraπŸ“DownloadsLicense
CameraPyRealsenseImage and depth from RealsenseLinuxπŸ†—
MacπŸ› οΈ
DownloadsLicense
CameraOpenCV Video CaptureImage stream from OpenCV Cameraβœ…DownloadsLicense
PeripheralKeyboardKeyboard char listenerβœ…DownloadsLicense
PeripheralMicrophoneAudio from microphoneβœ…DownloadsLicense
PeripheralPyAudio(Speaker)Output audio from speakerβœ…DownloadsLicense
ActuatorFeetechFeetech ClientπŸ“
ActuatorDynamixelDynamixel ClientπŸ“
ChassisAgilex - UGVRobomaster ClientπŸ†—DownloadsLicense
ChassisDora Kit CarOpen Source ChassisπŸ†—DownloadsLicense
ChassisDJI - Robomaster S1Robomaster ClientπŸ“
ArmAlex Koch - Low Cost RobotAlex Koch - Low Cost Robot ClientπŸ“
ArmAgilex - PiperAgilex arm clientπŸ†—DownloadsLicense
ArmLebai - LM3Lebai clientπŸ“
RobotTrossen - AlohaAloha clientπŸ“
RobotPollen - Reachy 1Reachy 1 ClientπŸ“
RobotPollen - Reachy 2Reachy 2 clientπŸ†—DownloadsLicense
Voice Activity Detection(VAD)Silero VADSilero Voice activity detectionβœ…DownloadsLicense
Speech to Text(STT)WhisperTranscribe audio to textβœ…DownloadsLicense
Object DetectionYolov8Object detectionβœ…DownloadsLicense
SegmentationSAM2Segment AnythingCudaβœ…
MetalπŸ› οΈ
DownloadsLicense
Large Language Model(LLM)Qwen2.5Large Language Model using Qwenβœ…DownloadsLicense
Vision Language Model(VLM)InternVLInternVL is a vision language modelπŸ†—DownloadsLicense
Vision Language Model(VLM)Qwen2.5-vlVision Language Model using Qwen2.5 VLβœ…DownloadsLicense
Vision Language Action(VLA)RDT-1BInfer policy using Robotic Diffusion TransformerπŸ†—DownloadsLicense
TranslationOpus MTTranslate text between languageπŸ†—DownloadsLicense
TranslationArgosTranslateOpen Source translation engineπŸ†—DownloadsLicense
Text to Speech(TTS)Kokoro TTSEfficient Text to Speechβœ…DownloadsLicense
RecorderLlama Factory RecorderRecord data to train LLM and VLMπŸ†—DownloadsLicense
RecorderLeRobot RecorderLeRobot Recorder helperπŸ“
VisualizationPlotSimple OpenCV plot visualizationβœ…DownloadsLicense
VisualizationRerunVisualization toolβœ…DownloadsLicense
SimulatorMujocoMujoco SimulatorπŸ“
SimulatorGymnasiumExperimental OpenAI Gymnasium bridgeπŸ“
SimulatorCarlaCarla SimulatorπŸ“
nanKornia Sobel OperatorKornia image processing Sobel operatorβœ…License

Examples

TypeTitleDescriptionLast Commit
AudioSpeech to Text(STT)Transform speech to text.License
AudioTranslationTranslate audio in real time.License
VisionVision Language Model(VLM)Use a VLM to understand images.License
VisionYOLOUse YOLO to detect object within image.License
VisionCameraSimple webcam plot exampleLicense
Model TrainingPiper RDTPiper RDT PipelineLicense
Model TrainingLeRobot - Alexander KochTraining Alexander Koch Low Cost Robot with LeRobotLicense
ROS2C++ ROS2 ExampleExample using C++ ROS2License
ROS2Rust ROS2 ExampleExample using Rust ROS2License
ROS2Python ROS2 ExampleExample using Python ROS2License
BenchmarkGPU BenchmarkGPU Benchmark of dora-rsLicense
BenchmarkCPU BenchmarkCPU Benchmark of dora-rsLicense
TutorialRust ExampleExample using RustLicense
TutorialPython ExampleExample using PythonLicense
TutorialCMake ExampleExample using CMakeLicense
TutorialC ExampleExample with C nodeLicense
TutorialCUDA ExampleExample using CUDA Zero CopyLicense
TutorialC++ ExampleExample with C++ nodeLicense

Python

Add a new python node

  • To work on a new node, start by:
cd node-hub
dora new your-node-name --lang python --kind node
cd ./your-node-name
uv venv --seed -p 3.11
uv pip install -e . # Install
uv run ruff check . --fix # Format
uv run ruff check . # Lint
uv run pytest . # Test
  • To add a python dependency just do:
uv add numpy # for example

The package is then added to your pyproject.toml

  • Modify the code within main.py in your liking.

  • Create a PR and let the CI/CD run test on it πŸ™‹

Structure

The structure of the node hub is as follows (please use the same structure if you need to add a new node):

node-hub/
└── your-node/
    β”œβ”€β”€ README.md
    β”œβ”€β”€ your-node
    β”‚   β”œβ”€β”€ __init__.py
    β”‚   β”œβ”€β”€ __main__.py
    β”‚   └── main.py
    β”œβ”€β”€ pyproject.toml
    └── tests
        └── test_<your-node>.py

The idea is to make a pyproject.toml file that will install the required dependencies for the node and attach main function of the node inside a callable script in your environment.

To do so, you will need to add a main function inside the main.py file.

def main():
    pass

And then you will need to adapt the following pyproject.toml file:

[project]
name = "[name of the node e.g. video-encoder, with '-' to replace spaces]"
version = "0.1"
authors = [{ name = "[Pseudo/Name]", email = "[email]" }]
description = "Dora Node for []"
readme = "README.md"
license = { text = "MIT" }

dependencies = [
    "dora-rs >= 0.3.8",
]

[project.scripts]
[name of the node with '-' to replace spaces] = "[name of the node with '_' to replace spaces].main:main"

[tool.ruff.lint]
extend-select = [
  "D",    # pydocstyle
  "UP",   # Ruff's UP rule
  "PERF", # Ruff's PERF rule
  "RET",  # Ruff's RET rule
  "RSE",  # Ruff's RSE rule
  "NPY",  # Ruff's NPY rule
  "N",    # Ruff's N rule
  "I",    # Ruff's I rule
]

Finally, the README.md file should explicit all inputs/outputs of the node and how to configure it in the YAML file.

Example

[project]
name = "opencv-plot"
version = "0.1"
authors = [
    "Haixuan Xavier Tao <tao.xavier@outlook.com>",
    "Enzo Le Van <dev@enzo-le-van.fr>"
]
description = "Dora Node for plotting data with OpenCV"
readme = "README.md"
license = { text = "MIT" }
requires-python = ">=3.7"

dependencies = [
    "dora-rs >= 0.3.8",
]
[dependency-groups]
dev = ["pytest >=8.1.1", "ruff >=0.9.1"]

[project.scripts]
opencv-plot = "opencv_plot.main:main"

[tool.ruff.lint]
extend-select = [
  "D",    # pydocstyle
  "UP",   # Ruff's UP rule
  "PERF", # Ruff's PERF rule
  "RET",  # Ruff's RET rule
  "RSE",  # Ruff's RSE rule
  "NPY",  # Ruff's NPY rule
  "N",    # Ruff's N rule
  "I",    # Ruff's I rule
]

Adding git dependency

  • If a git repository is added as submodule. Proper path should be added in pyproject.toml inorder to make sure that linting and testing are exempted for that dependency.
  • A very good example of how this can be done is as follows

Correct approach:

[tool.ruff]
exclude = ["dora_magma/Magma"]

[tool.black]
extend.exclude = "dora_magma/Magma"

Incorrect Approach:

[tool.ruff]
exclude = ["dora-magma/dora_magma/Magma"]

[tool.black]
extend.exclude = "dora_magma/Magma"
Note:
  • dora-magma is root folder of the node.

Rust

Add a new rust node

cd node-hub
dora new your-node-name --lang rust --kind node
cd ./your-node-name

Steps Before Building

  • Before building the node, make sure to add your node to the workspace members list in the root Cargo.toml file:
[workspace]
members = [
...
"node-hub/your-node-name"
]
  • Also change the Cargo.toml file in your node to use the workspace version of dora-node-api:
[dependencies]
dora-node-api = { workspace = true }

Structure

The structure of the node hub for Rust is as follows (please use the same structure if you need to add a new node):

node-hub/
└── your-node/
    β”œβ”€β”€ Cargo.toml
    β”œβ”€β”€ README.md
    └── src/
           └── main.rs

The README.md file should explicit all inputs/outputs of the node and how to configure it in the YAML file.

License

This project is licensed under Apache-2.0. Check out NOTICE.md for more information.