Bundlers

Next.js

Next.js builds with webpack, so the motif extractor wires in through next.config — the same @usemotif/compiler-swc package, called via its webpack entry. Pair it with the streaming style registry so server-rendered pages arrive with their CSS already in place.

Updated todayEdit on GitHubWeb & native

Install

example.tsx
yarn add -D @usemotif/compiler-swc

Add the plugin

next.config accepts a webpack function that receives the config before each compile. Push the plugin's webpack instance onto config.plugins.

next.config.ts
import type { NextConfig } from 'next';
import motif from '@usemotif/compiler-swc';
 
const nextConfig: NextConfig = {
transpilePackages: ['@usemotif/react', '@usemotif/tokens'],
webpack(config) {
  config.plugins.push(motif.webpack());
  return config;
},
};
 
export default nextConfig;

The plugin enforces a pre stage, so motif extraction runs ahead of Next's own SWC compile — motif rewrites the JSX, then SWC compiles what is left. The webpack hook fires for both the server and client compilations; the plugin is safe in both.

Transpile the motif packages

transpilePackages tells Next to run the motif packages through its own compile step. The motif packages ship 'use client'-marked modules — @usemotif/react (Pressable, Link, and the motion primitives) and everything built on it — and Next's App Router has to see those modules through its compiler to wire the client boundary correctly.

List every motif package the app imports from. For a typical web app that is @usemotif/react and @usemotif/tokens; add @usemotif/headless and @usemotif/icons to the array if you use them. (Native packages such as @usemotif/react-native never reach a Next build.)

Ship the extracted CSS

Import the virtual stylesheet once from the root layout. Next treats it like any other CSS import and includes it in every route's <head>.

app/layout.tsx
import 'virtual:motif-extract.css';
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
  <html lang="en">
    <body>{children}</body>
  </html>
);
}

Pair it with the style registry

Extraction covers the static styles. Anything that resolves at render time — dynamic prop bags, runtime theme switches — still emits CSS through the runtime, and on the server that CSS has to be collected per request and flushed into the stream.

That is the job of @usemotif/react/server and the App Router registry component. The setup is the same whether or not the compiler is wired in:

app/layout.tsx
import '@usemotif/react/server';

Turbopack

next dev --turbo does not run webpack, so the extractor does not fire under Turbopack dev. This is not a fault — pages still render correctly through the runtime path. The production next build uses webpack, so extraction lands in the deployed output. Develop on Turbopack if you prefer; ship with extraction either way.