Skip to article

Motion Studio

Edit Motion animations in your running app. Preview keyframes, timing and springs, then apply the changes to source.

Motion Studio puts a timeline under your running app. Select an animation, change its timing or spring, and see the result on the page. Press Apply when you're ready to change the source.

You can also select an element and create an animation. Studio keeps it as a draft while you add keyframes and properties. Apply sends the final draft to your code agent.

Studio is included with Motion+. Agent usage is billed by your own Cursor, Codex or Claude account.

Install

Motion Studio requires Motion 13.3.0 or later and Node.js 20.19 or later. Studio runs in your local development environment.

Give this prompt to your code agent, or follow the steps below.

Get the package

Create a token on your Motion+ tokens page. Add these lines to the project's .npmrc:

@motionplus:registry=https://api.motion.dev/npm/
//api.motion.dev/npm/:_authToken=${MOTION_TOKEN}

Set MOTION_TOKEN in your shell. Keep the token out of source control. npm does not load it from .env.local.

Install the package:

npm install -D @motionplus/studio@^2

For pnpm, Bun, Yarn and CI setup, see Install Motion+. Use @motionplus/studio as the package name.

Vite

Add motionStudio() before your React or Vue plugin. Keep your other plugins and config:

import { defineConfig } from "vite"
import { motionStudio } from "@motionplus/studio"

export default defineConfig({
  plugins: [motionStudio()],
})

For Vue, keep vue() from @vitejs/plugin-vue after motionStudio(). Studio reads the .vue source before Vue compiles it.

Run your normal dev command. Vite runs the editor server. Open your app and press Alt+T (Option+T on macOS).

The plugin only runs during development. It adds no editor code to the production build.

Next.js

Wrap your existing Next config:

// next.config.mjs
import { withMotionStudio } from "@motionplus/studio/next"

const nextConfig = {}
export default withMotionStudio(nextConfig)

Run the editor server from your project root in one terminal:

npx motion-studio serve

Keep it running. Start Next.js in a second terminal:

npm run dev

Open your app and press Alt+T. The wrapper supports both Turbopack and Webpack. It only changes the development config.

The editor server uses http://localhost:5200. To change the port, update both the wrapper and server:

export default withMotionStudio(nextConfig, {
  serverUrl: "http://localhost:5300",
})
npx motion-studio serve --port 5300

Webpack

Add a development-only pre-loader to your existing rules. Keep your app's entry, output, loaders and dev server settings:

// webpack.config.cjs
module.exports = (_, argv) => ({
  module: {
    rules: argv.mode === "production" ? [] : [{
      test: /\.[cm]?[jt]sx?$/,
      exclude: /node_modules/,
      enforce: "pre",
      use: [{
        loader: require.resolve("@motionplus/studio/loader"),
        options: {
          boot: { serverUrl: "http://localhost:5200" },
        },
      }],
    }],
  },
})

Run npx motion-studio serve in one terminal and your Webpack dev server in another. The loader loads the panel for pages that run an instrumented animation.

For Vue with Webpack, put the Studio pre-loader on .vue files before vue-loader. Keep VueLoaderPlugin in your config.

Connect an agent

Choose a provider in .env.local:

MTL_AGENT_PROVIDER=cursor

The supported values are cursor, codex and claude. Restart the dev server after you change this setting.

Cursor is included. Use Connect Cursor in the panel to sign in. An existing Cursor SDK sign-in is reused.

Codex needs its SDK:

npm install -D @openai/codex-sdk
npx codex login

Claude needs its SDK and Claude Code sign-in:

npm install -D @anthropic-ai/claude-agent-sdk
claude auth login

If the Claude command is missing, install Claude Code. The editor reuses its sign-in.

Set MTL_AGENT_MODEL to override the provider's default model. The selected model must be available to your account.

You can preview and apply literal edits without an agent. Creating an animation and making changes through chat need a connected agent.

Edit an animation

  1. Open the animation menu. Trigger a hover, press or other interaction if its animation has not run yet.
  2. Select the animation. Drag the playhead to inspect it.
  3. Drag a bar to change its delay. Drag an end to change its duration.
  4. Double-click a track to add a keyframe. Select a keyframe to edit its values or easing.
  5. Choose Spring in the transition editor to tune bounce and visual duration, or stiffness, damping and mass.
  6. Press Apply, or Cmd+S on macOS and Ctrl+S elsewhere.

Changes stay in the preview until Apply. Use the discard control to remove pending changes.

Use Cmd+Z or Ctrl+Z to undo. Add Shift to redo. Draft edits and applied source edits have undo history. Source history belongs to the current dev server session.

Add an animation

  1. Press Add animation.
  2. Select an element on the page.
  3. Choose Animation, Hover, Press or In view.
  4. Add keyframes. Add a property from the keyframe panel. Use its delete button to remove a property.
  5. Preview the result, then press Apply.

The agent adds the final animation to your source. It uses the app's JavaScript, React or Vue form. A failed run keeps the draft available for another attempt. Check the agent message if it reports a partial change.

Computed values

A value that comes from an expression can appear as read-only. Use its agent action or describe the change in chat. Studio gives the agent the source location and the requested change.

Direct edits change literal values in place. Agent edits can change the surrounding code. Both appear in the source undo history.

Supported animation forms

Studio reads JavaScript, TypeScript, JSX, TSX and Vue single file components. It supports animate(), sequences, component animation props, variants and gesture poses.

  • JavaScript: full and mini Motion, named aliases and namespace imports.
  • React: motion, m, the client entry points and scoped useAnimate() calls. Existing framer-motion imports are supported.
  • Vue: motion, m, Motion, M, useAnimate() and v-motion, including template props and directive objects.

Imports through your own wrapper module are not statically resolved. Runtime expressions and imported objects can need an agent edit. Studio currently exposes the timeline editor. Scroll and motion value editors are not part of this release.

Troubleshooting

The panel does not appear. Confirm the app runs in development. Press Alt+T. For Next.js and Webpack, check that the editor server is running and that its port matches serverUrl.

No animations appear. Trigger the interaction first. Check that the file imports Motion directly. An animation created by a wrapper in another package might not have a source location Studio can edit.

Apply reports a stale file. The source changed since the preview was made. Reload the page and make the edit again. Studio rejects stale edits to protect changes made in your code editor.

The agent is unavailable. Check MTL_AGENT_PROVIDER, install that provider's SDK, and complete its sign-in. Restart the dev server after you install an SDK.

A custom local hostname cannot save. Allow the app's origin when you start the companion server:

npx motion-studio serve --origin https://app.local:3000

The page must be able to reach the companion server. Use a local HTTPS proxy if your browser blocks an HTTP server from an HTTPS page.

Stop Studio. Close the panel with Alt+T. To remove it from development, remove the Vite plugin or Next.js wrapper, or remove the Webpack rule. Stop the companion server if you use one.