Personal Project

CanonCore

Google Drive meets Netflix. Visual browsing, drag-and-drop organisation, watch progress, collections others can fork.

Year

2025–Present

Technologies

Next.js 16, React 19, React Native, Expo

Source

GitHub

Live Site

Visit

The Product

CanonCore turns Google Drive into a fully featured media library: visual browsing, metadata enrichment, progress tracking, and public sharing, without moving or duplicating your files. The name comes from "canon" - the app pulls canonical metadata from sources like TMDB, with planned support for Fandom/MediaWiki and more. Create folder structures for movies and TV shows, reorganise with drag and drop, enrich items from TMDB, track what you've watched, and share collections publicly. Your files live in your storage, not ours.

I use this daily for my own movie and TV library. Active development continues with a React Native iOS app and interactive 3D graph visualisation — see In Progress below.


Features

Browsing & Organisation

Two views: Grid is Netflix-style with poster cards and progress bars. Tree is file explorer-style showing all descendants at once. Every item page has a hero banner. Folders display watched and total counts using a 90% completion threshold to account for credit skipping. "Go to next" performs a depth-first traversal to locate your first incomplete item automatically.

Edit mode enables drag-and-drop, bulk selection, and full keyboard navigation with screen reader announcements. Pinned items (max 10) appear in the sidebar. dnd-kit only loads in edit mode to keep browsing fast.

Tree view
Desktop video player with subtitle tracks

Media Playback

Vidstack-powered player streams media directly from Google Drive via HTTP range requests. Playback position auto-saves and resumes where you left off. Supports SRT, VTT, SUB, and ASS subtitle tracks.

One-Click Metadata

You can enrich movies and TV shows with TMDB metadata. A three-step wizard lets you search for a title, select from multiple poster options, and choose a backdrop image for hero banners.

Desktop TMDB search wizard with poster selection
Desktop sync panel and Drive connection UI

Google Drive Sync

All your media files stay in your Drive. Google's Changes API enables incremental syncs, fetching only changed items since the last update. If incremental sync returns no results, a verification step triggers a full sync. Conflicts are handled gracefully: if a file changed in Drive since your last sync, local changes are rejected with a notification. Errors are isolated per file.

Public Sharing

Make items public to share them. Your profile page shows your public items. The explore page shows public items from everyone with a featured banner carousel. Shared links generate dynamic preview cards for Twitter, Discord, and Slack.

Desktop explore page with featured carousel
Desktop fork to library dialog

Forking

Visibility inherits through the hierarchy—items can be public, private, or inherit from a parent. A public item with a private ancestor stays inaccessible. Other users can fork your collections into their own library, copying names, descriptions, artwork, and hierarchy. Media files and subtitles stay private. Think of it like sharing a Spotify playlist: the structure is public, the files aren't.

Spotlight Search

Press / anywhere to open Spotlight Search. Results load in parallel across Your Items, Public Collections, and People. A 60-second cache gives instant responses on repeat searches. Breadcrumb paths reveal each item's full hierarchy.

Desktop spotlight search modal
Desktop documentation with navigation and search

Built-in Documentation

Includes a documentation site built with Fumadocs.


In Progress

  • React Native iOS App — A native iOS companion app built with React Native and Expo. Browse your library, stream media, and track progress on the go, sharing the same backend and authentication as the web app.
  • 3D Graph Visualisation — Interactive 3D graph visualisation built with Three.js, rendering items and connections as a force-directed node network with camera controls, zoom, and real-time physics.

How It's Built

Architecture Decisions

Google Drive migration: I originally built this on SFTP, but path-based matching meant every rename or move created duplicates. No stable IDs, no change detection API, read-only from the web. Google Drive solved all of it: permanent file IDs survive renames and moves, Changes API for incremental sync, full read/write access so users can create folders directly from CanonCore. Should have started here.

Stack Auth → NextAuth.js v5: I started with managed auth, then migrated to self-hosted JWT sessions after hitting rate limits. I added 15+ rate limiters via Upstash Redis with different thresholds per action (strict for auth, generous for browsing).


Security & Resilience

Circuit breaker on TMDB and Google Drive calls to handle failures gracefully. Edge-level bot protection blocks 35+ AI crawlers while rate-limiting beneficial bots.


Performance

Extracted a view-only Grid from SortableGrid to avoid dnd-kit overhead in browse mode. Actions queue to IndexedDB when offline and replay on reconnect. Google Drive operations batched up to 100 per request, reducing sync time from ~45s to ~3s.


Accessibility

WCAG 2.1 AA compliant throughout. Reduced motion support via a custom hook that disables carousel autoplay and animations. Skip link to main content. ARIA live regions for drag-and-drop announcements.


Testing

2,400+ tests across unit, integration, and E2E layers. Vitest unit tests cover auth, items, Google Drive sync, and crypto operations. Integration tests run against real PostgreSQL. E2E tests with Playwright use the Page Object Model pattern and test against a real Google Drive account, not mocked. Tests automatically create missing fixtures for self-healing reliability.


Observability

Sentry error tracking across client, server, and edge runtimes with source maps for readable stack traces. Layered error boundaries catch failures at each route scope and report to Sentry automatically. OpenTelemetry distributed tracing via Vercel's integration and Speed Insights for Core Web Vitals monitoring in production.


CI/CD

GitHub Actions pipeline runs a quality gate (format, lint, type check, unused code detection) then kicks off tests and production build in parallel. Husky pre-commit hooks run ESLint and Prettier on staged files. Conventional commits enforced by commitlint.


SEO & Social Sharing

Dynamic OpenGraph images generated server-side for every public profile and item page — shared links show rich preview cards on Twitter, Discord, and Slack. JSON-LD structured data (Movie, TVSeries, Person schemas) for search engines. Dynamic sitemap keeps all public profiles and items indexed.


Component Documentation

All custom components are documented in Storybook.


Tech Stack

Front End: Next.js 16, React 19, React Native, Expo, TypeScript, Tailwind CSS 4, shadcn/ui, Vidstack, Three.js, dnd-kit, cmdk

Back End: Prisma 7, NextAuth.js v5, Server Actions

APIs: Google Drive (OAuth 2.0, Changes API), TMDB

Infrastructure: Vercel, Neon PostgreSQL (serverless branching), Upstash Redis, Sentry, GitHub Actions CI/CD