SyncStream is a small learning project that demonstrates ingesting video into DASH fragments, serving them from a Node backend, a React + Vite frontend player, and real-time playback synchronization using WebSockets.
This README documents how to set up the project locally, common fixes (including husky issues), and how to run the frontend and backend.
Prerequisites:
- Node.js: install Node 20+ (20.x or >=22.12) — confirm with
node -v. - npm (bundled with Node) or an npm-compatible client.
- Git —
git --version. - ffmpeg / ffprobe (optional) if you plan to create DASH manifests locally:
ffmpegandffprobeon your PATH.
Repository layout (top level):
package.json— root workspace, dev tools, husky, lint-staged.backend/— Node backend (Express + WebSocket server).frontend/— React + Vite app.
Clone the repo and install dependencies from the project root. The repo uses npm workspaces so install at root to install both packages.
git clone <repo-url> SyncStream
cd SyncStream
npm installIf npm install fails while running the prepare script with an error like sh: husky: command not found (see Troubleshooting below), follow the Husky fix steps in section 3.
If you prefer to install only a specific package, run:
cd backend && npm install
cd ../frontend && npm installNote: running npm install at root (workspaces) is sufficient and recommended.
This repository uses Husky and lint-staged to run format/lint on staged files.
Root package.json contains a prepare script that should run husky install. If you see errors like sh: husky: command not found during npm install, it usually means either Husky is not yet installed, or the prepare script is incorrect.
How to ensure Husky is set up correctly:
- Install Husky as a dev dependency at the project root (if not already installed):
npm install --save-dev husky@latest- Update the root
package.jsonpreparescript to runhusky install(NOT justhusky). Inpackage.jsonit should look like:
"scripts": {
"prepare": "husky install",
...
}- Run the installer (this will create the
.husky/directory):
npm run prepare
# or
npx husky install- Add a hook example (optional):
npx husky add .husky/pre-commit "npx --no-install lint-staged"
git add .husky/pre-commit- Verify the hook:
ls -la .huskyandcat .husky/pre-commit.
If you'd rather avoid Husky during a quick install, you can temporarily skip prepare by setting the env var when running install:
HUSKY_SKIP_INSTALL=1 npm installBut it's recommended to fix the prepare script and run npm run prepare so commit hooks are active.
Open two terminals (or use a multiplexer) and run each package's dev server.
Backend (from project root):
cd backend
npm run dev
# script runs: `tsx watch src/index.ts` (see backend/package.json)Frontend (from project root):
cd frontend
npm run dev
# script runs: `vite` — opens on http://localhost:5173 by defaultIf you prefer root workspace commands (install and run via npm workspace flags):
npm run dev --workspace=frontend
npm run dev --workspace=backendBuild both packages (from project root):
npm run buildPreview frontend build:
cd frontend
npm run previewRun formatting and lint checks:
npm run format # runs Prettier across the repo
npm run lint # root script delegates to packages
npm run typecheck # runs TypeScript checks in workspacesYou can also run per-package scripts:
cd frontend && npm run lint
cd backend && npm run lint-
If
npm installfails withhusky: command not found:- Ensure Husky exists in
devDependenciesin rootpackage.json. - Change the
preparescript tohusky install(see Section 3). - Run
npm installagain, thennpm run prepare.
- Ensure Husky exists in
-
If you see workspace dependency resolution issues, delete
node_modulesand reinstall from root:
rm -rf node_modules package-lock.json
npm install- If ports conflict, check the dev server output; change Vite dev port by setting
PORTenv var for frontend.
- The repo uses npm workspaces — prefer installing from the project root to ensure consistent dependency hoisting.
- Use
HUSKY_SKIP_INSTALL=1only as a last resort when you must install without hooks; fix the underlyingpreparescript afterward. - For DASH ingestion or recreating sample media, ensure
ffmpeg/ffprobeare installed and on PATH.
If you want, I can also:
- open a small PR that updates the root
package.jsonpreparescript tohusky install, - or run the exact commands in your environment and validate
npm installsucceeds.
Tell me which you'd prefer.