~/openloom/technology

How OpenLoom Works
Under the Hood

$ A complete technical breakdown of the end-to-end workflow. From recording in your Chrome extension to playback in any browser — powered by Supabase as your backend.

The Architecture

Three independent layers. You own the first two. The third is replaceable.

YOUR BROWSERChrome ExtensionBackend CredentialsScreen Capture APICanvas CompositorMediaRecorderSupabase REST APIchrome.storage.localPRIVATE — never leavesauth writeYOUR BACKENDPRIVATEFile Storagevideos/{code}/video.webmvideo.mp4Supabase Storage / Convex Files / GCSDatabasevideos/{code}titledescriptionstorage_urlview_countduration_mscapture_modereactions/{id}emojitimestampcreated_atPostgres / Convex DB / FirestoreAccess ControlSECURITY BOUNDARYPUBLICServerless FunctionsTHE PUBLIC GATEWAYGET/v?code={code}metadataPOST/viewincrement viewsGET/reactions?code={code}fetch reactionsPOST/reactions/addadd reactionEdge Functions / HTTP Actions / Cloud FunctionsHTTPSreactionsTHE VIEWERopenloom.liveStatic SPA · GitHub PagesNo backend credsNo DB accessNo server logicNo write accessNo user sessionsSelf-hostableFork → Build → DeployREPLACEABLE — no lock-inyour infrastructure — you own this
01 — YOUR BROWSER

Your Browser, Your Rules

The OpenLoom Chrome extension runs entirely in your browser. During setup, you connect your Supabase project by pasting your project URL and access token. The extension stores your backend credentials in Chrome's local storage, sandboxed to the extension. These credentials never leave your browser. (Convex and Firebase support coming soon.)

Nothing is uploaded until you explicitly choose to share a recording. When you do, the extension encodes the video and uploads it directly to your Supabase storage — authenticated by the credentials that only your browser has.

chrome.storage.local (extension sandbox)
settings
├── provider: "supabase"           # Backend provider
├── supabaseProjectUrl: "https://…"# Your Supabase project URL
├── supabaseServiceRoleKey: "…"    # Service role key
│                                  # ⚠ NEVER uploaded. NEVER shared.
├── supabaseProjectRef: "…"        # Project reference ID
└── provisioned: true              # Backend setup complete

IndexedDB (openloom-blobs)
└── recording-blob                 # Temp recording before upload
                                   # Cleaned up after share

Your backend credentials are the crown jewel. They grant write access to your backend project. Because they live only on your machine, no one else — not even OpenLoom's infrastructure — can modify your recordings, delete your data, or access your storage directly.

02 — YOUR BACKEND

Inside Your Backend Project

OpenLoom currently uses Supabase as its backend. It stores video files, metadata, and reactions using Supabase's native services. Convex and Firebase support are coming soon.

Supabase Storage

Holds the actual video files in a public videos bucket. Videos are stored as single WebM or MP4 files with permanent public URLs — no signed tokens needed for playback.

storage/videos/
  {short-code}.webm     (12.4 MB)
  {short-code}.mp4      (14.1 MB)

Public URL:
  {project-url}/storage/v1/
    object/public/videos/{code}.webm

PostgreSQL Database

Two tables store video metadata and reactions. Accessed via PostgREST (from the extension) and Edge Functions (from the viewer). Row Level Security policies protect all data.

videos (table)
  ├── short_code: "a1b2c3d4"
  ├── title: "Q3 Product Demo"
  ├── storage_url: "https://..."
  ├── view_count: 142
  ├── duration_ms: 45200
  └── capture_mode: "window"

reactions (table)
  ├── video_short_code: "a1b2c3d4"
  ├── emoji: "🔥"
  └── timestamp: 12.5

Edge Functions

Public Gateway

A single Deno-based Edge Function openloom serves as the public API. It uses built-in SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY environment variables — no manual secrets configuration needed.

Deployed automatically by the Chrome extension during setup via the Supabase Management API.

Row Level Security

Firewall

Both tables have RLS enabled. Only the service role (used by Edge Functions and the Chrome extension) can read and write data. Direct public access is denied.

ALTER TABLE videos ENABLE ROW LEVEL SECURITY;
ALTER TABLE reactions ENABLE ROW LEVEL SECURITY;

-- Only service role has access
CREATE POLICY "service_role_access" ON videos
  FOR ALL USING (true) WITH CHECK (true);
03 — PUBLIC API

The Public API Surface

