ZFlix is a full-stack hobby project with a Netflix-inspired architecture for browsing movies, series, and channels, tracking user activity, managing profiles, saving bookmarks, and handling subscription/payment flows from a shared monorepo.
ZFlix is built as a JavaScript/TypeScript monorepo inspired by Netflix-style product architecture:
packages/app: Expo + React Native app with web, Android, and iOS targets.packages/server: Node.js + Express backend service with Sequelize models, migrations, Redis caching, auth, media routes, payments, and subscription management.
The app uses a backend API for accounts, profiles, bookmarks, plans, media data, channel data, payment checkout, billing webhooks, and subscription state. The web build can be deployed to GitHub Pages, while the API is designed to run on Render or any Node hosting service.
- Movie, series, and channel discovery.
- User authentication and profile management.
- Bookmarks, watch activity, and personalized app data.
- TMDB-powered metadata flows.
- Redis-backed cache layer.
- Sequelize/MySQL persistence.
- Backend service for Stripe and PayPal payments, billing webhooks, and subscription flows.
- Expo web export for static hosting.
.
+-- packages
| +-- app # Expo / React Native client
| +-- server # Express API server
+-- .github # GitHub Actions workflows
+-- render.yaml # Render backend deployment blueprint
+-- package.json # Root workspace scripts
- Node.js 22+
- npm
- MySQL database
- Redis server
- TMDB API token/key
- Optional: Stripe, PayPal, SMTP, and media-service credentials
Create local env files from the examples:
cp packages/app/.env.example packages/app/.env
cp packages/server/.env.example packages/server/.envOn Windows PowerShell:
Copy-Item packages/app/.env.example packages/app/.env
Copy-Item packages/server/.env.example packages/server/.envImportant env rule:
packages/server/.envcontains private runtime secrets.packages/app/.envonly usesEXPO_PUBLIC_*values, which are bundled into web/native builds and are public.
Never put database passwords, Redis URLs, JWT private keys, Stripe secrets, PayPal secrets, or mailer passwords in EXPO_PUBLIC_* variables.
npm installThe API uses HTTP-only cookies for session and refresh tokens. When the API and the frontend run on different domains (e.g. Render + GitHub Pages), browsers block cookies unless SameSite=None; Secure is set. Browsers that block third-party cookies may also require Partitioned.
Add these to packages/server/.env:
# Cross-domain deployment (different API and frontend domains)
COOKIE_SAME_SITE=none
COOKIE_SECURE=true
COOKIE_PARTITIONED=trueFor local development (both on localhost):
COOKIE_SAME_SITE=lax
COOKIE_SECURE=false
COOKIE_PARTITIONED=falseNote:
COOKIE_SECURE=trueis required whenCOOKIE_SAME_SITE=none. Browsers silently dropSameSite=Nonecookies that are not markedSecure. UseCOOKIE_PARTITIONED=truewhen your frontend and API are on unrelated sites, such as GitHub Pages and Render. If both are under the same registrable domain, such asapp.example.comandapi.example.com, keep itfalseand prefer same-site cookies.
The backend is configured for Sequelize with MySQL.
Update packages/server/.env:
SEQUELIZE_DB=zflix
SEQUELIZE_USER=root
SEQUELIZE_PASS=your_password
SEQUELIZE_HOST=127.0.0.1
SEQUELIZE_DIALECT=mysql
SEQUELIZE_PORT=3306Run migrations:
npm --workspace server run db:migrateRun seeders when needed:
npm --workspace server run db:seedFor local development, run Redis and use:
REDIS_MODE=local
REDIS_LOCAL_HOST=127.0.0.1
REDIS_LOCAL_PORT=6379This repo also includes WSL helper scripts:
npm run start:redis
npm run stop:redisFor hosted deployments, use:
REDIS_MODE=external
REDIS_EXTERNAL_URL=rediss://default:password@host:portStart both the API and Expo app:
npm run start:devOr run each workspace separately:
npm run start:dev:server
npm run start:appUseful app commands:
npm --workspace app run start:web
npm --workspace app run android
npm --workspace app run iosBuild everything that has a build script:
npm run buildBuild only the backend:
npm run build:serverExport the web app:
npm run build:app:webThe Expo web output is generated in:
packages/app/dist
npm run typecheck
npm run lint- Frontend: GitHub Pages via
.github/workflows/deploy-pages.yml. - Backend: Render via
render.yaml. - Database: MySQL provider such as Aiven.
- Redis: Upstash Redis or another Redis-compatible service.
For the full deployment walkthrough, see:
For payment setup details, see:
This project is licensed under CC-BY-NC-4.0.