Convert Remotion-based TSX components into MP4 videos from a local terminal-style UI — no cloud, no CLI, fully offline.
TSX → MP4 is a local Mac app that takes a Remotion .tsx component file and renders it into a downloadable H.264 .mp4 video. It runs as a Node.js/Express server on localhost:4242 with a terminal-aesthetic drag-and-drop web UI.
No Remotion CLI setup required. No cloud rendering. Drop a file, click render, download the video.
- Drag & drop anywhere — drag TSX files onto the window from anywhere on your desktop
- Render queue — drop multiple files and render them sequentially, one after another
- Auto-detect composition — automatically reads your
compositionConfigexport and pre-fills the composition ID, resolution, fps, and duration - Auto-generated root file — no need to add
registerRoot()to your component; the server generates the entry point wrapper automatically - Per-item error cards — failed renders show the full error message with a retry button
- Open output in Finder — one-click button to open the output folder
- Terminal UI — hacker-style dark interface with scanlines, green-on-black, bracket buttons
- Node.js 18+ — nodejs.org
- macOS — uses
opencommand to launch Finder; core rendering works on Linux/Windows too
git clone https://github.com/your-username/tsx-to-mp4.git
cd tsx-to-mp4
./start.shThe browser opens automatically at http://localhost:4242.
First run installs all dependencies (~1 min). Every run after that is instant.
- Run
./start.sh - Drag your
.tsxRemotion file anywhere onto the window — or click [ BROWSE FILE ] - The app auto-detects your composition ID, resolution, and FPS
- Click ▶ RENDER QUEUE
- Watch the per-file progress bar in the queue
- Click [ DOWNLOAD ] when done — or [ OPEN OUTPUT ] to open the folder in Finder
You can queue multiple files at once and they render sequentially.
Your file must be a valid Remotion component with a default export and a compositionConfig export:
import { useCurrentFrame, AbsoluteFill } from 'remotion';
export const compositionConfig = {
id: 'MyVideo',
durationInSeconds: 5,
fps: 30,
width: 1920,
height: 1080,
};
export default function MyVideo() {
const frame = useCurrentFrame();
return (
<AbsoluteFill style={{ background: '#000', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<h1>Frame {frame}</h1>
</AbsoluteFill>
);
}The server reads compositionConfig to extract the composition settings and auto-generates a registerRoot() entry point — you never need to modify your component file.
tsx-to-mp4/
├── start.sh ← one-command launcher (installs deps, opens browser)
├── server/
│ ├── index.js ← Express server: /render, /detect, /jobs/:id, /open-output
│ └── package.json ← Remotion + Express dependencies
├── ui/
│ └── index.html ← terminal UI: queue, drag-drop, log, error cards
├── output/ ← rendered MP4s are saved here
└── temp/ ← auto-cleaned upload staging area
| Method | Route | Description |
|---|---|---|
GET |
/health |
Server status check |
POST |
/detect |
Extract compositionConfig from uploaded TSX |
POST |
/render |
Start a render job, returns { jobId } |
GET |
/jobs/:id |
Poll job status and progress |
POST |
/open-output |
Open output folder in Finder |
| Problem | Fix |
|---|---|
SERVER OFFLINE in UI |
Make sure ./start.sh is running in a terminal |
| Render fails immediately | Check the activity log — usually a TSX syntax or import error |
| Composition not found | Ensure your file exports compositionConfig with a valid id |
| Port 4242 already in use | Edit PORT in server/index.js |
| Node version error | Install Node.js 18+ from nodejs.org |
open command fails |
You're on Linux/Windows — open the output/ folder manually |
- Runtime — Node.js 18+
- Server — Express
- Bundler —
@remotion/bundler(Webpack) - Renderer —
@remotion/renderer(Puppeteer + FFmpeg) - Codec — H.264 via
renderMedia() - Frontend — Vanilla HTML/CSS/JS, no framework
MIT