Use this page as the integration contract for humans and coding agents adding
the browser package supervision from the supervision-js repository to
another web application.
The browser package is published as supervision. There is no CDN, UMD, or
<script> build. Install the current browser release with npm:
npm install supervision
The published package includes the internal supervision-js-core dependency.
Consumers must not install supervision-js-core separately.
Use:
The default render-preparation worker is embedded in the package and runs from a Blob URL. Consumers do not need to copy a worker file or configure a bundler-specific worker loader.
The renderer requires browser APIs. In an SSR application, create sessions only
on the client after the container element exists. The package can be imported by
build tooling, but createMediaSession() must not run during server rendering.
Do not import Pixi, Mediabunny, worker protocols, or internal core modules. Import the supported JavaScript entrypoints:
import { createMediaSession } from "supervision";
import { createMaskBrushEditor } from "supervision/editing";
Give the viewer a non-zero size. The renderer appends and resizes its own canvas inside this element:
<div id="viewer"></div>
#viewer {
width: 100%;
aspect-ratio: 16 / 9;
background: #020617;
overflow: hidden;
}
#viewer canvas {
display: block;
}
Create one session for one media item:
import {
BaseBoxStyle,
BaseLabelStyle,
createMediaSession,
type MediaSession,
} from "supervision";
const container = document.querySelector<HTMLElement>("#viewer");
if (!container) {
throw new Error("Missing #viewer container.");
}
let session: MediaSession | null = await createMediaSession({
container,
media: "/media/example.mp4",
presentation: {
boxStyle: new BaseBoxStyle(),
labelStyle: new BaseLabelStyle({ includeConfidence: true }),
},
renderer: {
autoPlay: false,
loop: true,
},
});
const unsubscribe = session.subscribe((state) => {
console.log(state.status, state.playbackBlocked, state.errorMessage);
});
await session.play();
// Run when the view unmounts or another media item replaces this one.
unsubscribe();
session.destroy();
session = null;
media accepts a URL string, File/Blob, or an advanced
MediaRendererSource.
Pass semantic detection frames at session creation:
import type { DetectionFrame } from "supervision";
const frames: DetectionFrame[] = [
{
frameIndex: 0,
mediaTime: 0,
endTime: 1 / 30,
detections: [
{
id: "person-1",
className: "person",
confidence: 0.92,
rect: {
x: 240,
y: 290,
width: 240,
height: 420,
},
},
],
},
];
const session = await createMediaSession({
container,
media: "/media/example.mp4",
detections: { frames },
});
Geometry uses media pixels, not CSS pixels:
rect.x and rect.y are the rectangle center;width and height must be positive;{ x, y } media coordinates;mediaTime and endTime are seconds;0 and 1;presentation, not in detection records.The host application owns model calls. The session can own appendable detection storage and rendering:
const session = await createMediaSession({
container,
media: uploadedFile,
normalize: { stream: true },
detections: {
appendable: {
datasetId: "upload-123",
},
},
});
for await (const batch of inferenceResults) {
await session.appendDetectionFrames(batch);
}
Use a stable, app-owned datasetId. Do not pass rendered canvases, Pixi
objects, or prepared mask textures. Append DetectionFrame values.
The host application owns:
DetectionFrame values;destroy() when a viewer is removed.The supervision package owns:
Use exactly one of these for a normal single-source session:
| Input | Use when |
|---|---|
detections.frames |
All detections are already available. |
detections.source |
The app loads time ranges through a custom source. |
detections.appendable |
Results arrive after the session starts. |
detections.sources |
Separate app-owned streams need independent writes, ordering, or styles. |
Do not combine detections.sources with the three single-source inputs.
subscribe().See React Integration for a complete component pattern.
The zero-configuration default requires worker-src blob:. If the application's
Content Security Policy disallows Blob workers, copy the standalone script
exported at supervision/render-preparation-worker into the application's
public assets during its build, then provide a worker factory:
import { RenderPreparationMode, createMediaSession } from "supervision";
const session = await createMediaSession({
container,
media,
renderer: {
renderPreparation: {
mode: RenderPreparationMode.Worker,
workerFactory: {
createWorker: () =>
new Worker("/assets/supervision-mask-preparation.worker.js", {
name: "supervision-render-preparation",
}),
},
},
},
});
Serve that asset from an origin allowed by worker-src. The standalone file is
self-contained, so it does not need adjacent JavaScript chunks. Its message
protocol is internal; applications should only use it through
workerFactory.
Before considering an integration complete:
npm ci succeeds in a fresh checkout of the consuming application.worker / ready in the production
build when workers are enabled.supervision-web instead of supervision.supervision-js-core separately.createMediaSession() during SSR.x and y as top-left coordinates.