Skip to content

Integrate an existing Next.js project

FrameKit can be added to an existing Next.js App Router application without replacing the rest of the project.

  • Node.js >=22.13.0.
  • pnpm >=11.14.0 when using pnpm.
  • Next.js >=16 <17.
  • React and React DOM >=19 <20.
  1. Install the package.

    Terminal window
    pnpm add @mauriciodmo/framekit
  2. Wrap the Next.js configuration.

    next.config.ts
    import { withFrameKit } from '@mauriciodmo/framekit/next'
    export default withFrameKit()

    Pass your existing Next.js options to withFrameKit({...}) when needed. FrameKit owns output: 'standalone', distDir: '.framekit/next', and the temporary / to /editor redirect.

  3. Add the generated alias and FrameKit styles.

    tsconfig.json
    {
    "compilerOptions": {
    "paths": {
    "@/*": ["./src/*"],
    "@framekit/generated/*": ["./src/generated/framekit/*"]
    }
    }
    }
    src/app/globals.css
    @import "tailwindcss";
    @import "@mauriciodmo/framekit/styles.css";

    Keep the Tailwind import only when the project uses Tailwind.

  4. Wrap the root layout.

    src/app/layout.tsx
    import { FrameKitStudioRoot } from '@mauriciodmo/framekit/studio/root'
    import './globals.css'
    export default function RootLayout({ children }: { children: React.ReactNode }) {
    return <FrameKitStudioRoot>{children}</FrameKitStudioRoot>
    }

    The root layout must remain a server component. Do not add another <html>, <head>, or <body> around FrameKitStudioRoot.

  5. Add the FrameKit routes.

    src/app/[section]/[[...slug]]/page.tsx
    import { createStudioPage } from '@mauriciodmo/framekit/studio/root'
    import { StudioClient } from '@framekit/generated/studio-client'
    export const runtime = 'nodejs'
    export const dynamic = 'force-dynamic'
    export default createStudioPage(StudioClient)
    src/app/login/page.tsx
    import { createLoginPage } from '@mauriciodmo/framekit/studio/root'
    export const runtime = 'nodejs'
    export const dynamic = 'force-dynamic'
    export default createLoginPage()
    src/app/api/framekit/[...action]/route.ts
    import { createFrameKitApiHandler } from '@mauriciodmo/framekit/server'
    import { templates } from '@framekit/generated/templates'
    export const runtime = 'nodejs'
    export const dynamic = 'force-dynamic'
    const handler = createFrameKitApiHandler(templates)
    export const GET = handler
    export const POST = handler
    export const PATCH = handler
    export const DELETE = handler
    src/app/framekit/render/[id]/page.tsx
    import type { Metadata } from 'next'
    import { createRenderPage } from '@mauriciodmo/framekit/server'
    import { RenderClient } from '@framekit/generated/render-client'
    export const runtime = 'nodejs'
    export const dynamic = 'force-dynamic'
    export const revalidate = 0
    export const fetchCache = 'force-no-store'
    export const metadata: Metadata = {
    robots: { index: false, follow: false },
    }
    export default createRenderPage(RenderClient)
  6. Generate the registry and start development.

    Terminal window
    pnpm framekit generate
    pnpm framekit dev

FrameKit writes src/generated/framekit/templates.ts, brands.ts, studio-client.tsx, and render-client.tsx. Treat them as generated output.

The generated routes support both authentication modes. With FRAMEKIT_AUTH_ENABLED missing or false, /editor and /brand are usable without a session, /login redirects to /editor, and /settings plus the access API are unavailable. Set FRAMEKIT_AUTH_ENABLED=true to enable users, sessions, API tokens, and protected Studio/access routes.

Before exposing the application to an untrusted network, explicitly set FRAMEKIT_AUTH_ENABLED=true. See Configuration for the strict value and bootstrap contracts.

Next, create your first template and review Project structure. For command behavior and generated-file details, use the CLI and generated-files pages under Reference.