React Export - Docs
Use Framer-exported React components in any React project. Two flows - pick whichever fits.
Two flows
In the Proofly React Export plugin in Framer, after selecting components you'll see two options:
- Integrate in project (recommended) - publish to npm, install with a single command. Zero files in your repo.
- Download scaffold .zip - standalone Vite demo project. Good for prototyping or exploring.
Integrate flow - setup
The plugin will hand you an install command. Paste it in your project root:
npm install @proofly-framer/ui@https://registry.proofly.ae/ui/<exportId>.tgz
The runtime (@proofly-framer/runtime) installs transitively - you don't name it on the command line.
Then import components from @proofly-framer/ui anywhere:
import { Button, Footer } from '@proofly-framer/ui'
export default function Page() {
return (
<>
<Button variant="Primary" title="Contact" />
<Button variant={{ lg: 'Desktop', base: 'Mobile' }} />
<Footer />
</>
)
}Per-framework setup
Next.js (App Router)
No config needed. Every component file already declares "use client" so they work in client and server trees alike. Use them directly inside server components or client components.
For no-FOUC CSS on first render, import the runtime stylesheet at your layout root:
// app/layout.tsx
import '@proofly-framer/runtime/styles.css'
export default function Layout({ children }: { children: React.ReactNode }) {
return <html><body>{children}</body></html>
}Next.js (Pages Router)
// pages/_app.tsx
import '@proofly-framer/runtime/styles.css'
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}Vite + React
// src/main.tsx
import '@proofly-framer/runtime/styles.css'
import { createRoot } from 'react-dom/client'
import App from './App'
createRoot(document.getElementById('root')!).render(<App />)Remix
// app/root.tsx
import styles from '@proofly-framer/runtime/styles.css?url'
export const links = () => [{ rel: 'stylesheet', href: styles }]Astro (React islands)
Use React islands as usual. Framer components require React 19+; make sure your Astro integration is on the matching version.
Polymorphic variant prop
The variant prop accepts either a string (fixed variant) or an object mapping breakpoints to variant names. Fixed variants render as-is; objects switch on viewport width at base (0), sm (320), md (768), lg (960), xl (1200).
<Button variant="Primary" /> // fixed
<Button variant={{ base: 'Mobile', lg: 'Desktop' }} /> // responsive
<Button variant={{ base: 'Mobile', md: 'Tablet', lg: 'Desktop' }} />Updating after a re-export
When the designer re-exports in Framer, they'll share a new install command with a new export ID. Two ways to apply it:
# Option 1 - paste the new install command the plugin gave you npm install @proofly-framer/ui@https://registry.proofly.ae/ui/<new-id>.tgz#sha512-<integrity> # Option 2 - run our helper CLI (updates package.json + re-installs) npx @proofly-framer/update <new-export-id>
Package-manager syntax
# npm / pnpm / yarn classic / bun - no quotes needed npm install @proofly-framer/ui@https://registry.proofly.ae/ui/<id>.tgz pnpm add @proofly-framer/ui@https://registry.proofly.ae/ui/<id>.tgz yarn add @proofly-framer/ui@https://registry.proofly.ae/ui/<id>.tgz bun add @proofly-framer/ui@https://registry.proofly.ae/ui/<id>.tgz # yarn 3+ (berry) - wrap the dep spec in quotes yarn add "@proofly-framer/ui@https://registry.proofly.ae/ui/<id>.tgz" # @proofly-framer/runtime installs transitively - no need to name it
Requirements
- React 19+ (and
react-dom19+) - we rely on the React 19<Context>shorthand andprefetchDNShints. - TypeScript with
moduleResolutionset tobundlerornode16/nodenext(forexportsmap support). - Do not install
framer-motionseparately. Our runtime bundles it to guarantee a single shared instance.
Customizing
Wrap components in your own files - this is the standard React pattern and the intended customization point:
// src/components/TrackedButton.tsx
import { Button } from '@proofly-framer/ui'
import type { ComponentProps } from 'react'
export function TrackedButton(props: ComponentProps<typeof Button>) {
return (
<Button
{...props}
tap={(...args) => {
track('button_click')
props.tap?.(...args)
}}
/>
)
}For deeper edits (changing the JSX itself), use the Download scaffold flow - it ships editable sources you can fork.
Scaffold flow
The scaffold flow hasn't changed. After clicking Download scaffold in the plugin:
npx @proofly-framer/react-export <exportId>
Extracts a ready-to-run Vite project with src/framer-core/ (generated) and src/framer/ (editable wrappers). Good for prototyping. Not ideal for integrating into an existing app.