The Problem
Web‑based video editors normally rely on server‑side rendering or proprietary SaaS APIs, exposing user media and API keys to third‑party services. Teams that need full privacy, offline capability, or fine‑grained cost tracking lack an open‑source, client‑only alternative that can still tap modern text‑to‑video, image‑to‑image and audio models.
What This Does
videosos delivers a full‑featured video editor that runs completely in the browser. The UI lives under src/app/ and src/components/, while model‑selection, pricing, and cost aggregation are implemented in src/lib/ (e.g., src/lib/fal.ts). Model metadata lives in data/fal_models_schemas.json. The project bundles FFmpeg‑wasm and Remotion for client‑side rendering, and stores everything in IndexedDB (src/app/api/uploadthing/ utilities).
Key files:
src/app/[locale]/page.tsx– entry page rendered by Next.js.src/components/right-panel.tsx– UI hub that pulls pricing (src/lib/pricing.ts) and model lists.src/lib/fal.ts– central façade for the fal.ai API; the largest source file (≈2 k lines).
How It Is Wired
- Startup –
npm run dev(ordocker compose up) launches the Next.js server defined bynext.config.mjs. The first request hitssrc/app/layout.tsx, which injects global CSS (src/app/globals.css) and loads locale data frommessages/*.json. - Model Loading –
src/components/right-panel.tsximportssrc/lib/fal.ts. That module readsdata/fal_models_schemas.jsonand exposesfetchModels()which calls the fal.ai endpoint (API key read fromprocess.env.FAL_API_KEY). - Cost Calculation – UI components (
src/components/ui/*) pull pricing viasrc/lib/pricing.ts. This module is imported by only a handful of components (instability 0.9) but performs HTTP calls to the provider’s pricing API, then caches results in IndexedDB. - Media Generation – When a user triggers generation,
src/components/media-panel.tsxinvokessrc/lib/fal.ts’sgenerateMedia()which returns a streaming URL. The response is stored via theuploadthinghelpers (src/app/api/uploadthing/core.ts) and displayed in the timeline (src/components/video-frame-selector.tsx). - Export – The “Export” button calls
src/components/export-dialog.tsx, which uses Remotion (remotiondependency) to compose the final video. Rendering happens in the browser via FFmpeg.wasm; the only external effect is a Blob download.
The import graph shows no circular dependencies and 95 internal modules with 82 edges. The most‑connected node is src/components/ui/button (10 inbound imports, 0 outbound), indicating a stable, low‑risk UI primitive. Conversely, src/components/right-panel imports 16 modules but is not imported elsewhere, giving it an instability of 1 – changes here have the widest blast radius.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/videosos
cd videosos
# Install Node dependencies
npm ci # uses package-lock.json
# Copy example env and add your API keys
cp .env.example .env
# edit .env → set FAL_API_KEY, RUNWARE_API_KEY, etc.
# Run locally (Docker optional)
npm run dev # starts Next.js on http://localhost:3000
# Or containerised build
docker compose up --build # builds docker/node/Dockerfile
The Makefile provides shortcuts (make lint, make test) that run the GitHub Actions lint workflow locally.
Real‑World Use
A marketing team can spin up the app on an internal workstation, load their private fal.ai key, and produce short promotional videos without any data leaving the device. The UI lets them select a model, preview cost (src/lib/pricing.ts), generate assets, arrange them on the timeline, and export a final MP4—all client‑side.
Code Health & Issues
- HIGH – Oversized files –
src/lib/fal.ts,src/components/media-panel.tsx,src/components/right-panel.tsxeach exceed 2 k lines; refactor into focused modules. - HIGH – Duplicated code – Repeated 6‑line blocks across 22 script files (
scripts/*.ts); extract shared helpers. - HIGH – Deep nesting – Max indentation depth 11 in
src/components/right-panel.tsx,tools/docs-scraper/scrape_models.py,src/components/left-panel.tsx; flatten with guard clauses. - MEDIUM – Broad exception handling –
scripts/parse_fal_models.pyuses bareexcept; replace with specific catches. - MEDIUM – High branching density –
src/lib/pricing.tsand related scripts contain >70 branches; consider strategy tables.
Additional observations: CI is defined in .github/workflows/lint.yml, but only linting runs; no test suite execution despite a single test file present. The repository contains committed secrets (docs/fal/pages/real-time/secrets.md). License (MIT) and lockfiles are present.
The Bottom Line
videosos offers a functional, privacy‑first browser editor with a rich model catalog, but the codebase suffers from large monolithic files and duplicated script logic that will increase maintenance cost. It is suitable for teams comfortable with Next.js and willing to invest in refactoring for long‑term stability.