Each backend exposes a public API through its serverless function layer. These are the only way anyone — including the official viewer — can interact with your recordings. No backdoors, no admin panels, no hidden routes.

Base URL Patterns
Supabase
https://{project-ref}.supabase.co/functions/v1/openloom
Convex
Coming soon
Firebase
Coming soon
MethodEndpointPurpose
GET/v?code={code}Fetch video metadata — title, duration, view count, capture mode
POST/viewIncrement the view counter. Fire-and-forget, no response body
GET/reactions?code={code}Fetch all timestamped emoji reactions for the video
POST/reactions/addAdd a new emoji reaction at a specific timestamp

Supabase uses query-parameter style URLs (/v?code=xxx). The web viewer automatically selects the correct URL pattern based on the provider prefix in the share link.

04 — THE VIEWER

The Viewer is a Dumb Client

The OpenLoom web player at openloom.live is a completely stateless single-page application. It carries zero secrets and has zero special access. It's a static Next.js app exported and deployed on GitHub Pages — nothing more.

Zero backend credentials

Can't read databases or storage directly

Zero server-side logic

Static HTML/JS/CSS on GitHub Pages

Zero persistent state

No cookies, sessions, or user accounts

Zero write access

Only calls serverless functions over HTTPS

What happens when someone opens a link

playback sequence
1Parse the URL
https://openloom.live/v/{encoded-id}/{video-code}

Decode the base64url ID to extract the provider prefix (s-, c-, or f-) and project identifier.

2Construct the API base
s → supabase.co/functions | c → convex.site | f → cloudfunctions.net

The provider prefix determines which URL pattern to use.

3Fetch metadata
GET /v?code={code} → { title, duration_ms, view_count, storage_url, ... }

Retrieve the video's metadata from the serverless function.

4Load the video
fetch(storage_url) → <video src={url} />

The storage URL points directly to the video file. Supabase and Firebase use permanent public URLs. Convex uses a redirect proxy.

5Play
<video /> → Plyr initializes → reactions load in parallel

Video plays. Reactions load in parallel. View count increments.

The viewer does not know your admin credentials, your database schema, or your storage bucket name. It only knows the public serverless function URL — the same URL available to anyone with the link.

05 — GITHUB PAGES

Deployed on GitHub Pages

The official web player at openloom.live is deployed as a static Next.js export on GitHub Pages. No server, no runtime, no build service — just static HTML/CSS/JS served from GitHub's CDN. This gives the viewer maximum transparency and zero operational complexity.

GitHub Pages deployment pipeline
# The webviewer is a Next.js app with static export
# next.config.ts → output: "export"

# GitHub Actions workflow triggers on push to main:

1. Checkout repo → Install dependencies
2. next build → generates static /out directory
3. Upload /out as GitHub Pages artifact
4. Deploy to GitHub Pages environment

# Result: static files served at openloom.live
# Custom domain configured via CNAME record
# HTTPS provided automatically by GitHub

Fully auditable

Every deployment is a git commit. The source code, build output, and deployed version are all public and verifiable.

Zero cost

GitHub Pages is free for public repositories. No hosting bills, no usage-based pricing, no surprise charges.

No build server

GitHub Actions runs the build. No Netlify, Vercel, or Cloudflare account needed. One less vendor dependency.

Global CDN

GitHub Pages uses Fastly's CDN. Static files are served from edge locations worldwide with automatic HTTPS.

Deploy Your Own Viewer

Because the viewer is just a static web app with no built-in secrets, you can fork and deploy your own instance. This gives you full control and eliminates any dependency on openloom.live.

deploy your own viewer on GitHub Pages
# 1. Fork the repository on GitHub
$ git clone https://github.com/your-fork/OpenLoom.git
$ cd OpenLoom/webviewer

# 2. Enable GitHub Pages in repo Settings → Pages
#    Source: "GitHub Actions"

# 3. Push to main — GitHub Actions builds & deploys automatically
$ git push origin main

# 4. (Optional) Add a custom domain in Settings → Pages
#    watch.yourcompany.com → CNAME to your-fork.github.io

Your own domain

watch.yourcompany.com instead of openloom.live

Custom branding

Modify the CSS, swap colors, add your logo

Full UI control

Change the player, add features, remove what you don't need

Zero downtime risk

Even if openloom.live goes offline, your recordings are accessible

This is the key insight: your data lives on your backend. Your viewer can live anywhere. The two are connected only by public HTTPS endpoints. Swap the viewer, swap the backend — nothing about the other layer changes.

Own your recordings

No middleman. No vendor lock-in. Your backend, your machine, your rules.