CLI workflow

The Reframe CLI installs published Framer components into an existing React project. Run every command from the project directory that contains your package.json.

The complete workflow is:

  1. Sign in to Reframe.
  2. Initialize the project once.
  3. Publish a component from the Reframe Framer plugin and copy its export ID.
  4. Add the component to your project.
  5. Use, update, rename, or remove the generated component as your project evolves.

Requirements

  • Node.js 22 or newer.
  • An existing React project with a package.json.
  • A Reframe account.
  • A component export ID from the Reframe Framer plugin.

The CLI supports JavaScript and TypeScript projects. It detects the project language from tsconfig.json, TypeScript source files, and package scripts.

You can check the installed CLI and its available commands at any time:

pnpx @reframejs/cli --version
pnpx @reframejs/cli --help

Authenticate

Sign in once on a machine:

pnpx @reframejs/cli login

The command opens a browser authorization page. Complete sign-in there and return to the terminal. If the browser does not open automatically, the CLI prints a URL and a short code that you can open manually.

Check the account currently used by the CLI:

pnpx @reframejs/cli status

Example output:

✓ Authenticated as you@example.com

To remove the local CLI credential from this machine:

pnpx @reframejs/cli logout

The credential is stored in the user-level Reframe configuration directory. Never copy it into source control or a frontend application.

Initialize a project

Initialize the project once, from the project root:

pnpx @reframejs/cli init

The CLI examines the folders already present in your project and suggests a parent directory for Reframe-managed files. It recognizes common layouts such as:

  • src/components
  • components
  • app/components
  • src/ui
  • ui

If your project has a src folder but no component folder, the default is src/components. If it has neither, the default is components. You can accept the suggestion or enter another project-relative path.

For example, choosing src/components creates this directory:

src/components/framer/
  components/
  assets/
  meta/
  styles/
  styles.css

Projects do not need a src folder. For an app that keeps components at the repository root, choose components:

pnpx @reframejs/cli init --path components

That project receives its generated files at components/framer/.

The CLI writes a small .reframe.json file at the project root. It records the selected output directory as a relative path, so the project remains portable when it is moved or cloned. Re-running init is safe.

Generated component files include a link to the Reframe documentation. The link comes from the published CLI release, so you do not need to edit the generated comments or add a documentation URL to your project. New components added with a later CLI release automatically receive that release's current documentation link.

Add an export

Select and publish a component in the Reframe Framer plugin. Copy the export ID shown by the plugin; it normally starts with rf_.

From your React project, run:

pnpx @reframejs/cli add rf_abc123

The command downloads the private export associated with your Reframe account, detects whether your project is JavaScript or TypeScript, and writes the generated component into the managed framer directory. It also copies any assets and styles required by the export and records the installation locally.

After a successful add, the output includes the local component path. Import that path into your application:

import Button from "./components/framer/components/button";

export default function HomePage() {
  return <Button buttonText="Get started" />;
}

The CLI also inspects the generated imports and makes sure the Reframe runtime and any external packages used by the export are available in your project. When a package is missing or cannot be resolved, it uses the package manager detected from your project to install it. For example, a component that imports three and gsap can cause those packages to be added automatically. The command prints the packages it installs.

If your package manager blocks an install—for example, pnpm may require you to approve a native build script—follow the package manager's prompt and run the same add command again. You can also install the reported packages yourself from the project root.

An export ID is private and account-scoped. A component name alone is not a substitute for the ID, and another account's private export cannot be downloaded with your credentials.

Give an installed component a custom local name

Use --name when the local file name should be different from the published Framer component name:

pnpx @reframejs/cli add rf_abc123 --name marketing-navbar

The CLI converts the value into a safe local file name. In a TypeScript project, the result is organized like this:

src/components/framer/
  components/
    marketing-navbar.tsx
    marketing-navbar.jsx
    marketing-navbar.runtime.jsx
  styles/
    marketing-navbar.css
  meta/components/
    marketing-navbar.json

Use the custom local path in your application:

import MarketingNavbar from "./components/framer/components/marketing-navbar";

export default function MarketingLayout({ children }) {
  return (
    <>
      <MarketingNavbar.Responsive />
      {children}
    </>
  );
}

The published component's behavior, props, variants, and assets remain the same. --name changes the local installation name and the generated file locations; it does not create a new Framer export.

This is useful when two different exports have the same display name:

pnpx @reframejs/cli add rf_old-navbar --name legacy-navbar
pnpx @reframejs/cli add rf_new-navbar --name navbar

Without --name, Reframe protects an existing local component by assigning a collision-safe name. Use --name when you want a name that communicates the role of each version clearly.

If the same export is already installed and you pass a new --name, the CLI moves that installation to the new local name and updates its registry entry. It does not keep two copies of the same export under two names. To keep two different versions at the same time, publish them as separate exports in Framer and install each with its own ID and local name.

List installed components

The local Reframe registry remembers each installed component's export ID, local name, version, and generated component file. List everything currently installed:

pnpx @reframejs/cli list

