patx/youtube-clone

Cheated on gpt for claude on this absolutely pointless YouTube clone. Writing a webapp like Youtube is the easiest part! Hosting, bandwidth, serving, load balancing, CDNs, payment, storage are all out of scope ;)

$ git clone https://gitman.io/git/patx/youtube-clone

MeTube

A YouTube-style video platform: accounts, uploads, a browsable catalogue, likes, threaded comments, and channel subscriptions.

It runs on Node's standard library alone — no npm dependencies. The HTTP server, router, session auth, multipart upload parser and range-request media server are all hand-rolled, and the database is Node 22's built-in node:sqlite. The front end is a vanilla ES-module SPA with no build step.

Running it

npm run seed     # creates the database and renders sample videos with ffmpeg
npm start        # http://localhost:3000

npm run dev restarts on file changes. npm run reset wipes the database and all media, then re-seeds from scratch.

Requirements: Node 22.5+ (for node:sqlite) and ffmpeg/ffprobe on your PATH — used to probe durations and cut thumbnails on upload, and to generate the sample clips.

Demo accounts

The seed builds six channels and five viewers. Sign in as any of them with the password password123:

Channel About
pixelforge Generative art and shader breakdowns
quietkitchen Slow cooking, sharp knives
northbound Long walks in cold places
lowlatency Competitive play and frame data
roomtone Home recording on a budget
thedailyloop A five-minute news digest

Viewer accounts: marta, dev_haruki, clara_b, sam.reads, tuesday.

What it does

Accounts — sign up, sign in, sign out. Passwords are hashed with scrypt (16384/8/1) and compared in constant time; sessions are opaque 32-byte tokens in an HttpOnly, SameSite=Lax cookie, expiring after 30 days.

Browse — a paginated home grid, category filters, search across titles, descriptions and channel names, a trending sort, and a subscriptions feed. Hovering a card cross-fades the still into the real video, muted, while an amber hairline sweeps the frame and the duration badge counts down.

Watch — an HTML5 player served over HTTP range requests, so seeking works against the file on disk. Views are counted once playback actually starts and recorded to your history. Likes and dislikes render as a two-sided meter with a ratio bar underneath.

Comments — post, reply one level deep, like, and delete. A video's owner can remove any comment on it; everyone can remove their own. Comments from the channel that published the video are badged CREATOR. Sort by top or newest.

Subscriptions — subscribe from a watch page or a channel page; your subscriptions appear in the sidebar with video counts and drive the feed.

Upload — drag-and-drop or browse, with a real progress bar (XHR) and a streaming server-side parser that writes straight to disk rather than buffering the file in memory. Duration is probed and a thumbnail is cut with ffmpeg. Limit 512 MB; MP4, WebM, MOV and OGG.

Your channel — edit your display name, bio and avatar colour; edit or delete your videos (deleting removes the media files too).

Library — history (with a clear button), liked videos, and watch later.

Plus: light and dark themes, keyboard focus styles throughout, / to focus search, prefers-reduced-motion respected (hover previews are disabled), and a layout that works down to a phone.

Layout

server/
  index.js      HTTP server, routing, static + media serving
  routes.js     every API endpoint
  model.js      queries and JSON shaping
  db.js         schema and connection
  auth.js       password hashing, sessions, cookies
  multipart.js  streaming multipart/form-data parser
  static.js     file serving with Range support
  http.js       request/response helpers
public/
  index.html    app shell
  css/app.css   design tokens and components
  js/           router, store, API client, DOM helpers, views
scripts/
  seed.js       demo data
  seeddata.js   channels, videos, comments
  videoclips.js ffmpeg recipes for the sample clips
data/           SQLite database and uploaded media (gitignored)

Design

The interface borrows the vocabulary of an editing suite rather than a social app: deep slate panels, a single phosphor-amber accent, and every number — durations, view counts, timestamps, subscriber totals — set in tabular monospace like timecode. Type is Bricolage Grotesque for display, Public Sans for body, JetBrains Mono for figures.

Notes and limits

  • Sessions live in SQLite; expired rows are ignored on lookup but not swept.
  • Uploads are stored as-is — there is no transcoding, so playback depends on the browser supporting the uploaded codec.
  • Everything is served over HTTP for local use. Behind TLS you would want the Secure flag on the session cookie.
  • There is no rate limiting, moderation or email verification.

The sample videos

The clips are generated, not downloaded: each is an ffmpeg render of a generative source — Mandelbrot drifts, Conway's life, rule-110 automata, Sierpinski carpets, gradient fields — graded and captioned, with a tone bed for audio. Recipes live in scripts/videoclips.js, and each clip's variant picks different coordinates, seeds and palettes so no two look alike.