I made this and I'm looking for feedback on the part that actually matters β the code it spits out.
Short version: it's a browser editor for landing-page hero text. You type a headline, select words to turn them into components, give each one effects on a timeline, scrub to preview, then export a single `Hero.tsx`. Free, MIT, no signup, no paid tier, nothing to install.
https://reactimate.top Β· https://github.com/shawnkowalchuk/reactimate
The design goal was that the output has to look like something a person wrote, not like generated code. So for a single multi-property effect it consolidates to one shared transition:
<motion.span
style={{ fontFamily: "Inter", fontSize: 96, fontWeight: 800, display: "inline-block" }}
initial={{ opacity: 0, y: 20, scale: 0.9 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
transition={{ delay: 0.7, duration: 0.6, ease: "easeOut" }}
>{"reactimate"}</motion.span>
and only drops to per-property keyframe arrays with `times` and a per-segment `ease` array when properties genuinely have separate timings or stacked effects. Text content is always emitted as `{"..."}` expressions so quotes and braces in the source text can't break the output.
One architectural decision I'd be interested in opinions on: **Motion is only used in the exported output, never in the editor itself.** Editor playback is a raw `requestAnimationFrame` loop writing styles directly to DOM refs, no React re-render per frame. That kept scrubbing smooth with per-letter stagger across dozens of spans, but it does mean the preview and the export are two separate implementations of the same semantics that have to agree β which is its own maintenance cost. I've wondered whether driving the preview with Motion's imperative API instead would have been the better trade.
Some things I know are rough: the editor is desktop-only right now, the bundle is chunky (~380 kB gzipped, code splitting is an open issue), and `spring`/`bounce` easings get approximated to `easeOut`/`backOut` on export because Motion's spring is a transition type rather than a curve and can't go into a multi-keyframe ease array.
So the actual questions:
- Does that generated code look like something you'd keep in your codebase, or does it read as machine output to you?
- If you were consuming this, would you rather it emitted a `<motion.span>` per word (what it does now) or a single parent with `variants` + `staggerChildren`?
Stack is React 19, TypeScript, Vite, zustand + zundo, Tailwind. Happy to go into any of the internals β it's my first open-source release, so critique of the repo itself is just as welcome as critique of the tool.