Motion+ is distributed through a private npm registry at api.motion.dev. Your access token is a secret: it never belongs in package.json, lockfiles, or anything else you commit. The setup below keeps it in an environment variable instead.
You can find your token on your Motion+ tokens page.
Quick start (npm, pnpm, Bun)
1. Create (or update) .npmrc in your project root:
@motionplus:registry=https://api.motion.dev/npm/
//api.motion.dev/npm/:_authToken=${MOTION_TOKEN}
This file is safe to commit: it references an environment variable, not the token itself.
2. Add the dependency to package.json:
{
"dependencies": {
"motion-plus": "npm:@motionplus/core@^2.12.0"
}
}
This installs the scoped package @motionplus/core under the name motion-plus, so imports work exactly as documented:
import { Cursor } from "motion-plus/react"
If you prefer, you can depend on @motionplus/core directly and import from @motionplus/core/react instead.
3. Provide the token and install:
export MOTION_TOKEN=your-token-here
npm install # or pnpm install / bun install
Semver ranges work like any npm package: ^2.12.0, 2.12.0, latest.
Where to put the token
Your package manager reads ${MOTION_TOKEN} from the process environment at install time. How you set it depends on your tooling:
- Bun loads
.envfiles automatically. AddMOTION_TOKEN=...to.env(and.envto.gitignore) and you're done. - npm and pnpm do not read
.envfiles. Export the variable in your shell, use direnv, or prefix installs with dotenv-cli:npx dotenv-cli -- npm install.
Yarn
Yarn 1 (Classic) ignores the scoped-registry line in .npmrc, so add a .yarnrc alongside it:
"@motionplus:registry" "https://api.motion.dev/npm/"
Keep the .npmrc from the quick start: Yarn 1 reads the auth token from it. Then set MOTION_TOKEN in your shell and yarn install.
Yarn 2+ (Berry) uses .yarnrc.yml instead of .npmrc:
npmScopes:
motionplus:
npmRegistryServer: "https://api.motion.dev/npm"
npmAuthToken: "${MOTION_TOKEN}"
CI
Add MOTION_TOKEN as a secret in your CI provider and expose it as an environment variable. For example, in GitHub Actions:
- run: npm ci
env:
MOTION_TOKEN: ${{ secrets.MOTION_TOKEN }}
The same applies to deploy platforms that run your install step (Vercel, Netlify, etc.): add MOTION_TOKEN to their environment variable settings.
Migrating from the URL-based install
If you previously installed Motion+ via https://api.motion.dev/registry.tgz?...:
- Replace the dependency in
package.jsonwith the alias form from the quick start. Your imports don't change. - Add the
.npmrc(and.yarnrcor.yarnrc.ymlif you use Yarn). - Delete your lockfile entry for
motion-plus(or simply reinstall) so it re-resolves against the registry. - If your token was ever committed (in
package.json, a lockfile, or a URL), treat it as compromised: regenerate it from your account page.
The old endpoint keeps working, so you can migrate whenever suits you.
Troubleshooting
401 Unauthorized.MOTION_TOKENis empty or invalid at install time. Remember npm and pnpm don't read.envfiles; check the variable is actually exported in the environment running the install. Regenerate the token from your account page if needed.404fromregistry.npmjs.orgfor@motionplus/.... The scoped-registry config isn't being picked up. Check the.npmrcis in the project root (Yarn users: see the Yarn section above).- Install works locally but fails in CI or on deploy.
MOTION_TOKENisn't set in that environment. Add it as a secret. - Monorepos (pnpm workspaces, Rush, Turborepo). The config above works natively; place
.npmrcat the workspace root.