Example output:

Installed Reframe components:
  button                   rf_11d1e45f520e97715b974b18  src\components\framer\components\button.jsx
  marketing-navbar        rf_abc123                       src\components\framer\components\marketing-navbar.tsx
  pricing                 rf_d7ee80388d53b2414f1648d8     src\components\framer\components\pricing.jsx

To find the ID for one local component, pass its local name or file stem:

pnpx @reframejs/cli list pricing

Example output:

pricing
  ID: rf_d7ee80388d53b2414f1648d8
  File: src\components\framer\components\pricing.jsx
  Version: v3

You can also search by the published component name or by the full Reframe ID. The command reads the current project's registry; it does not search every component available in your Reframe account.

Update an installed component

Run add with the same export ID when a new version is published:

pnpx @reframejs/cli add rf_d7ee80388d53b2414f1648d8

Reframe compares the published version and checksum with the local registry. If nothing changed, it reports that the component is already up to date. If it changed, the CLI shows the old and new versions and asks for confirmation:

"Pricing" has changed (v3 → v4). Update local component? [y/N]

Answer y to update, or use --yes in scripts and CI:

pnpx @reframejs/cli add rf_d7ee80388d53b2414f1648d8 --yes

Only files owned by the selected export are updated. Keep application wrappers, routes, and product-specific CSS outside the managed framer directory so they remain yours when the export changes.

Remove an installed component

Use list first when you know the local file name but not the export ID:

pnpx @reframejs/cli list pricing

Then remove it by ID:

pnpx @reframejs/cli remove rf_d7ee80388d53b2414f1648d8

For convenience, the local name also works:

pnpx @reframejs/cli remove pricing

The CLI asks you to confirm before deleting anything:

Remove "Pricing" and its generated files? [y/N]

Use --yes for a scripted cleanup:

pnpx @reframejs/cli remove pricing --yes

Removal deletes the generated component entry point, export stylesheet, component metadata, and other files recorded for that export. It rebuilds the managed stylesheet index so the removed component is no longer imported. A shared asset is kept when another installed component still uses it.

Before removing a component, search your application for imports of it and delete or replace those imports:

// Remove this import if the Pricing export is no longer used.
import Pricing from "./components/framer/components/pricing";

The CLI does not edit your routes, pages, wrappers, or application code. If a query matches more than one installed component, it stops and prints the matching IDs; run remove again with the exact ID to select one safely.

Create a preview project

To inspect an export in an isolated app, run:

pnpx @reframejs/cli create --component <component-id>

This creates a new Vite React project with the selected component as one of the starter options. It installs the generated dependencies and prints the output directory and development command.

Choose an output directory explicitly:

pnpx @reframejs/cli create \
  --component rf_d7ee80388d53b2414f1648d8 \
  --out ./pricing-preview

Use --no-install when you only want the generated project files:

pnpx @reframejs/cli create \
  --component rf_d7ee80388d53b2414f1648d8 \
  --out ./pricing-preview \
  --no-install

Enter the output directory and install dependencies with your preferred package manager before starting the preview.

Common problems

Initialize the project before adding components

Run init from the same project root where you run add, list, or remove:

pnpx @reframejs/cli init

If you have already initialized the project, confirm that .reframe.json is next to the correct package.json.

Sign in before running commands

Run:

pnpx @reframejs/cli login
pnpx @reframejs/cli status

list and remove operate on your local registry and do not need a network request, but add, updates, and preview creation require access to the published export.

The component is not found

Copy the complete export ID from the plugin. An export ID usually starts with rf_; it is not the Framer component name. If you are trying to remove an installed component, run pnpx @reframejs/cli list first and use the ID shown there.

The browser authorization page does not open

Copy the URL printed by the CLI and paste it into a browser. The authorization request stays active while you complete the flow.

Package installation fails

The CLI writes the component files and then installs dependencies detected from the generated source. Read the package manager's message if an install fails, install the reported packages from the project root, and run the command again. With pnpm, a message about ignored build scripts is controlled by pnpm's dependency security settings; follow pnpm's prompt to approve the required dependency build script, then retry the installation.

A graphics or WebGL component has no visible size

Browser graphics components need a non-zero layout box before they can create a canvas or renderer. Reframe adds a small runtime guard for common WebGL exports, but your application still needs to give the component usable dimensions:

import InteractiveScene from "./components/framer/components/interactive-scene";

export default function SceneSection() {
  // The explicit height gives the canvas a real drawing area.
  return (
    <InteractiveScene style={{ width: "100%", height: 420 }} />
  );
}

If the component exposes width and height props, you can use those instead. The CLI can install imported packages such as three, but it cannot choose the right visual dimensions for a component's surrounding layout.

A remove command reports no matching component

Use the exact local file stem or export ID from the registry:

pnpx @reframejs/cli list
pnpx @reframejs/cli remove rf_abc123

Make sure you are running the command from the same project root where the component was installed. Also check the spelling of the package name: @reframejs/cli includes the js in reframejs.