Viz: the first local video editor for free. No server, no backend, no data leaves your machine. A fully client-side video editor that runs entirely in your browser.
Developed by Zrnge — github.com/zrnge/viz.
Built with Vanilla JS, Vite, and ffmpeg.wasm.
- Upload — Drag-and-drop or file picker (MP4, WebM, MOV, PNG/JPEG/GIF/WebP, MP3/WAV/AAC/OGG/M4A)
- Multi-track timeline — Video, image, text, and audio layers with vertical scrolling
- Preview — HTML5 video player with custom controls
- Edit — Trim, split, copy, paste, duplicate, delete, undo/redo
- Move between tracks — Drag clips vertically to compatible tracks
- Text overlays — Font, size, color, and background styling
- Audio mixing — Video audio + audio clips are mixed and exported
- Export — Download the edited video (MP4 via ffmpeg.wasm, WebM fallback)
- Project save/load — Export/import project JSON (timeline + edits; media files must be re-linked)
- Keyboard shortcuts — Space, Ctrl+S, Del, Arrow keys, Ctrl+E/Z/Y/C/V/D
All video processing uses ffmpeg.wasm, a WebAssembly port of FFmpeg. The WASM core is self-hosted in public/ffmpeg-core/ so the app works even if third-party CDNs are blocked, with a CDN fallback for resilience.
ffmpeg.wasm requires SharedArrayBuffer, which needs cross-origin isolation headers:
Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp
Local development: Vite's dev server sets these headers automatically.
GitHub Pages: Static hosts can't set custom headers, so we use coi-serviceworker.js — a service worker shim that injects the required headers. It causes one automatic page reload on first visit.
- Node.js 18+
- npm 9+
# Clone the repository
git clone https://github.com/zrnge/viz.git
cd viz
# Install dependencies
npm install
# Start development server
npm run devThe dev server starts at http://localhost:5173 with COOP/COEP headers enabled.
npm run buildThe prebuild script copies the self-hosted ffmpeg core from node_modules/@ffmpeg/core to public/ffmpeg-core/.
Preview the production build:
npm run preview- Push your code to the
mainbranch - Go to Settings → Pages in your GitHub repo (
https://github.com/zrnge/viz/settings/pages) - Under Source, select GitHub Actions — NOT "Deploy from a branch"
- The included
.github/workflows/deploy.ymlbuilds and deploysdist/on every push tomain - The site will deploy to
https://zrnge.com/viz/
Important: If you previously used "Deploy from a branch", GitHub Pages may keep serving the raw source files. After switching to GitHub Actions, go to Actions and re-run the latest workflow, then wait 1–2 minutes for the deployment to update.
Note:
vite.config.jsdefaults tobase: '/viz/'for deployments under the/viz/subpath (e.g.,zrnge.com/viz/). If you deploy to a custom-domain root (e.g.,zrnge.com/), set theBASE_PATHenvironment variable to/in the workflow or change the default invite.config.js.
npm run build
npx gh-pages -d distThen go to Settings → Pages and set the source to gh-pages branch.
├── public/
│ ├── coi-serviceworker.js # Cross-origin isolation shim
│ ├── 404.html # SPA redirect for GitHub Pages
│ └── ffmpeg-core/ # Self-hosted FFmpeg WASM core
├── scripts/
│ └── copy-ffmpeg-core.js # Prebuild copy helper
├── src/
│ ├── main.js # App orchestrator
│ ├── style.css # Dark theme + glassmorphism styles
│ ├── composition.js # Composition data model
│ ├── ffmpeg-worker.js # FFmpeg loading, audio mix, export
│ ├── multi-timeline.js # Multi-track timeline
│ ├── canvas-preview.js # Preview renderer + transforms
│ ├── video-player.js # HTML5 video player wrapper
│ ├── toolbar.js # Toolbar buttons & shortcuts
│ ├── upload.js # Drag-and-drop upload
│ ├── media-manager.js # Add video/image/text/audio
│ ├── properties-panel.js # Element properties editor
│ ├── context-menu.js # Right-click menu
│ ├── clipboard.js # Copy/paste/duplicate/delete
│ └── utils.js # Helpers (formatTime, validation, toasts)
├── index.html # SPA entry point
├── vite.config.js # Vite config (base path, headers, chunks)
├── package.json
└── README.md
| Key | Action |
|---|---|
Space |
Play / Pause |
Ctrl+S |
Split at playhead |
Del / Backspace |
Delete element |
Ctrl+E |
Export |
Ctrl+C / Ctrl+V |
Copy / Paste |
Ctrl+D |
Duplicate |
Ctrl+Z / Ctrl+Y |
Undo / Redo |
← / → |
Skip back/forward |
Shift+← / Shift+→ |
Frame step |
Made with ❤️ by Zrnge.
- Website: zrnge.com/viz
- Source: github.com/zrnge/viz
This means GitHub Pages is serving the raw source files instead of the built dist/ output.
Fix:
- Go to
https://github.com/zrnge/viz/settings/pages - Set Source to GitHub Actions
- Save, then go to
https://github.com/zrnge/viz/actions - Re-run the latest workflow
- Wait 1–2 minutes and hard-refresh
https://zrnge.com/viz/
GitHub Pages is not enabled. Follow the steps above and set the source to GitHub Actions first.
MIT