Write the Application Once. Integrate Each Platform Once.
Service applications for human-robot interaction are usually written against the interface of one platform, so every change of hardware forces a rewrite. RoIS 2.0 standardizes the interaction at the symbolic level, and OpenRoIS provides the maintained implementation, SDKs, and adapters that the standard needs in practice.
The RoIS Model, Realized as Processes You Can Deploy
The gateway hosts the main HRI Engine. Each adapter hosts a sub HRI Engine for one robot, avatar, or service, and reaches it through the transport that platform requires. Media stays on a separate data plane.
The Building Blocks for Putting RoIS to Work
Recursive Engine
One Engine class realizes both the main and the sub HRI Engine roles of RoIS. The gateway and every adapter share a single dispatch implementation.
Five-Method Component Contract
discover, invoke, query, subscribe, and unsubscribe. ROS 2, gRPC, and game engines stay inside adapters.
JSON-RPC 2.0 over WebSocket
Every operation of the five RoIS interfaces maps to a namespaced method. The control plane works from browsers and across the internet.
Learn more →TypesSingle Source of Truth
RoIS types are authored once in Python, exported to JSON Schema, and generated into TypeScript and C#, and checked locally against the normative RoIS files.
Learn more →ProfilesProfile-Driven Applications
Applications discover components, commands, queries, and events at runtime, so one application works with any platform behind the gateway.
Learn more →ComponentsDecorator-Based Components
Declare a component with @component, @query, @invoke, and @subscribe. Write only the code that talks to your robot.
Standard Operations over JSON-RPC 2.0
RoIS 2.0 defines what a service application can ask of an HRI Engine. OpenRoIS maps each operation onto a JSON-RPC 2.0 method, with requests, responses, and asynchronous notifications over one WebSocket connection.
System
rois.system.*connectdisconnectget_profile
Command
rois.command.*searchbindset_parameterexecuterelease
Query
rois.query.*query
Event
rois.event.*subscribeunsubscribenotify
Streaming
rois.stream.*connect_streamsuspend_streamnotify_status
Build on Either Side of the Standard
Application developers use an SDK to address any platform through the RoIS interfaces. Robot developers write components that translate those interfaces into calls to their own stack, and the adapter framework handles the rest.
- TypeScript SDK for web and Node.js applications
- C# SDK for Unity and .NET applications
- Python adapter SDK with ROS 2 support
- Service Application
- Component
- On the Wire
import { RoISClient } from "@openrois/sdk";
const client = await RoISClient.connect("ws://localhost:8765");
// Discover components across every connected robot, then pick one by type.
const refs = await client.search();
const nav = refs.find((ref) => ref.includes("Navigation"))!;
// Read state synchronously.
const status = await client.query(nav, "component_status");
// React to events.
client.on("reached_target", (n) => console.log(n.params));
await client.subscribe(nav, "reached_target");
// Reserve an actuation component, command it, release it.
await client.bind(nav);
await client.setParameter(nav, [
{ name: "target_positions", data_type_ref: "string[]", value: '["kitchen"]' },
]);
await client.execute(nav, { command_type: "start" });
await client.release(nav);
from openrois.interfaces.bus import InvokeResponse
from openrois.interfaces.hri import ReturnCode
from openrois_components_core import component, invoke, query, results, subscribe
@component("Navigation", function="actuation")
class Navigation:
"""Translates RoIS Navigation into calls to your robot's own API."""
def __init__(self, config: dict) -> None:
self._robot_url = config["robot_url"]
async def connect(self) -> None:
self._robot = await MyRobotClient.open(self._robot_url)
@query("component_status")
async def status(self):
return results.status("BUSY" if self._robot.moving else "READY")
@invoke("start")
async def start(self, parameters):
await self._robot.go_to(parameters)
return InvokeResponse(return_code=ReturnCode.OK, command_id="nav-1")
@subscribe("reached_target")
async def on_reached_target(self):
"""Registers the event. Emit it with self.parent.emit_async(...)."""
// Service application to gateway
{ "jsonrpc": "2.0", "id": 7, "method": "rois.command.bind",
"params": { "component_ref": "robot_1/Navigation" } }
{ "jsonrpc": "2.0", "id": 7, "result": { "return_code": "OK" } }
// Gateway to service application, pushed when the robot arrives
{ "jsonrpc": "2.0", "method": "rois.event.notify",
"params": {
"subscribe_id": "sub-3f2a",
"event_type": "reached_target",
"results": [
{ "name": "target", "data_type_ref": "string", "value": "kitchen" },
{ "name": "is_final_target", "data_type_ref": "bool", "value": "true" }
] } }
Built in the Open, One Capability at a Time
OpenRoIS is alpha software with an unstable API. The foundations are in place and demonstrated with a physical robot. The rest of the RoIS surface follows a public roadmap.
- RoIS interface types in Python, JSON Schema, TypeScript, and C#
- Recursive engine, gateway process, WebSocket server and client, and adapter SDK (Python)
- TypeScript client SDK and profile-driven web inspector
- C# client SDK for Unity and .NET
- Reference components for the Preferred Robotics Kachaka (gRPC, ROS 2)
- Authentication (JWT), authorization (RBAC), and TLS at the gateway
- Streaming Interface control plane
- Gateway configuration file and health endpoint
- Open reference platform on the Pollen Robotics Reachy Mini (simulated first)
- Packages on PyPI, npm, NuGet, and UPM
- All 17 basic RoIS HRI Components (v1.0)
Help Carry RoIS into Practice
OpenRoIS is community-driven and developed in the open under the Apache License 2.0. Components for new robots are the natural entry point, and the roadmap lists work that can be picked up in parallel.
Using OpenRoIS in Your Research?
The position paper describing OpenRoIS was submitted to SII 2027 and is under review. Its preprint is on arXiv as arXiv:2609.21178. Until the paper is published, please cite the preprint, or the software. The repository also provides a CITATION.cff file.
@misc{carrera2026openrois,
author = {Carrera Villalobos, Sebastian and Arellano, Christopher Nolan and
Hitzmann, Arne and Morais Brito, Edilson and Utsumi, Akira and
Horikawa, Yukiko and Miyashita, Takahiro and El Hafi, Lotfi},
title = {{OpenRoIS}: A Community-Driven Open-Source Middleware Implementing
the Robotic Interaction Service ({RoIS}) Framework for Physical
Robots and Virtual Agents},
year = {2026},
eprint = {2609.21178},
archivePrefix = {arXiv},
primaryClass = {cs.RO},
doi = {10.48550/arXiv.2609.21178},
url = {https://arxiv.org/abs/2609.21178},
note = {Submitted to the 2027 IEEE/SICE International Symposium on
System Integration (SII 2027)}
}
@software{openrois,
author = {{OpenRoIS Community}},
title = {{OpenRoIS}: Open-Source Middleware Implementing the {OMG}
Robotic Interaction Service ({RoIS}) Framework 2.0},
url = {https://openrois.org/},
license = {Apache-2.0},
year = {2026}
}