Build a more complete visual editing experience with GrapesJS. Puck is a strong React-first editor for composing your own components. If your product is growing into a full page builder, website editor, email builder or customer-facing visual editor, GrapesJS gives you a broader editor foundation to integrate and extend.
GrapesJS and GJS.Market figures, verified 2026-09-03. They describe the project this page recommends, not a score against Puck — a star count is not evidence that one editor suits your product better than the other.
The short answer
Is Puck still the right fit?
Both are open-source editors you can self-host and put in front of your users. They start from different architectural directions, so the real question is not which is better — it is whether you are building a React component editor or a full visual editing experience.
Stay with Puck if
Your editor is a React component editor, and that is what it should stay.
This describes your product
Your application is deeply React-centric.
Your editor revolves around your own React components.
You want a React-native component configuration experience.
You want to control most of the editor UX yourself.
Your content model maps naturally to React components.
Nothing on this page is a reason to migrate. Puck is well documented, actively developed and MIT-licensed.
These are concrete product signals, not a claim about what most teams do. If several of them describe your roadmap, your editor has outgrown a component configurator.
Your editor is becoming more than a component configurator
Users have started asking for visual page composition, reusable blocks, responsive controls, asset workflows, templates, style controls, layers and multiple pages — editor features rather than more components.
Your product needs a document-oriented editor
Instead of a React component with props serialised to JSON, you need a page made of sections, components, styles, assets and layout — a document your users edit rather than a config they fill in.
Your editor needs to support more than React
If the same editor has to be reused across different application environments, or embedded somewhere React is not the host, framework independence stops being theoretical.
Users want to control styling, not just content
A visual style layer is a large subsystem. When "let users pick the spacing" turns into a roadmap item, an editor that already has a Style Manager saves a project.
You need HTML and CSS as an output, not only React
Exports, static publishing, third-party embeds and email all want portable markup. Rendering exclusively through React components makes those harder than they need to be.
Email templates appeared on the roadmap
Email is a different rendering target with its own constraints. It is not what Puck is documented for, and it is a workflow the GrapesJS ecosystem already covers.
The editor is now a feature you sell
Once the editor is part of what customers pay for, the cost of building and maintaining editor infrastructure yourself becomes a product decision rather than an implementation detail.
The honest case
When you should stay with Puck
You do not need to migrate simply because GrapesJS exists. Puck is a well-documented, MIT-licensed, actively developed editor, and for a whole class of products it is the better fit.
Your product is entirely React
Puck runs inside your React tree, so your components, context, hooks and design system are available in the editor without an integration layer.
Your content model is React components
If what users edit is a component tree with typed props, Puck expresses that directly. A visual document model would be an extra translation step.
Your editor is relatively focused
A configurator with a fixed component set does not need a Style Manager, an Asset Manager or a Layer Manager. Unused subsystems are still surface area to hide.
You want to own the editor UI
Puck documents thirteen override slots plus composition, so teams that intend to design the whole editing experience have a clear path.
You need tight React integration
Opt-in React Server Component support, dynamic props, resolvers and external data sources are all documented, React-native concerns.
You do not need an HTML/CSS editing model
If nothing in your roadmap requires editing markup or styles visually, the broader editor foundation is capability you would carry without using.
If those describe your product, staying on Puck is the right call — and this page has done its job.
Puck is designed around editing and composing React components. GrapesJS is designed around visual document editing, and provides a broader set of editor subsystems to do it with.
Neither model can be described as missing capabilities the other has: anything GrapesJS ships as a module can be implemented on top of Puck, and anything Puck does natively with React can be integrated into GrapesJS. The difference is the starting point.
What the starting point changes is how much editor infrastructure your team has to assemble before the product looks finished — which is the question the next two sections answer concretely.
Neither architecture is universally superior. They optimise for different things, and the right one is the one that matches what your users are actually editing.
Build vs adopt
How much editor infrastructure does your team need?
The real decision is rarely "Puck or GrapesJS". It is how much editor infrastructure your team should own and implement. This table reads each capability from each project's own documentation: "core" means a documented module, "configurable" means the project supports it through configuration or overrides, and "custom implementation" means your team writes it. None of these cells means "impossible".
Capability
Puck
GrapesJS
React component editing
Core strength
Integration — custom component types or the React wrapper
Visual canvas
Available — iframe preview
Core
Blocks
Components and configuration
Core — Block Manager
Style system
Custom and configurable
Core — Style Manager
Layers and outline
Available and customizable
Core — Layer Manager
Assets
Custom implementation or integration
Core — Asset Manager
Responsive editing
Viewports and configuration
Core — Device Manager
Commands
Custom, in your application
Core — Commands
Storage
Application responsibility
Core — Storage Manager, plus your integration
Project data
JSON of component props
Project data — structure, style, assets and pages
HTML and CSS output
Not the primary model
Core use case
Custom editor UI
Highly customizable
Highly customizable
Plugins
Plugin API
Plugin API and marketplace ecosystem
Email workflows
Not a documented focus
Available through the ecosystem
Verified 2026-09-03 against puckeditor.com/docs and grapesjs.com/docs. A capability marked "custom implementation" for one project is not a flaw — it is a design decision about what belongs in the library and what belongs in your application.
These are documented modules of the GrapesJS core, and they are what "a broader editor foundation" concretely means for a visual website builder, SaaS page builder, CMS editor, email builder or white-label editor.
▣
Visual canvas
A complete visual editing environment rendering a live document, not a preview of a component tree.
◈
Components
Define editable component types with their own model, traits, and behaviour on the canvas.
▤
Blocks
Register reusable drag-and-drop blocks that users compose pages from.
◐
Style Manager
Visual controls for typography, spacing, colour, dimensions and more, scoped by selector.
◇
Asset Manager
Browse, upload and reuse images and other media from inside the editor.
▭
Device Manager
Define viewports and let users edit across responsive breakpoints.
⛁
Storage
Connect editor data to your own backend, with local or remote storage and autosave.
⌘
Commands
Extend and script editor behaviour, and bind it to your own UI.
⬡
Plugins
Add functionality without modifying the core editor — the extension point the ecosystem is built on.
⟨⟩
HTML / CSS
Export portable markup and styles you can render anywhere you control.
✉
Email
Extend the same editor for HTML email and MJML workflows through ecosystem plugins.
Feature matrix
Puck vs GrapesJS
Capability by capability, in each project's own vocabulary. Both projects move, so this reflects what their documentation covers as of the verification date below. Cells avoid a bare yes/no wherever the honest answer is "supported, but you configure or implement it".
Capability
GrapesJS
Puck
Architecture
Visual document editor with its own component tree
React component tree, edited as typed props
License
BSD-3-Clause core, MIT React wrapper
MIT — @puckeditor/core 0.23.0
Open source
Yes
Yes
React dependency
None in the core; official React wrapper available
Required — React is the runtime
Framework flexibility
Framework-agnostic core
React-focused by design
Visual canvas
Core — a live document in an iframe
Built in — same-origin iframe preview
Components
Component types with a model, view and traits
Core strength — your own React components
Blocks
Core — Block Manager
Component drawer; slot fields for nesting
Layers / outline
Core — Layer Manager
Built in — outline region, replaceable via overrides
Style management
Core — Style Manager with visual CSS controls
Your own CSS and design system; the Theming API styles the editor UI
Assets and media
Core — Asset Manager with pluggable sources
Custom implementation — supply a field UI or an external source
Device preview
Core — Device Manager
Built in — Viewports
Responsive editing
Visual breakpoint editing through the Style Manager
Viewport switching; responsive rules live in your own CSS
Commands
Core — Commands
Application responsibility — dispatch and actions
Undo and redo
Core — UndoManager
Built in — documented history API
Rich text editing
Built-in RTE, extendable
Built in — richtext field and rich-text menu components
Custom components
Component API — addType()
Core — any React component plus a ComponentConfig
Custom editor UI
Highly customizable — panels, custom views, full UI replacement
Highly customizable — thirteen override slots plus composition
Templates
Plugin — templates manager listings
Application responsibility — store and reload saved data
Storage
Core — Storage Manager, local or your backend
Application responsibility — you persist the data
Project data
Components, styles, assets, pages and editor state
JSON of component props, under content and root
HTML and CSS output
Core use case — exports portable HTML and CSS
Not the primary model — output is rendered React
React rendering
Integration — mount React, or render exported markup
Core — a Render component replays the saved data
React Server Components
Client-side editor — check your integration requirements
Opt-in support, documented
Email workflows
Available through the plugin ecosystem
Not a documented use case
MJML
Plugin — MJML presets and export
Not applicable
Plugins
Plugin API and a public marketplace
Plugin API and UI overrides
AI assistance
Not in the core — custom integration
Documented AI plugin and cloud client
Self-hosting
Yes — you run the editor
Yes — you run the editor
White-label
Replaceable UI, panels and branding
Theming API and UI overrides
SaaS embedding
Embed the editor inside your product
Embed the editor inside your React product
Custom backend and database
Storage Manager talks to your own API
Application responsibility — you own the transport
Permissions
Application responsibility — gate the commands you expose
Built in — permissions API and feature toggling
Publishing
Application responsibility
Application responsibility
Plugin marketplace
GJS.Market — 100+ plugins
Community plugin list
Verified 2026-09-03 against each project's official documentation. "Core" means a documented module of the library; "via configuration" and "custom implementation" mean the capability is reachable but your team assembles it. No cell here means a project cannot do something.
Then both are viable. Puck is the stronger fit when React is the core application architecture, components are the content model, the editor should manipulate component props, and your design system is already deeply integrated with React. GrapesJS is the stronger fit when React is one integration layer rather than the whole editor architecture — when you also need HTML and CSS visual editing, want to reuse the editor across different frontend environments, or need the broader editor subsystems.
Next.js
↓
React
↓
GrapesJS
↓
Your Components
↓
Your Backend
npm install grapesjs @grapesjs/react
Mount the editortsx
import { useRef } from 'react';
import grapesjs from 'grapesjs';
import GjsEditor from '@grapesjs/react';
import 'grapesjs/dist/css/grapes.min.css';
// GrapesJS runs on the client: it owns an iframe canvas and a live document.
// In Next.js, mount it from a client component.
export default function Editor() {
return (
<GjsEditor
grapesjs={grapesjs}
options={{
height: '100vh',
storageManager: { type: 'remote', autosave: true },
}}
onEditor={(editor) => {
// Register the component types you mapped from your Puck config here.
}}
/>
);
}
Your components stay yours. The editor sits between them and the document your users are building, and saves through to your own backend.
One product shape per row, one verdict. Three of these go to Puck outright, and one is genuinely a tie — if every row pointed the same way, the table would not be worth reading.
What you are building
Better starting point
A React component configurator
Puck
An editor for your React design system
Puck
A highly custom, React-native editing experience
Puck
A marketing page builder
GrapesJS
A page builder inside your SaaS product
GrapesJS
A customer-facing website builder
GrapesJS
An email builder
GrapesJS
A framework-independent visual editor
GrapesJS
A visual editing surface for a headless CMS
Either
If you cannot yet say which row describes your product, choosing an editor is premature. Write down the three things your users must be able to change, and the answer usually resolves itself.
SaaS
Building a visual editor into your SaaS?
This is the section that stops the rest of the page overpromising. GrapesJS provides the editing layer. Your SaaS still owns authentication, authorization, persistence, billing, publishing and business logic — and that is the larger half of the project.
Your SaaS owns
8 responsibilities
Everything that makes it a product rather than an editor.
Authentication and sessions
Organizations and team membership
Roles and permissions
Billing, plans and entitlements
Your database and data model
Publishing and hosting of what users build
Versioning, drafts and rollback
Audit trails and support tooling
GrapesJS provides
5 responsibilities
The editing layer, as documented modules you configure.
The canvas and component tree
Blocks, layers, styles and assets
Responsive editing and device preview
Commands, undo and redo
Project data in, project data out
You still build
6 responsibilities
The integration between the two — the real project.
This is the part Puck gets right by default, and the part a GrapesJS integration has to be deliberate about. Your users should work with the components and blocks that make sense for your product, not with generic page-builder primitives.
Marketing sections
The sections a landing page is actually made of.
Blocks in the panel
Hero
Pricing
CTA
Testimonials
Product surfaces
Reusable chrome and interactive pieces.
Blocks in the panel
Product Card
Navigation
Forms
Footer
Commerce blocks
Storefront-specific components with their own data.
Blocks in the panel
Collection Grid
Cart Summary
Checkout Steps
Badges
In GrapesJS these are component types registered with addType() and exposed through the Block Manager, with traits for the props a user may change. Constraining the palette to your own system is what keeps the output on-brand without policing it afterwards.
If your roadmap includes newsletters, CRM templates, marketing automation, transactional templates or a customer-facing email builder, the same editor core can be extended with email and MJML tooling. Email rendering is its own discipline: no editor guarantees universal client compatibility, and the final templates still have to be tested in real clients.
Your SaaS↓GrapesJS↓
Web Page Builder
Email BuilderThe email branch continues:↓MJML↓Email HTML
The GrapesJS project's own demo — the free baseline, with the full default panel set.
grapesjs.com/demo.htmlFree
grapesjs.com/demo.html
Blocks
Styles
Loads an external demo in an iframe
Ecosystem
Extend your GrapesJS editor
Grouped by what you are building. Every card below is a real listing — name, price and thumbnail come straight from the catalogue, so nothing here can advertise a plugin that does not exist.
React and SaaS
React UI layers and editor shells for teams putting a builder inside a product.
Puck and GrapesJS use different content and editor models, so a migration is a data-model transformation rather than a package replacement. Everything below describes that transformation.
Puck
Your config, plus the props of each placed component.
Configuration
Component Props
JSON Data
GrapesJS
A project document covering structure, style, media and editor state.
Components
Styles
Assets
Pages
Editor State
Storage
Existing content models and editor configuration have to be mapped, not ported. The next two sections show the mapping and the roadmap.
Mapping
From Puck components to GrapesJS components
Each side has its own vocabulary for the same idea: a thing users can place, and the parts of it they can edit. A migration is the transform between the two.
Puck
Component
Props
Fields
Render
Migration layer
A transform you write once per component type. There is no automatic converter — this is the work.
GrapesJS
Component
Traits
Attributes
Blocks
Commands
Storage
What has to be mapped
Components
Each Puck component type becomes a GrapesJS component type.
Editable fields
Puck fields become traits, attributes or editable child components.
Props and defaults
defaultProps map onto the component model's defaults.
Validation
Field constraints move into trait definitions or your own checks.
Rendering
A React render function becomes markup the canvas can host.
Blocks
What was implicit in the config becomes an explicit block registration.
Stored content
Existing Puck JSON has to be transformed into project data.
Editor UI
Panels, fields and overrides are reconfigured, not ported.
Migration effort depends on the number of components, your existing content schema, any custom editor behaviour and your integrations. A handful of simple components is a very different job from a large library with bespoke field UIs.
Example
Example: migrating a hero component
A conceptual before-and-after, simplified to show the shape of the mapping. Treat the exact field-to-trait correspondence as illustrative rather than as a universal automatic conversion.
Puck: config + renderjsx
// Puck: a component is configuration + a React render function.
// Field types are documented at puckeditor.com/docs/api-reference/fields
const config = {
components: {
Hero: {
fields: {
title: { type: 'text' },
description: { type: 'textarea' },
image: { type: 'text' },
},
defaultProps: {
title: 'Ship faster',
description: 'The visual editor your team already knows.',
image: '/hero.png',
},
render: ({ title, description, image }) => (
<section className="hero">
<img src={image} alt="" />
<h1>{title}</h1>
<p>{description}</p>
</section>
),
},
},
};
GrapesJS: component type + blockjs
// GrapesJS: a component type owns its markup, its editable traits and how it
// is exposed to the canvas. Traits are the closest analogue to Puck fields.
editor.Components.addType('hero', {
model: {
defaults: {
tagName: 'section',
attributes: { class: 'hero' },
traits: [
{ name: 'title', type: 'text', changeProp: true },
{ name: 'description', type: 'text', changeProp: true },
{ name: 'image', type: 'text', changeProp: true },
],
components: [
{ type: 'image' },
{ tagName: 'h1', type: 'text', content: 'Ship faster' },
{ tagName: 'p', type: 'text', content: 'The visual editor…' },
],
},
},
});
// A block is what makes the type draggable from the panel. Puck derives this
// from the config; in GrapesJS it is a separate, explicit registration.
editor.Blocks.add('hero-block', {
label: 'Hero',
category: 'Sections',
content: { type: 'hero' },
});
Migrating content you already have
Config is only half of it. Anything your users already saved is Puck JSON, and it has to be walked and transformed into components your new types understand.
Migrating content you already havejs
// Existing Puck content is a JSON tree of { type, props } nodes. Migrating it
// means walking that tree and emitting the GrapesJS component definitions your
// new types understand — a transform you write once, per component type.
function puckNodeToGjs(node) {
const map = {
Hero: ({ title, description, image }) => ({
type: 'hero',
title,
description,
image,
}),
// …one entry per component type in your Puck config
};
const toGjs = map[node.type];
if (!toGjs) throw new Error(`Unmapped Puck component: ${node.type}`);
return toGjs(node.props);
}
// Puck stores content under `data.content`; `data.root` holds page-level props.
const components = puckData.content.map(puckNodeToGjs);
editor.setComponents(components);
Conceptual example. Field types, trait definitions and the exact component model will depend on your own components.
Roadmap
A practical Puck to GrapesJS migration
1
Step 1
Inventory
List what exists: Puck components, their fields, your content types, the saved JSON, the renderer and the publishing flow. Most surprises in a migration are in this list.
2
Step 2
Map components
Decide the correspondence before writing code: Puck component to GrapesJS component type, Puck field to trait, attribute or custom UI, Puck layout to component structure, Puck data to project data.
3
Step 3
Rebuild the editor UI
Recreate only the interface your users actually use. A migration is the cheapest moment to drop the panels nobody opened.
4
Step 4
Migrate existing content
Walk the stored Puck tree and emit the component definitions your new types understand. Keep the transform in version control — you will run it more than once.
5
Step 5
Run both in parallel
Where the risk is high, keep the old editor rendering old content while the new one takes new content. Dual rendering buys you the ability to stop.
6
Step 6
Validate
Compare visual output, responsive behaviour, publishing, saved data and the workflows your users actually perform — not just that the editor loads.
7
Step 7
Cut over
Move users across once the comparison is clean, with the old path still reachable until the new one has been through a full usage cycle.
No gate
The migration guide is this page
Everything above is the guide — no email required, nothing gated, no promised timeline. Migration effort depends on how many components you have, how much custom editor behaviour you built and how much content already exists, so we will not quote a duration we cannot stand behind.
⇄
Concept mapping
Puck config, fields, props and render, matched to GrapesJS component types, traits, blocks and storage.
☑
Component checklist
The eight things that have to be mapped per component type, listed above.
⛁
Data-model checklist
What Puck persists versus what a GrapesJS project holds, and where each piece lands.
⚛
React and Next.js setup
How the editor mounts inside a React app, and what that means in Next.js.
◐
Style and asset setup
Which subsystems to configure first so the editor feels finished rather than raw.
⇥
Rollout and QA
Migrate one surface at a time, keep originals, and diff rendered output against the source.
We can help map your existing Puck components and content model to a production-ready GrapesJS implementation. Scope and schedule are agreed after the architecture review — we do not quote timelines before seeing the codebase.
1
1
Architecture review
We read your Puck configuration, content model and editor customisations, and write down what actually has to move.
2
2
Component mapping
Each Puck component becomes a specified GrapesJS component type with its traits, block and constraints.
3
3
Data migration
A transform for your stored content, run against your real data rather than a sample.
4
4
Custom editor UI
The panels, chrome and interactions your users need — built to match your product, not the default demo.
5
5
Plugins and extensions
Marketplace plugins where they fit, custom plugins where they do not.
6
6
Backend integration
Storage, assets, permissions and publishing wired into your own API and database.
7
7
Testing and deployment
Output comparison, responsive checks and a cutover plan with a way back.
There is no single best alternative — it depends on what your editor is for. GrapesJS is the strongest option when you need a broader visual editor foundation with a canvas, blocks, styles, layers, assets and responsive editing built in. Craft.js is closer to Puck in spirit as a React-first framework. If your editor really is a React component configurator, the best alternative may be staying on Puck.
Is GrapesJS an alternative to Puck?
Yes, for a specific kind of product. Both let you build an in-app visual editor and both are open source and self-hosted. They differ in starting point: Puck edits a React component tree, GrapesJS edits a visual document. GrapesJS is a genuine alternative when you need the visual document model; it is a worse fit when React components are the content model.
What is the difference between Puck and GrapesJS?
Puck is a React-first editor built around composing and configuring your own React components: its data is JSON describing component types and props, and rendering happens through React. GrapesJS is a broader visual editor foundation built around a visual document, with documented modules for components, blocks, styles, layers, assets, devices, commands and storage, and HTML and CSS as first-class output.
Is Puck React-only?
Puck runs inside React — React is the runtime for both the editor and the rendered output. Its data is plain JSON, so another system could read it, but the editing and rendering experience is React-native by design. That is a strength for React products and a constraint if the same editor has to run somewhere React is not the host.
Can GrapesJS work with React?
Yes. GrapesJS ships an official React wrapper, @grapesjs/react, and the core editor is framework-agnostic, so it mounts inside a React or Next.js application like any other client-side component. See the GrapesJS React integration guide for the mounting patterns.
Can GrapesJS use React components?
You can integrate React components into a GrapesJS editor, but not in the way Puck does. GrapesJS component types own their markup in the canvas document, so a React component is typically mirrored as a GrapesJS type with matching traits, or rendered into the canvas through a custom view. It is an integration layer rather than the native model.
Can I use GrapesJS with Next.js?
Yes. GrapesJS is a client-side editor that owns an iframe canvas, so it has to be mounted from a client component. In the Pages Router that usually means a dynamic import with SSR disabled; in the App Router a client component is enough.
Can Puck edit HTML and CSS?
Not as its primary model. Puck edits component props, and the markup and styling come from the React components you wrote. You can of course build a component that accepts raw markup or class names, but there is no documented visual HTML or CSS editing surface the way GrapesJS provides a Style Manager and an editable document.
Is GrapesJS suitable for SaaS products?
Yes — it is designed to be embedded, and it is used as the editing layer inside SaaS products. It provides the editor, not the product: authentication, organizations, permissions, billing, persistence and publishing remain yours to build.
Can I build a page builder with GrapesJS?
Yes. That is the core use case: a canvas, a block palette, style controls, layers, assets, responsive devices and HTML and CSS output. What you add is your own block library, editor UI and storage.
Can I build a white-label editor with GrapesJS?
Yes. The editor UI is replaceable — panels, buttons and views can be swapped or rebuilt, and there is no vendor branding you are required to display. Multi-tenant branding, per-tenant block sets and permissions are things your application implements on top.
Can I build an email editor with GrapesJS?
Yes, using ecosystem plugins for email blocks and MJML authoring and export. Email rendering is its own discipline: no editor can guarantee universal email-client compatibility, so templates still need testing in the clients your recipients actually use.
Can I migrate Puck content to GrapesJS?
Yes, by transforming it. Puck stores a JSON tree of component types and props; GrapesJS stores project data describing components, styles, assets and pages. Migration means walking the Puck tree and emitting the GrapesJS component definitions your new types understand — a transform you write once per component type.
Is there an automatic Puck-to-GrapesJS converter?
No. There is no automatic converter, and any page that claims one is overstating it. The two editors persist different things, so the mapping depends on your components and your content schema. What can be reused is the shape of the transform, which this page shows.
How difficult is a Puck migration?
It depends on the number of component types, how much custom editor behaviour you built, how much content already exists and how coupled your renderer is to React. We do not publish a duration, because a migration of six components with clean data and one of sixty with hand-edited JSON are not the same project.
Can I use my existing React design system with GrapesJS?
Yes, but you connect it deliberately. Typically you register a GrapesJS component type per design-system component, expose the props users may change as traits, and add each one to the Block Manager. That constraint is what keeps output on-brand.
Can I connect GrapesJS to my own database?
Yes. The Storage Manager can be configured to read and write through your own API, so project data lives in your database in whatever shape you choose. Nothing has to pass through a third-party service.
Can I self-host GrapesJS?
Yes. It is an npm package you bundle into your own application — there is no hosted service, no account and no per-seat licence. The core is BSD-3-Clause licensed and the React wrapper is MIT.
Do I need to use GJS.Market plugins?
No. GrapesJS is fully usable without any marketplace plugin, and the core modules are free and open source. Plugins exist so you can buy a capability instead of building it — an editor UI shell, email tooling, a block library — when that trade is worth it for your team.
Should I migrate from Puck to GrapesJS?
Only if your editor has outgrown the component-configurator model. If users are asking for visual styling, blocks, layers, assets, templates, responsive controls or non-React output, a broader foundation will save work. If your editor composes your React components and that is what it should keep doing, staying on Puck is the right call.
Next step
Build beyond the component editor
If Puck already fits your React component model, there may be no reason to switch. But if your editor is becoming a full visual product, GrapesJS gives you a broader foundation to build on, customise and extend.
Developers
Try GrapesJS
Open a live editor, then read the docs and build. Nothing to install to start looking.