Generate Manim math animations from natural-language prompts.
Manim AI is an end-to-end app where you type a math/animation idea (e.g., “visualize the derivative as a tangent line moving along a curve”), and the system:
- turns your prompt into Manim Python code using an LLM (OpenAI and/or Gemini)
- renders the animation inside an isolated Docker execution environment
- stores the result and lets you track status, preview, and download completed videos from the UI
This repo is a 3-service system:
- Frontend: Next.js app (
manim_frontend/) - Backend API: Express + TypeScript + Prisma + Clerk (
manim_backend/) - Render service: Python Flask service that executes Manim via Docker and notifies the backend via webhook (
Manim_microservice/)
- User submits a prompt in the frontend.
- Frontend calls the backend
POST /api/generate(authenticated via Clerk bearer token). - Backend creates a
Jobin Postgres, generates Manim code via LLM, then calls the Python render servicePOST /render. - Python service queues the render, runs Manim in a persistent Docker container, and then calls back the backend webhook
POST /webhooks/job-completion. - Backend marks the job completed/failed and (on success) creates a
Videorecord. Frontend pollsGET /api/status/:jobUuid.
Manim_Ai_Project/
├── manim_frontend/ # Next.js 15 + React 19 UI
├── manim_backend/ # Express API + Prisma (Postgres) + Clerk auth
└── Manim_microservice/ # Python Flask render queue + Manim-in-Docker executor
- Node.js: 18+ (recommended)
- Python: 3.10+ recommended
- Docker: required for rendering (the Python service uses Docker to run Manim)
- PostgreSQL: required for the backend (Prisma)
- Clerk: required for authenticated API calls (frontend uses Clerk)
- LLM API key: OpenAI and/or Gemini (backend supports both)
- S3-compatible storage (optional but supported): AWS S3 or MinIO (backend generates presigned download URLs)
From manim_backend/:
cd manim_backend
npm installCreate manim_backend/.env from manim_backend/.env.example and update values. Recommended local ports:
- Backend: 5000
- Frontend: 3000
- Python render service: 8000
Important env vars:
DATABASE_URL: Postgres connection stringCLERK_PUBLISHABLE_KEY/CLERK_SECRET_KEY: Clerk keysOPENAI_API_KEYand/orGEMINI_API_KEY(+ optionalGEMINI_MODEL)PYTHON_SERVICE_URL: usuallyhttp://localhost:8000FRONTEND_URL: usuallyhttp://localhost:3000(CORS allowlist)WEBHOOK_API_KEY: shared secret used to validate render callbacks
Initialize Prisma:
npm run db:generate
npm run db:migrateStart the backend:
npm run devHealth check:
GET /healthGET /api/health
From Manim_microservice/:
cd Manim_microservice
python -m venv .venv
source .venv/Scripts/activate # Windows Git Bash
pip install -r requirements.txtCreate Manim_microservice/.env from Manim_microservice/.env.example.
Critical env vars:
BACKEND_URL: should match your backend, e.g.http://localhost:5000WEBHOOK_API_KEY: must match the backendWEBHOOK_API_KEYPORT: default8000
Run the service:
python app.pyHealth check:
GET /health(python service)
From manim_frontend/:
cd manim_frontend
npm installCreate manim_frontend/.env.local:
NEXT_PUBLIC_API_BASE_URL=http://localhost:5000
Start the frontend:
npm run devOpen:
- Frontend:
http://localhost:3000
All /api/* routes below are authenticated (Clerk bearer token required).
POST /api/generate: create a job (returns{ jobUuid })GET /api/status/:jobUuid: poll job status; returns status, progress, andvideoIdwhen availableGET /api/videos: list user videos (paginated)GET /api/video/:videoId/download: get a presigned download URL (S3)
Webhook (called by the Python render service):
POST /webhooks/job-completion: expects headerX-Webhook-Key: <WEBHOOK_API_KEY>
- Port consistency: the frontend defaults to
NEXT_PUBLIC_API_BASE_URL=http://localhost:5000, so it’s easiest to run the backend on 5000 (setPORT=5000inmanim_backend/.env). - CORS allowlist: backend CORS origins are restricted; ensure
FRONTEND_URLandPYTHON_SERVICE_URLare set correctly in production. - Rendering requires Docker: the Python service uses Docker to run Manim; make sure Docker Desktop is running.
MIT (see LICENSE if present).
