Skip to content
EditorStackPlayground

How to embed a page builder in a React application

Four viable routes for putting a visual page builder inside a React app, with the measured bundle cost of each, the questions that eliminate two of them immediately, and what nobody tells you about the work after integration.

Updated

TL;DR

  • For a React application there are four realistic routes: Puck (90.4 kB gzip, editor included), Craft.js (29.2 kB, build the editor yourself), GrapesJS (294.6 kB, framework-agnostic HTML canvas), or a commercial SDK.
  • Two questions eliminate most of the field: will your own customers use the editor, and must the output be portable HTML?
  • Integration is roughly 8% of the work — asset storage, persistence, permissions and the editor UI are the rest, and they are the same regardless of which library you pick.

Start with two questions

Most of the field eliminates itself before you compare features.

Will people outside your organisation use this editor? If yes, hosted platforms (Builder.io, Plasmic) are structurally wrong: their accounts and branding are the vendor's, and reselling the editing experience is not what they are for.

Must the output be portable HTML? If pages must render in an email, on a customer's own hosting, or in a system you do not control, a React component tree is the wrong storage format and GrapesJS becomes the candidate despite being the heaviest.

The four routes, with measured costs

| Route | Bundle (min+gzip) | Editor UI included | Output | |---|---|---|---| | Puck | 90.4 kB | Yes | Typed JSON of your components | | Craft.js | 29.2 kB | No | JSON tree of your components | | GrapesJS | 294.6 kB | Basic, needs replacing | HTML and CSS | | Commercial SDK | Vendor-hosted | Yes | Vendor format or HTML |

Bundle figures are from our own benchmark, with React external for the React-only libraries.

The recommended default: Puck

For a React product with a design system, Puck is the shortest route to something a customer can use. You describe each component's editable fields once, and the editor is generated from that description.

const config = {
  components: {
    Hero: {
      fields: { title: { type: 'text' }, cta: { type: 'text' } },
      defaultProps: { title: 'Welcome', cta: 'Get started' },
      render: ({ title, cta }) => <HeroSection title={title} cta={cta} />,
    },
  },
};

render is your production component. That single line is why there is no drift between what the editor shows and what users see, and why there is no export step to maintain.

In Next.js App Router, the pattern is an editor route that is a client component, and a public route that server-renders the same data through Puck's Render. Page data lives in your database.

When to choose the others

Craft.js when the editor interface has to look like your product rather than like an editor. You get the drag-and-drop node tree and write everything visible yourself — see Puck vs Craft.js for the honest cost of that choice.

GrapesJS when the editor must run outside React, when users need real style control, or when the output must be HTML — a white-label builder resold to agencies is the classic case. GrapesJS vs Puck covers the trade, and GrapesJS in React has a tested component for mounting it.

A commercial SDK when the timeline is the constraint and the editor is a feature rather than a differentiator.

The work nobody puts in the estimate

Integration is the small part. What follows it is the same regardless of library:

  • Asset management — upload, storage, thumbnails, a picker, quotas. Around 80 hours.
  • Persistence and versioning — autosave, drafts, publish state, recovery. Around 60 hours.
  • Multi-tenant permissions — who may edit which page, sharing, roles. Around 60 hours.
  • A block library that matches your product — around 100 hours, and the thing users judge you on.
  • The editor UI, if you chose Craft.js or GrapesJS — around 120 hours.

Our build-versus-buy calculator totals these at roughly 520 hours and lets you uncheck what you already have.

A realistic sequence

  1. Write down who edits and what the output must be. Those two answers pick the library.
  2. Build a spike with three real components from your design system, not a demo hero block.
  3. Put it in front of one real user before building anything else. Editor projects fail on interaction assumptions far more often than on technology.
  4. Then build persistence, then assets, then permissions — in that order, because each one is harder to retrofit than the last.

Frequently asked questions

What is the best page builder library for React?
Puck for most teams: it renders your own React components, ships an editor interface, and stores typed JSON. Craft.js if the editor UI must be entirely yours, and GrapesJS if the editor must also work outside React or emit standalone HTML.
How do I add a visual editor to Next.js?
Load the editor in a client component with a dynamic import and SSR disabled, keep the public page server-rendered, and store the page data in your own database. Puck's renderer works in server components, which is why it is the smoothest Next.js path.
How long does it take to embed a page builder?
A working editor takes hours. A customer-facing feature takes months: our estimate is around 520 engineering hours including the editor UI, block library, asset management, persistence, permissions and QA.
Can I use my existing design system components in the editor?
With Puck and Craft.js, yes — that is their core model. With GrapesJS, not natively: it renders HTML in an iframe canvas, so your React components would need wrapping rather than rendering.

Written by the EditorStack Research Team. How we test and what we refuse to publish is on the methodology page.