Drop a raw talking head video. Get back a finished Instagram reel.
Captions, cuts, branding — done. Runs as a macOS menu bar app.
- You pick a video from the menu bar app (or drop it in the
input/folder) - Groq Whisper transcribes every word with millisecond-accurate timestamps
- Claude reads the transcript and decides what to cut — pauses, false starts, dead air
- Remotion renders the final reel with animated word-by-word captions and delivery-based emphasis
- You get a finished
.mp4auto-named from the content, ready to post
- Node.js 20+
- Rust toolchain (for the Tauri menu bar app)
- ffmpeg + ffprobe installed
- API keys for Groq (Whisper) and Anthropic (Claude)
git clone https://github.com/phillhendry/reelforge.git
cd reelforge
npm install
# Add your API keys
cp .env.example .env
# Edit .env — add GROQ_API_KEY and ANTHROPIC_API_KEYnpm run tauri:devClick the tray icon to open the UI. Pick a video, hit render.
# Start the web server
npm run server
# Open http://localhost:3100
# Or use the CLI directly
npm run process -- ./input/my-video.mp4ReelForge runs as a macOS system tray app built with Tauri:
- Click the menu bar icon to toggle the popover
- No dock icon — stays out of your way
- Spawns the Express server automatically
- Open input/output folders in Finder from the UI
- Build a standalone
.appwithnpm run tauri:build
Claude analyses the transcript and produces an edit decision list:
- Cuts pauses >800ms, false starts, repeated phrases
- Keeps natural speech rhythm — single filler words in flowing sentences stay
- Snaps cuts to word boundaries with 80ms/150ms padding so nothing clips
- Fade-to-black ending with 400ms tail after the last word
Uses Remotion's native @remotion/captions system:
createTikTokStyleCaptions()for word grouping- Each caption page gets its own
<Sequence>for frame-perfect timing - Delivery-based emphasis — words spoken slower than median pace or after a pause get a bigger visual pop (larger scale, snappier spring, subtle highlight retention)
| Style | Description |
|---|---|
highlight |
Accent background highlights the active word |
bounce |
Active word scales up with a spring animation |
typewriter |
Words fade in as they're spoken |
minimal |
Active word is white, others are dimmed |
| Preset | Dimensions | Use Case |
|---|---|---|
instagramReel |
1080x1920 (9:16) | Instagram Reels, TikTok |
youtubeShort |
1080x1920 (9:16) | YouTube Shorts |
instagramSquare |
1080x1080 (1:1) | Instagram Feed |
landscape |
1920x1080 (16:9) | YouTube, LinkedIn |
- Queue multiple renders — each gets its own progress bar
- Cancel any active job mid-render
- Auto-watch mode processes files dropped in
input/(max 2 concurrent) - Toggle auto-watch on/off from the UI
- Clear finished jobs individually or all at once
Output files are auto-named from the AI analysis summary:
speaker-shares-tips-on-design-systems_2026-03-19T14-30-00.mp4
# Full edit + captions
npm run process -- ./input/raw-take.mp4
# Captions only — no AI editing
npm run process -- ./input/raw-take.mp4 --no-cuts
# Different caption style
npm run process -- ./input/raw-take.mp4 --caption-style=bounce
# YouTube Shorts preset
npm run process -- ./input/raw-take.mp4 --preset=youtubeShort
# Save debug files (transcript + EDL as JSON)
npm run process -- ./input/raw-take.mp4 --debugStart the server with npm run server (port 3100).
| Method | Endpoint | Description |
|---|---|---|
POST |
/render |
Start a render (used by the UI) |
POST |
/render/talking-head |
Start a render with full options |
POST |
/render/carousel |
Render carousel slides as a reel |
GET |
/status/:jobId |
Poll job progress |
GET |
/jobs |
List all jobs |
POST |
/cancel/:jobId |
Cancel an active job |
DELETE |
/jobs |
Clear all finished jobs |
DELETE |
/jobs/:jobId |
Clear a single finished job |
POST |
/auto-watch |
Toggle auto-processing { "enabled": true } |
GET |
/files |
List videos in input directory |
POST |
/open-folder/input |
Open input folder in Finder |
POST |
/open-folder/output |
Open output folder in Finder |
GET |
/health |
Health check |
input/video.mp4
│
▼
┌──────────┐
│ Probe │ ffprobe → dimensions, duration, fps
└────┬─────┘
▼
┌──────────────┐
│ Transcribe │ Groq Whisper → Remotion Caption[]
└──────┬───────┘
▼
┌──────────────┐
│ Analyse │ Claude → edit decision list
└──────┬───────┘
▼
┌──────────────┐
│ Pad + Remap │ Pad EDL for playback, remap captions
└──────┬───────┘
▼
┌──────────────┐
│ Emphasis │ Detect stressed words from delivery
└──────┬───────┘
▼
┌──────────────┐
│ Render │ Remotion SSR → MP4
└──────┬───────┘
▼
output/content-summary_2026-03-19.mp4
- Remotion — React-based video rendering with native caption support
- Groq Whisper — Fast cloud transcription with word-level timestamps
- Claude — AI editing decisions (not content generation)
- Express — HTTP server + file watcher
- Tauri — macOS menu bar app wrapper (~5MB binary)
Set in .env or pass via API:
BRAND_PRIMARY_COLOR=#ffffff
BRAND_ACCENT_COLOR=#E8FF00
BRAND_FONT_FAMILY=Inter# Development (hot-reload)
npm run tauri:dev
# Production build
npm run tauri:buildOutput:
src-tauri/target/release/bundle/macos/ReelForge.appsrc-tauri/target/release/bundle/dmg/ReelForge_1.0.0_aarch64.dmg
MIT. Remotion is free for individuals and companies up to 3 people.
Built by Phill. Blame Claude.