Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

Unframer CLI

The unframer CLI has two main capabilities: exporting Framer components as React code and acting as a command-line client for Framer MCP. This page covers both.

Installation

npm install -g unframer
Or use npx to run without installing:
npx unframer --help

React Export commands

Download components

npx unframer {projectId} --outDir ./src/framer
Downloads all exported components as .jsx files (with JSDoc type annotations) and a styles.css file. The projectId is the short ID shown in the React Export plugin after exporting.

Create an example app

npx unframer example-app {projectId}
Scaffolds a complete Vite + React app with your components pre-configured. Good for seeing the export in action before integrating into your own project.

Watch for changes

npx unframer {projectId} --outDir ./src/framer --watch
Polls your Framer site URL and re-exports when changes are detected. You must click Publish in Framer for changes to be picked up.

Externalize packages

npx unframer {projectId} --outDir ./src/framer --external zustand
If esbuild fails because of a package conflict, use --external to skip bundling that package. Install it manually with npm install afterwards.

Framer sometimes uses older versions of npm packages internally. If you externalize a package, install the same major version Framer expects (e.g. zustand@3 instead of zustand@4).

MCP CLI commands

The CLI can also act as a direct MCP client, letting you interact with your Framer project from the terminal without an AI assistant.

Login

npx unframer mcp login
This prompts you to choose between Plugin mode (paste the MCP URL from the Framer plugin) or Server API mode (enter your Framer API key and project URL). Credentials are saved to ~/.unframer/config.json.

Project structure

# Full project XML (pages, components, styles) npx unframer mcp getProjectXml # Specific node by ID npx unframer mcp getNodeXml --nodeId "abc123" # Published website URLs npx unframer mcp getProjectWebsiteUrl

Modifying content

# Update text or attributes npx unframer mcp updateXmlForNode \ --nodeId "abc123" \ --xml '<Text nodeId="abc123">New heading text</Text>' # Search fonts npx unframer mcp searchFonts --query "Inter"

CMS operations

# List all collections npx unframer mcp getCMSCollections # Get items from a collection npx unframer mcp getCMSItems --collectionId "col123" # Create or update an item (use field IDs from getCMSCollections, not field names) npx unframer mcp upsertCMSItem \ --collectionId "col123" \ --slug "my-post" \ --fieldData '{"j11rZL4rT": {"type": "string", "value": "Hello"}}' # Delete an item npx unframer mcp deleteCMSItem --collectionId "col123" --itemId "item456"

Code files

# Create a code component npx unframer mcp createCodeFile \ --name "MyComponent.tsx" \ --content "export default function MyComponent() { return <div>Hello</div> }" # Read a code file npx unframer mcp readCodeFile --codeFileId "code123" # Update a code file npx unframer mcp updateCodeFile \ --codeFileId "code123" \ --content "// updated code"

Export React components

npx unframer mcp exportReactComponents
This triggers the same export pipeline as the React Export plugin, returning the CLI command to download the components.
exportReactComponents requires Plugin mode (the Framer MCP plugin must be open). It uploads the export through the authenticated plugin session. Server API mode cannot create a React Export project.

Help

Every command supports --help for detailed options:
npx unframer mcp updateXmlForNode --help npx unframer --help

Server API mode

In Server API mode, the CLI connects directly to Framer's cloud API without needing the browser plugin open. Use --project to specify which project to operate on:
npx unframer mcp getProjectXml --project "https://framer.com/projects/My-Project--abc123"
Expect an initial delay of ~9 seconds while the headless Chrome instance spins up. Each CLI invocation connects to Framer, runs the command, then disconnects when finished.