# OpenCut Administrator & Developer Guide

This guide is the architectural and operational reference for the **OpenCut-app/OpenCut** repository — the ground-up rewrite of the OpenCut video editor. It is written for developers, architects, and operators who need to understand exactly how this codebase is structured, configured, built, and deployed.

> [!IMPORTANT]
> **Scope check.** At this commit, OpenCut is an early-stage rewrite. The repository is a freshly scaffolded TanStack Start web application: an HTML shell, one route that renders nothing, a Tailwind theme, and a complete shadcn/ui component library. The video editor itself — timeline, preview, export, media handling — **does not exist in this repository yet.** This guide documents the scaffold honestly and completely. Where a capability is planned but not implemented, it is labeled as such. The currently shipping editor is the classic codebase at [opencut-app/opencut-classic](https://github.com/opencut-app/opencut-classic).

---

## 1. Executive Summary

OpenCut is a free, open-source (MIT-licensed) video editor. The project is rebuilding its application from scratch around a new architecture: a plugin-first design, a shared Rust core targeting desktop/mobile/browser, an Editor API, an MCP server for AI agents, and headless automation.

This repository is the **web front-end shell** of that rewrite. Its current technical profile:

| Attribute | Value |
|---|---|
| Repository type | Monorepo (Bun workspaces + Turborepo) |
| Primary app | `apps/web` (`@opencut/web`) |
| Framework | TanStack Start (SSR) + TanStack React Router |
| UI runtime | React 19.2 |
| Build tool | Vite 8 |
| Styling | Tailwind CSS v4 + shadcn/ui (`base-mira` style) |
| Deployment target | Cloudflare Workers (custom domain `new.opencut.app`) |
| Package manager | Bun `1.3.11` |
| Language | TypeScript 6 (strict) |
| Test runner | Vitest 4 (configured; no tests yet) |
| License | MIT (© 2026 OpenCut) |
| Source files | 81 files, ~84 KB of source |

The single most important architectural fact for an operator is that this is a **server-rendered React application deployed as a Cloudflare Worker** — there is no separate backend, database, or API tier in this repository.

---

## 2. Architecture

### 2.1 High-level structure

```
OpenCut (monorepo root)
│
├── Bun workspaces ──── manages apps/*
├── Turborepo ───────── orchestrates dev / build / deploy across apps
│
└── apps/web  (@opencut/web)  ← the only app today
        │
        ├── TanStack Start ──── SSR framework (server entry + routing)
        │     └── TanStack React Router (file-based routes)
        ├── React 19 ────────── UI rendering
        ├── Vite 8 ──────────── dev server + production bundler
        ├── Tailwind v4 ─────── styling
        ├── shadcn/ui ───────── 56 prebuilt components
        └── Cloudflare plugin ─ builds the app as a Worker (wrangler deploy)
```

### 2.2 Request flow (production)

```
Browser → new.opencut.app (Cloudflare edge)
            │
            ▼
        Cloudflare Worker  "opencut-web"
        main = @tanstack/react-start/server-entry
            │
            ▼
        TanStack Start SSR
            │  matches route "/" via routeTree.gen.ts
            ▼
        __root.tsx  (HTML shell: <head> meta/links, TooltipProvider, Scripts)
            │
            ▼
        index.tsx  →  Home()  →  returns null   (no body content yet)
            │
            ▼
        HTML streamed back to browser
```

The Worker runs with the `nodejs_compat` compatibility flag, allowing TanStack Start's server entry to use Node.js-style APIs on the Cloudflare runtime.

### 2.3 The monorepo build pipeline (Turborepo)

`turbo.json` defines three tasks with their dependency and caching rules:

| Task | `dependsOn` | Outputs / behavior |
|---|---|---|
| `build` | `^build` (build upstream packages first) | `.output/**`, `dist/**` |
| `dev` | — | `cache: false`, `persistent: true` (long-running) |
| `deploy` | `build` | runs after a successful build |

Because there is only one app today, Turborepo's cross-package orchestration is effectively a pass-through to `apps/web`, but the pipeline is in place for when the Rust core and additional packages are added.

---

## 3. System Requirements

| Component | Requirement |
|---|---|
| **Bun** | `1.3.11` (the declared `packageManager`) |
| **Node.js** | 18+ recommended for tooling; the Worker uses `nodejs_compat` at runtime |
| **TypeScript** | `^6.0.2` (provided as a dev dependency) |
| **Cloudflare account** | Required only for deployment (`wrangler`) |
| **OS** | Any platform Bun supports (Linux, macOS, Windows) |

> [!NOTE]
> No system-level services are required — no database, message broker, or external API. Local development needs only Bun and a browser.

---

## 4. Repository Structure

```
OpenCut/
├── package.json            Root workspace + Turbo scripts
├── turbo.json              Turborepo task pipeline
├── bunfig.toml             Bun install policy (minimumReleaseAge)
├── bun.lock                Bun lockfile
├── LICENSE                 MIT, © 2026 OpenCut
├── README.md               Project status + roadmap
│
└── apps/
    └── web/                @opencut/web — the web application
        ├── package.json        App deps + scripts
        ├── vite.config.ts      Vite plugin chain
        ├── wrangler.jsonc      Cloudflare Worker config
        ├── tsconfig.json       TypeScript config
        ├── components.json     shadcn/ui config
        ├── .cta.json           Create-TanStack-App metadata
        ├── public/             favicon, robots.txt, manifest.json
        └── src/
            ├── router.tsx          Router factory
            ├── routeTree.gen.ts    Generated route tree (do not edit)
            ├── styles.css          Tailwind + theme tokens
            ├── routes/
            │   ├── __root.tsx      HTML shell + providers + devtools
            │   └── index.tsx       "/" route → renders null
            ├── components/ui/      56 shadcn/ui components
            ├── hooks/
            │   └── use-mobile.ts   useIsMobile() (768px breakpoint)
            └── lib/
                └── utils.ts        cn() class-name helper
```

> [!NOTE]
> 56 of the repository's source files are shadcn/ui components under `apps/web/src/components/ui/`. They are installed and importable but not yet wired into any rendered view. The hand-written application logic is currently confined to `__root.tsx`, `index.tsx`, `router.tsx`, `lib/utils.ts`, and `hooks/use-mobile.ts`.

---

## 5. Configuration Reference

Every configuration file in the repository, with its exact, source-based values.

### 5.1 Root `package.json`

```json
{
  "name": "opencut",
  "private": true,
  "workspaces": ["apps/*"],
  "scripts": {
    "dev": "turbo dev",
    "dev:web": "turbo dev --filter=@opencut/web",
    "build": "turbo build",
    "deploy": "turbo deploy"
  },
  "devDependencies": { "turbo": "latest" },
  "packageManager": "bun@1.3.11"
}
```

| Field | Meaning |
|---|---|
| `workspaces: ["apps/*"]` | Bun treats every directory under `apps/` as a workspace package |
| `packageManager` | Pins Bun `1.3.11` for reproducible installs |
| `scripts` | Thin Turborepo wrappers; real work happens in `apps/web` |

### 5.2 `bunfig.toml` — install policy

```toml
[install]
minimumReleaseAge = 604800 # 7d
```

`minimumReleaseAge = 604800` seconds (7 days) instructs Bun to **refuse any dependency version published in the last week**. This is a supply-chain attack mitigation: it creates a quarantine window so that a maliciously published package version is likely to be detected and yanked before it can be installed. See §9 (Security).

### 5.3 `turbo.json`

See §2.3 for the task table. The schema is `https://turbo.build/schema.json`.

### 5.4 `apps/web/package.json` — scripts

| Script | Command |
|---|---|
| `dev` | `vite dev --port 5173` |
| `build` | `vite build` |
| `preview` | `vite preview` |
| `test` | `vitest run` |
| `deploy` | `bun run build && wrangler deploy` |

### 5.5 `apps/web/vite.config.ts` — plugin chain

```ts
plugins: [
  devtools(),
  cloudflare({ viteEnvironment: { name: 'ssr' } }),
  tailwindcss(),
  tanstackStart(),
  viteReact(),
]
```

| Plugin | Role |
|---|---|
| `devtools()` | TanStack DevTools integration during development |
| `cloudflare({ viteEnvironment: { name: 'ssr' } })` | Targets the Cloudflare Workers runtime; binds the SSR environment |
| `tailwindcss()` | Tailwind CSS v4 via the official Vite plugin |
| `tanstackStart()` | TanStack Start SSR framework integration |
| `viteReact()` | React fast-refresh + JSX transform |

`resolve: { tsconfigPaths: true }` enables the TypeScript path aliases (`#/*`, `@/*`) at build time.

### 5.6 `apps/web/wrangler.jsonc` — Cloudflare Worker

```jsonc
{
  "name": "opencut-web",
  "compatibility_date": "2025-09-02",
  "compatibility_flags": ["nodejs_compat"],
  "main": "@tanstack/react-start/server-entry",
  "routes": [
    { "pattern": "new.opencut.app", "custom_domain": true }
  ]
}
```

| Key | Value | Meaning |
|---|---|---|
| `name` | `opencut-web` | Worker name in the Cloudflare account |
| `compatibility_date` | `2025-09-02` | Pins the Workers runtime behavior to that date |
| `compatibility_flags` | `["nodejs_compat"]` | Enables Node.js API compatibility |
| `main` | `@tanstack/react-start/server-entry` | The Worker entry module (provided by TanStack Start) |
| `routes` | `new.opencut.app` (custom domain) | Binds the Worker to the production domain |

> [!CAUTION]
> The `routes` block hard-codes the official production domain. Any fork **must** change `name` and remove or replace `routes` before deploying, or `wrangler deploy` will attempt to publish to OpenCut's domain (and fail without permission).

### 5.7 `apps/web/tsconfig.json` — TypeScript

| Option | Value | Notes |
|---|---|---|
| `target` / `module` | `ES2022` / `ESNext` | Modern output |
| `jsx` | `react-jsx` | Automatic JSX runtime |
| `moduleResolution` | `bundler` | Vite-style resolution |
| `strict` | `true` | Full strict mode |
| `noUnusedLocals` / `noUnusedParameters` | `true` | Dead-code linting at compile time |
| `noFallthroughCasesInSwitch` | `true` | Switch safety |
| `noUncheckedSideEffectImports` | `true` | Flags side-effect-only imports |
| `noEmit` | `true` | Vite handles emit; `tsc` is type-check only |
| `paths` | `#/*` → `./src/*`, `@/*` → `./src/*` | Import aliases |

### 5.8 `apps/web/components.json` — shadcn/ui

| Field | Value |
|---|---|
| `style` | `base-mira` |
| `tailwind.baseColor` | `neutral` |
| `tailwind.cssVariables` | `true` |
| `tailwind.css` | `src/styles.css` |
| `iconLibrary` | `hugeicons` |
| `rsc` | `false` (not using React Server Components) |
| `aliases` | `components` → `#/components`, `utils` → `#/lib/utils`, `ui` → `#/components/ui`, `lib` → `#/lib`, `hooks` → `#/hooks` |

### 5.9 `apps/web/src/styles.css` — theme

The stylesheet composes four imports and defines the theme tokens:

```css
@import 'tailwindcss';
@import "tw-animate-css";
@import "shadcn/tailwind.css";
@import "@fontsource-variable/inter";

@custom-variant dark (&:is(.dark *));

@theme inline {
    --font-heading: 'Playfair Display', serif;
    --font-sans: 'Inter Variable', sans-serif;
    /* ...full shadcn CSS-variable color token set... */
}
```

| Token | Value |
|---|---|
| Heading font | Playfair Display (loaded via Google Fonts in `__root.tsx`) |
| Body/sans font | Inter Variable (`@fontsource-variable/inter`) |
| Dark mode | Class-based (`.dark` ancestor) via `@custom-variant` |
| Color system | shadcn CSS variables (`--color-*` mapped to `--*` theme vars) |

### 5.10 `apps/web/public/`

| File | Content |
|---|---|
| `robots.txt` | `User-agent: *` / `Disallow:` (allows all crawlers) |
| `favicon.ico` | Site icon |
| `manifest.json` | ⚠️ **Still the default Create-TanStack-App placeholder** — `short_name: "TanStack App"`, `name: "Create TanStack App Sample"`. Not yet customized for OpenCut. |

> [!WARNING]
> `public/manifest.json` has not been updated from the scaffold default. Before any public launch it should be rebranded (name, short_name, theme color, icons). Tracked in §13.

---

## 6. Routing and the Application Shell

### 6.1 Router factory — `src/router.tsx`

```tsx
export function getRouter() {
  const router = createTanStackRouter({
    routeTree,
    scrollRestoration: true,
    defaultPreload: 'intent',
    defaultPreloadStaleTime: 0,
  })
  return router
}
```

| Option | Effect |
|---|---|
| `scrollRestoration: true` | Restores scroll position on navigation |
| `defaultPreload: 'intent'` | Preloads a route's data/code on hover or focus intent |
| `defaultPreloadStaleTime: 0` | Preloaded data is considered immediately stale (always refetched) |

### 6.2 Route tree — `src/routeTree.gen.ts`

Auto-generated by TanStack Router from the files in `src/routes/`. It registers exactly two routes: the root (`__root`) and the index (`/`).

> [!IMPORTANT]
> `routeTree.gen.ts` is machine-generated. Do not edit it by hand — it is regenerated on every build. Add routes by creating files under `src/routes/`.

### 6.3 Root shell — `src/routes/__root.tsx`

The root route defines the HTML document: `<head>` metadata (charset, viewport, title), the favicon link, Google Fonts preconnect + the **Playfair Display** stylesheet, and the app CSS import. The body wraps all child routes in a `TooltipProvider` and mounts `TanStackDevtools` (with the Router DevTools panel) plus the framework `Scripts` component.

> [!NOTE]
> The document `<title>` is hard-coded to `"OpenCut rewrite — beta.opencut.app"`. Note that this references `beta.opencut.app`, while the deployment target in `wrangler.jsonc` and the README is `new.opencut.app` — a naming inconsistency flagged in §13.

> [!NOTE]
> `TanStackDevtools` is mounted unconditionally in the shell. In a typical production build it should be gated behind a development-only check; verify this before public launch (§13).

### 6.4 Index route — `src/routes/index.tsx`

```tsx
export const Route = createFileRoute('/')({ component: Home })

function Home() {
  return null
}
```

The home page renders `null`. This is the placeholder where the editor UI will be mounted. **There is no editor component in this repository yet.**

---

## 7. The UI Component Layer

The repository ships a full shadcn/ui kit (56 components, see §4 / User Guide §5) configured with the `base-mira` style, the `neutral` base color, CSS-variable theming, and the Hugeicons icon set. Components are built on **Base UI** (`@base-ui/react`) and **Radix UI** primitives.

Supporting utilities:

| Utility | Location | Purpose |
|---|---|---|
| `cn(...inputs)` | `src/lib/utils.ts` | Merges class names via `clsx` + `tailwind-merge` |
| `useIsMobile()` | `src/hooks/use-mobile.ts` | Returns `true` below a 768px viewport; live-updates on resize |

A large set of interaction libraries is already declared as dependencies, ready for the editor build: `react-hook-form` + `zod` + `@hookform/resolvers` (forms/validation), `date-fns` + `react-day-picker` (dates), `embla-carousel-react` (carousels), `cmdk` (command palette), `sonner` (toasts), `vaul` (drawers), `recharts` (charts), `react-resizable-panels` (resizable layout — a likely editor-panel primitive), `next-themes` (theme switching), and `input-otp`.

> [!NOTE]
> These libraries are installed but not yet consumed by any rendered code. Treat the dependency list as a statement of intent for the editor UI, not as currently active features.

---

## 8. Build and Deployment Operations

### 8.1 Local development

```bash
bun install          # from repo root
bun run dev          # all apps via Turborepo
# or: bun run dev:web (web only)
```

Vite serves on `http://localhost:5173`.

### 8.2 Production build

```bash
# repo root
bun run build        # turbo build → vite build in apps/web
```

Outputs land in `.output/**` and/or `dist/**` (per `turbo.json`).

### 8.3 Deploy to Cloudflare

```bash
# from apps/web
wrangler login        # one-time auth
bun run deploy        # vite build && wrangler deploy
```

This publishes the Worker `opencut-web` and binds it to `new.opencut.app`.

### 8.4 Inspecting a running deployment

```bash
# Stream live logs from the deployed Worker
wrangler tail opencut-web
```

| Operation | Command |
|---|---|
| Build | `bun run build` |
| Preview production build locally | `bun run preview` (from `apps/web`) |
| Deploy | `bun run deploy` (from `apps/web`) |
| Tail logs | `wrangler tail opencut-web` |
| Roll back | Redeploy a previous build, or use Cloudflare's deployment history in the dashboard |

> [!TIP]
> Cloudflare retains deployment history per Worker. To roll back, redeploy from a known-good commit or promote a previous version from the Cloudflare dashboard's Worker deployments view.

---

## 9. Security Analysis

This is a static, server-rendered shell with no user input, authentication, data storage, or secrets — so the present attack surface is small. The relevant points are about supply-chain posture and what will need hardening as the editor grows.

### 9.1 Supply-chain controls (present)

| Control | Mechanism | Effect |
|---|---|---|
| **Dependency quarantine** | `bunfig.toml` `minimumReleaseAge = 604800` | Refuses dependency versions less than 7 days old, reducing exposure to freshly published malicious releases |
| **Pinned package manager** | `packageManager: bun@1.3.11` | Reproducible installs; resists tooling drift |
| **Lockfile** | `bun.lock` | Exact, reproducible dependency graph |

> [!TIP]
> The `minimumReleaseAge` policy is a strong, low-cost supply-chain control. Keep it in place. If a build fails because a needed version is too new, prefer waiting out the window over lowering the threshold.

### 9.2 Runtime posture (present)

- **No secrets / environment variables.** The repository consumes no `.env` files and `.cta.json` declares no env var values. There are no credentials to leak in this repository.
- **No authentication or authorization.** There is no login, session, or user model — appropriate for a shell, but the editor's eventual collaboration/cloud features will introduce this surface.
- **`nodejs_compat` enabled.** This widens the Worker's available APIs; review what the editor build actually uses so the compatibility surface stays minimal.
- **Permissive `robots.txt`.** All crawlers are allowed (`Disallow:` empty), which is fine for a public marketing/editor site.

### 9.3 Future trust boundaries (planned, not yet present)

The roadmap (§12) introduces the project's most significant future security surfaces:

> [!WARNING]
> **First-class third-party plugins** and an **MCP server for AI agents** are planned. Both execute or are driven by untrusted external code/instructions. When these land, they will become the primary trust boundaries and will require sandboxing, capability scoping, and an explicit permission model. None of this exists in the current repository — but it should be designed in from the start of the plugin architecture.

### 9.4 Development tooling exposure

`TanStackDevtools` is mounted in the root shell (§6.3). DevTools panels can expose router internals and should not ship enabled in production. Confirm the build strips or gates them before public launch.

---

## 10. Code Quality and Conventions

| Convention | Detail |
|---|---|
| **Strict TypeScript** | `strict`, `noUnusedLocals`, `noUnusedParameters`, `noFallthroughCasesInSwitch`, `noUncheckedSideEffectImports` all on |
| **Path aliases** | Import from `#/...` (and `@/...`), both mapping to `apps/web/src/` |
| **Class composition** | Always via `cn()` (`clsx` + `tailwind-merge`) to avoid conflicting Tailwind classes |
| **Generated files** | `routeTree.gen.ts` is generated; never edit by hand |
| **Component source of truth** | UI components follow shadcn conventions (`base-mira` style, CSS variables, Hugeicons) |
| **Module type** | `apps/web` is an ES module (`"type": "module"`) |

The codebase is small, idiomatic, and consistent with current TanStack Start + shadcn scaffolding conventions. There is little custom logic to assess yet.

---

## 11. Testing Strategy

The toolchain is configured for testing but no tests exist yet.

| Element | Status |
|---|---|
| Runner | Vitest 4 (`vitest run` via `bun run test`) |
| DOM environment | jsdom 28 |
| Component testing | `@testing-library/react` 16, `@testing-library/dom` 10 |
| Test files present | **None** |

> [!IMPORTANT]
> `bun run test` succeeds vacuously today because there are zero test files. As editor logic lands, establish test coverage from the first feature — the harness is already in place, so there is no setup cost.

---

## 12. Roadmap

From the project README, the rewrite is targeting:

- **An Editor API** — programmatic control of the editor.
- **First-class third-party plugins** — enabled by a plugin-first architecture.
- **One codebase for desktop, mobile, and browser** — via a shared **Rust core**.
- **An MCP server** — to let AI agents operate the editor.
- **Headless mode** — automation and batch rendering.
- **A scripting tab** — in-editor scripting.

> [!NOTE]
> None of the above is implemented in this repository. The Rust core, plugin system, MCP server, headless mode, and scripting tab are design goals. This repository is the web shell those features will attach to.

---

## 13. Improvements and Known Gaps

Source-based items worth addressing, derived from the current state of the repository.

- [ ] **Rebrand `public/manifest.json`** — it still carries the scaffold defaults (`"TanStack App"` / `"Create TanStack App Sample"`). Set OpenCut's name, short_name, theme color, and icons.
- [ ] **Resolve the domain-name inconsistency** — `__root.tsx` hard-codes the `<title>` `"OpenCut rewrite — beta.opencut.app"`, while `wrangler.jsonc` and the README use `new.opencut.app`. Pick one and align them.
- [ ] **Gate `TanStackDevtools` to development** — it is mounted unconditionally in the root shell (§6.3). Strip or guard it for production builds.
- [ ] **Add tests** — the Vitest/jsdom/Testing-Library harness is ready but unused (§11). Begin coverage with the first editor feature.
- [ ] **Build the editor** — the home route renders `null`. This is the central piece of work; everything else is foundation.
- [ ] **Design plugin/MCP trust boundaries up front** — the planned plugin system and MCP server are the project's future primary security surfaces (§9.3). Bake sandboxing and a permission model into the architecture rather than retrofitting them.

> [!NOTE]
> The community issues filed against OpenCut (export memory usage, playback stutter, audio/text bugs) pertain to the **classic** editor at `opencut-classic`, not to this rewrite repository, which contains none of that code. They are not actionable here.

---

## 14. Quick Reference

### Commands

| Action | Command | Run from |
|---|---|---|
| Install | `bun install` | repo root |
| Dev (all) | `bun run dev` | repo root |
| Dev (web only) | `bun run dev:web` | repo root |
| Build | `bun run build` | repo root |
| Preview build | `bun run preview` | `apps/web` |
| Test | `bun run test` | `apps/web` |
| Deploy | `bun run deploy` | `apps/web` |
| Tail logs | `wrangler tail opencut-web` | anywhere (authed) |

### Key files

| File | Purpose |
|---|---|
| `apps/web/wrangler.jsonc` | Cloudflare Worker name, domain, compat flags |
| `apps/web/vite.config.ts` | Vite + SSR + Cloudflare + Tailwind plugin chain |
| `apps/web/tsconfig.json` | Strict TS config + path aliases |
| `bunfig.toml` | Supply-chain install policy (7-day quarantine) |
| `turbo.json` | Monorepo task pipeline |
| `apps/web/src/routes/__root.tsx` | HTML shell, providers, devtools |
| `apps/web/src/routes/index.tsx` | `/` route (renders `null` today) |
| `apps/web/src/router.tsx` | Router factory + preload config |
| `apps/web/components.json` | shadcn/ui configuration |

### Facts

| Fact | Value |
|---|---|
| Dev port | `5173` |
| Worker name | `opencut-web` |
| Production domain | `new.opencut.app` |
| Compatibility flag | `nodejs_compat` |
| Compatibility date | `2025-09-02` |
| Package manager | `bun@1.3.11` |
| Path alias | `#/*` and `@/*` → `apps/web/src/*` |
| Mobile breakpoint | `768px` |

---

_Generated June 2026 from OpenCut-app/OpenCut at a5888e2. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
