# Build brief — a focused alternative to Netflix

> **Verdict:** Not faithfully · **Buildability:** 48/100 · **Category:** Audio Video
> **Source:** https://www.canitbevibecoded.com/netflix
> Independent editorial assessment from Can It Be Vibe Coded? Not affiliated with, endorsed by, or derived from Netflix. Verify current pricing and capabilities before acting.

## Context

**Netflix** — Subscription streaming service for licensed and original film and TV. It currently costs $19.99/mo.

You can absolutely build a Netflix, the software part is the easy part. A video catalog, transcoding pipeline, adaptive streaming player, watch progress, and profiles is a genuinely fun weekend of work, and self-hosted media servers already prove it. What you cannot build is the thing you were actually paying for: thousands of hours of licensed content plus originals you legally cannot obtain. A media server pointed at an empty disk is a very nice empty shelf. The honest DIY move is Jellyfin or a hand-rolled version of it over media you already own, which changes what the product is rather than replacing it.

This brief describes a focused, single-operator replacement for the part of Netflix that is genuinely reproducible. It is deliberately narrower than the product it replaces, and it says so in writing. Build the useful core; do not pretend to have rebuilt the rest.

## What you are building

A self-hosted streaming site that scans a local media folder, pulls metadata and artwork, and plays it back in the browser with per-profile resume.

- Transcribe supplied recordings, cut them on a timeline, and export finished files.
- A responsive interface with real empty, loading, success, and error states.

## Requirements

### Functional

- Media files you actually have the right to store.
- A machine with disk space and enough CPU or a GPU for transcoding.
- Ffmpeg installed.
- Bandwidth if you want to stream outside your own network.

### Data and integrations

- A metadata API key, for example TMDB.

Each of these needs a real account, credential, or quota. Set them up before writing feature code.

### Non-functional

- Accessibility: semantic markup, labelled controls, visible focus, and reduced-motion support.
- Security: server-side secrets, validated input, and no credentials in the client bundle.
- Reliability: retries with backoff on external calls, and a clear failure state when a provider is down.
- Portability: the operator can export their data and leave without losing it.

## Implementation brief

Build a self-hosted personal media streaming server and web player. Single project, runs on my own machine, no accounts service, no cloud, no telemetry.

Stack, no substitutions:
- Node.js with TypeScript, Fastify for the API
- SQLite via better-sqlite3 for the library database
- React with Vite for the frontend, plain CSS, no component library
- ffmpeg and ffprobe invoked as child processes
- hls.js in the browser for playback

What it does:
1. Reads MEDIA_ROOT from .env and recursively scans it for video files (mp4, mkv, avi, mov). Parses filenames into title, year, and optional season/episode.
2. Runs ffprobe on each file to record duration, resolution, codecs, and audio tracks.
3. Optionally enriches each title with metadata and poster art from the TMDB API using TMDB_API_KEY from .env. If the key is missing, skip enrichment gracefully and show a generated placeholder poster.
4. Serves a library browse UI: poster grid, search, filter by movie vs series, series drilldown to seasons and episodes.
5. Plays video at /watch/:id. If the source is browser-friendly h264/aac, stream it directly with HTTP range support. Otherwise transcode on the fly to HLS with ffmpeg, segmenting into a cache directory, and serve the playlist to hls.js. Reuse cached segments on repeat plays.
6. Tracks watch progress per profile. Local profiles are just names in SQLite, no passwords, no auth provider. Resume where you left off, mark watched at 90 percent, and show a Continue Watching row.
7. Extracts embedded subtitle tracks with ffmpeg, converts to WebVTT, and exposes them as selectable tracks in the player.
8. A CLI command "npm run scan" for rescanning, plus a watcher that picks up new files while running.

Explicitly out of scope: any content acquisition, downloading, scraping, or DRM. No native mobile or TV apps. No recommendation engine beyond a recently-added row. No multi-user auth or public internet exposure; bind to localhost by default and document that exposing it is my problem.

Deliver a README with setup steps, a .env.example listing MEDIA_ROOT, TMDB_API_KEY, PORT, and TRANSCODE_CACHE_DIR, and seed the database on first run. Keep the whole thing runnable with npm install then npm run dev.

## Delivery standard

- Inspect the repository first, then write a short implementation plan before writing code.
- Deliver the smallest complete end-to-end workflow first; every primary control must work against persisted data.
- Use real validation and storage; never substitute fake dashboards, decorative controls, hard-coded success states, or mock integrations.
- Include responsive layouts plus genuine empty, loading, success, validation, and failure states.
- Keep secrets server-side in environment variables, provide .env.example, and never commit credentials or user data.
- Add structured logs around every external call and return actionable errors without leaking sensitive details.
- Write unit tests for the core logic and one automated test of the main user journey.
- Finish with a README covering setup, architecture, data location, backups, tests, deployment, and known limitations.

## Acceptance criteria

- [ ] A clean install starts the app using only the README and .env.example.
- [ ] The primary journey works from first visit through saved result, reload, edit, export, and deletion where applicable.
- [ ] Invalid input, missing configuration, provider failure, and an empty database each have a usable state.
- [ ] The interface works at 390px and 1440px, is keyboard navigable, and shows visible focus on every control.
- [ ] Tests, type checking, linting, and a production build all pass with no ignored failures.
- [ ] No part of the interface implies a live integration, security guarantee, or scale capability that was not actually built and verified.

## Non-goals

Do not build these, and do not claim to have replaced them:

- The entire catalog: licensed films, TV, and originals you cannot legally acquire.
- Global CDN delivery that does not stutter on hotel wifi.
- Native apps on every TV, console, phone, and streaming stick.
- Downloads with DRM, offline playback, and multi-device sync that just works.
- Recommendations built on hundreds of millions of viewing histories.

## What you still own after launch

- Secure credentials, rotate secrets, and handle provider rate limits.
- Run migrations, backups, restores, and dependency updates.
- Test the critical journey after every model, API, or hosting change.
- Monitor failures and fix the edge cases a first prompt will miss.

## Risk

**Operational risk.** The code is achievable; dependable data, integrations, and ongoing operations are the real cost.

Editorial confidence in this assessment: high. No reviewed project implementation is linked yet.

---

Generated by [Can It Be Vibe Coded?](https://www.canitbevibecoded.com) · Full report: https://www.canitbevibecoded.com/netflix
