Skip to content

Repository files navigation

Onelight

Onelight is a self-hosted, open-source media review and approval tool for post-production. It is a frame.io alternative built for studios that want to own their footage, their notes, and their economics: no per-seat fees, no vendor lock-in, and no footage sitting on someone else's servers.

You upload originals, Onelight makes color-correct review proxies, collaborators leave frame-accurate notes with drawings, and those notes export back into the edit as markers with their text intact.

Why it exists

Onelight is part of halideworks, a set of open tools that replace rent-extracting post-production vendors. The pieces that matter, and that most alternatives get wrong:

  • Frame accuracy. Positions are stored as integer frames against a rational frame rate, never seconds. The player derives frame identity from requestVideoFrameCallback, not currentTime, and drop-frame timecode math is property-tested for a full 24 hours at every supported rate.
  • Color correctness. Proxies carry explicit color tags, HDR sources are tonemapped through libplacebo, and the review room is a strictly neutral grey environment with no gradients or tinted chrome near the footage.
  • Notes that survive the edit. Comments carry forward across versions with provenance, and export to Resolve marker EDL, Avid, Premiere xmeml, and FCPXML with the comment text preserved.
  • Seat-free self-hosting. Run it on one box with Docker, or on Cloudflare Workers with D1 and R2.

Status

This is a v1 in active development, covering the first four phases of the design: foundations, ingest and media pipeline, player and comments, sharing and exports.

The automated test suite is extensive: an API contract suite that runs on both SQLite (Node) and D1 (Cloudflare Workers), timecode property tests, byte-exact golden fixtures for every NLE export format, a WebCodecs frame-accuracy harness, golden-frame color QC, and a full-stack integration run that scales the media worker to three, kills one mid-encode, and asserts another finishes the job. Some final acceptance steps require a Linux host with ffmpeg and real NLE applications.

What it costs, and how fast it is

Onelight runs two ways from one build: a Docker stack on a machine you own, or entirely serverless on Cloudflare Workers, D1 and R2.

  • Pricing works the serverless bill out from Cloudflare's published rates. The short version is that R2 charges nothing for egress, which for a tool whose whole job is sending video to people is the line that would otherwise dominate: 1 TB stored costs about $15 a month and serving all of it costs nothing.
  • Benchmarks covers encoding throughput and what the workers need to keep up. Methodology only; no measurements taken yet, and the page says so.

Encoding always needs a machine, because ffmpeg does. A media worker is a container that claims jobs over HTTP, encodes, uploads and keeps nothing, so it can be a spare desktop, a VM, or a spot instance that dies without consequence. Cloudflare Containers can run it too, with caveats that Encoding sets out.

Quick start with Docker

cp .env.example .env
# set SECRET_KEY to at least 32 random characters, and WORKER_SECRET
docker compose -f deploy/docker-compose.yml up --build

Browse to the configured PUBLIC_URL, complete first-run setup, create a project, and invite a member. deploy/Caddyfile.example shows a TLS-terminating reverse proxy. Production deployments must set an explicit SECRET_KEY; compose refuses to start without it.

Every setting is declared once in packages/core/src/config-manifest.ts, with its type, default and which container reads it; .env.example and the environment lists in deploy/docker-compose.yml are generated from it, and CI fails if a declared setting is not actually passed to the container. .env.example is therefore the settings reference, and it is never hand-edited. Administrators can see what the running server resolved, subsystem by subsystem, on the admin system page.

GPU encoding is opt-in through a Compose override. Intel integrated graphics and Intel Arc use Quick Sync through VAAPI:

# Set ONELIGHT_RENDER_GID to: getent group render | cut -d: -f3
docker compose -f deploy/docker-compose.yml \
  -f deploy/docker-compose.gpu-intel.yml up --build

Use deploy/docker-compose.gpu-nvidia.yml for NVIDIA or deploy/docker-compose.gpu-amd.yml for AMD on Linux. The worker probes the real encoder before it accepts jobs. Its /healthz response reports the selected backend.

Development

Requirements: Node 22 or newer and pnpm 9.

pnpm install
pnpm dev            # API plus the web app at http://localhost:3000

Set SECRET_KEY to at least 32 characters before starting. Gates, all of which run in CI:

pnpm typecheck
pnpm lint
pnpm format
pnpm test           # Node / better-sqlite3 contract and unit suites
pnpm test:workers   # the same contract suite on the D1 workers pool
pnpm db:check       # migration D1-safety and foreign-key check
pnpm openapi:check  # committed OpenAPI document and generated client are current
pnpm config:check   # every documented setting is passed to the container
pnpm web:check      # svelte-check
pnpm qa             # media verification harness (skips where ffmpeg is absent)

Layout

Onelight is a pnpm monorepo, TypeScript throughout for the Cloudflare Workers target.

Path Purpose
packages/core Runtime-agnostic domain: ids, time, timecode, markers, permissions, ports
packages/db Drizzle schema, migrations, and the migration runners for both backends
packages/api The Hono application, routes, and the contract test suite
packages/player The frame-accurate video player, timeline, and annotation overlay
packages/web The SvelteKit single-page app
packages/worker The media pipeline: probe, proxy ladder, sidecars, watermarks, PDF reports
apps/server The Node entry point: API, static app, media worker pump, maintenance sweeps
apps/worker The Linux Docker media worker
apps/cf The Cloudflare Workers entry point with D1 and R2
qa Media verification harness (WebCodecs ground truth, color QC, tmcd)
deploy docker-compose and reverse-proxy examples

The REST API is a public contract. The OpenAPI document is generated from the routes and committed at packages/api/openapi.json.

License

Onelight is free software licensed under the GNU Affero General Public License, version 3 only (AGPL-3.0-only). See LICENSE.

The AGPL is deliberate. If you run a modified Onelight as a network service, you must offer your users the corresponding source of your modified version. That keeps the tool and its improvements open for everyone.

Copyright (C) 2026 David Torcivia and Onelight contributors.

About

Self-hosted, open-source media review and approval for post-production. A frame.io alternative with frame-accurate playback, color-correct proxies, and NLE marker export. AGPL-3.0.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages