Frontend Packages

@onehop/client: The core library used by all other framework-specific packages. Can also be used independently.
@onehop/react: Our React-specific implementations for Pipe and Channels.

Integrating Pipe with a React App

Installing dependencies

Start off by adding both of our frontend packages to your project

# Using npm
npm i @onehop/client @onehop/react

# Using yarn
yarn add @onehop/client @onehop/react

Initializing the Hop SDK

Grab your project ID from the Project Settings page.

You should call the init function outside of a React component. For example, in your application’s entrypoint file:

import React from "react";
import ReactDOM from "react-dom";
import { hop } from "@onehop/client";

import App from "./App";

hop.init({ projectId: "project_xxx" // TODO: replace with your project ID });

ReactDOM.render(<App />, document.getElementById("root"));

Integrating Pipe with React Hooks

The @onehop/react package exposes a collection of React hooks which allow you to easily implement product features into your app. We’ll focus on usePipeRoom in this section.


usePipeRoom takes in an object as it’s first and only argument, consisting of joinToken and ref, where ref is a React reference to a video element.

Let’s jump into an example bare-minimum component:

import {useRef} from 'react';
import {usePipeRoom} from '@onehop/react';

const joinToken = 'prjt_xxx'; // TODO: replace this with a real Pipe join token

export function Livestream() {
	const videoRef = useRef(null);

	const room = usePipeRoom({
		ref: videoRef,

	return (
			<button disabled={!room.canPlay} onClick={() => videoRef.current?.play()}>

			<video ref={videoRef} />

As you can see, Pipe allows you to provide your own video element - Pipe just hooks into it and controls the video source and live scrubbing. This gives you flexibility to use any player wrapper or implement the video element however you want.

usePipeRoom returns the following object:

livebooleanwhether the current room is live or offline
canPlaybooleanwhether the room is able to play the stream
susbcriptionstringone of: available, unavailable, non_existent

Integrating Pipe with Vanilla JS

import {hop, pipe} from '@onehop/client';

// TypeScript only — declaring that `node` is a variable
// that exists, and is a DOM Video element
declare const node: HTMLVideoElement;

const client = hop.init({
	projectId: 'project_xxx',

const joinToken = 'join_token_xxx';


client.getRoomStateMap().addListener(map => {
	const room = map.get(joinToken);

	if (
		!room ||
		room.subscription !== 'available' ||
	) {
		console.log('Not ready:', {room});

	pipe.mount(node, room.connection.llhls.edge_endpoint);