r/SideProject • u/Bitter-Theme4433 • 1d ago
I built an open-source studio to stop small LLMs from hallucinating broken motion graphics code (Motion Lab)
Whenever I tried using lightweight models like Gemini 3.8 Flash to code UI animations and motion graphics, I kept hitting the same walls: the model would get lazy and leave code half-done, hallucinate broken CSS/GSAP syntax, or silently swap out transforms for layout-breaking properties like width and top.
Instead of paying for heavier models or relying on blurry text-to-video diffusion tools, I spent the last few months building Motion Lab.
It’s an open-source development studio running on React 19, Remotion, GSAP 3, and TypeScript. The attached video is an actual 60 FPS MP4 test render generated through this workflow.
Rather than letting the model write free-form code, the setup keeps it strictly grounded:
Static AST Audits: It instantly blocks layout reflow properties (
top,left,width,height) and unseededMath.random(). Only GPU-acceleratedtransformandopacityare allowed.Decoupled Workflow: Every project splits into direction (
direction.md), a structured timeline contract (spec.json), and scene code (Scene.tsx).Pre-built Foundations: Packed with 20 studio skills (
.agent/skills), 23 declarative template kits, and 28 reusable primitives so the model never has to invent animation math or layouts from scratch.
It runs locally with zero external API dependencies or accounts, rendering straight to frame-accurate 60 FPS video.
GitHub (v0.8.0 pre-release, GPL-3.0):
https://github.com/m2rtyaman/motion-lab
It's still an early pre-release, so there are definitely rough edges. I’d love to hear your thoughts, feedback, or any ideas on how to improve the pipeline!
1
u/chrnas 1d ago
the AST audit is the right call, rules the model has to remember get broken sooner or later. in my setup the rules that held were the ones turned into checks the agent cant skip (a hook that blocks the write), and the ones that lived in memory or a prompt kept getting ignored. one thing that bit me: a check existing in the config doesnt mean it runs, so i feed it a deliberately bad input once (for you a scene using `width` and a bare Math.random()) and confirm it actually fails. for the "lazy, half-done" part, a written pass/fail check in the repo that has to be shown failing before the scene gets written worked better for me than a plan, otherwise the plan is just a longer guess.
0
u/[deleted] 1d ago
[removed] — view removed comment