PageKit β€” the self-hosted GrapesJS site builder, sold as source. Get early access

Craft.js alternative

Craft.js Alternative: Build a Production Visual Editor With GrapesJS

Compare Craft.js and GrapesJS, understand the architectural differences, explore a live visual editor, and learn how to migrate a Craft.js-based editor to GrapesJS.

Visual drag-and-drop editorCustom componentsBlocksStyle ManagerAsset ManagerStoragePlugin ecosystem
Craft.js

You own everything around the node tree.

  1. React Application
  2. Craft.js
  3. Your Editor Interface
GrapesJS

The editing subsystems arrive assembled.

  1. Your Application
  2. GrapesJS
    • Canvas
    • Blocks
    • Style Manager
    • Storage
  3. Publishing

Current releases

PackageVersionLicenseLatest releaseGitHub starsnpm downloads
@craftjs/core0.2.12MIT2025-02-148,738267k/moSource
grapesjs0.23.6BSD-3-Clause2026-08-2526,1881.4M/moSource

Read from the npm registry and the GitHub API on 2026-09-03. Star counts and download figures are ecosystem signals, not a measure of which project suits your product. Both repositories are actively published and neither is archived.

The short answer

Is GrapesJS a Good Craft.js Alternative?

GrapesJS and Craft.js solve related but different problems. Craft.js is a React-focused framework for building customizable page editors, while GrapesJS provides a broader visual editor foundation with components, blocks, styling, assets, storage and plugins.

GrapesJS can be a strong alternative when you want more editor infrastructure out of the box, especially for HTML/CSS-based visual editors, SaaS page builders, CMS editing surfaces and embeddable builders.

It is not universally better. If your product is deeply React-centric and the editor has to operate on a React component tree, Craft.js is the more direct fit β€” and the sections below say so in detail rather than as a disclaimer.

Side by side

Craft.js vs GrapesJS in 30 Seconds

No scores, because the rows are not comparable quantities. Each capability is labelled with where it comes from: included in the project, reachable through an add-on, or defined by your own code.

  • Built-in
  • Add-on
  • Custom
CapabilityCraft.jsGrapesJS
Primary focusA React framework for building your own page editors.A visual editor framework with the editing surface already assembled.
React-firstBuilt-inYes. Components are React components; the tree is a React tree.Add-onNo. The core is framework-agnostic; React arrives through @grapesjs/react.
Visual canvasBuilt-inYour components render live and are directly selectable.Built-inAn isolated canvas with direct selection and inline text editing.
Custom componentsBuilt-inAny React component, described by a static Craft.js descriptor.Built-inAny component type, described with a model, traits and defaults.
Drag and dropBuilt-inIncluded. Connectors make an element draggable and droppable.Built-inIncluded. Components move between containers on the canvas.
Drag-and-drop paletteCustomYou build the toolbox that lists what can be dragged in.Built-inIncluded. Blocks register with the Block Manager and appear in a panel.
Style managementCustomApplication-defined. Styling is whatever your components already do.Built-inIncluded. The Style Manager edits CSS per selector and per device.
Asset managementCustomApplication-defined. You supply your own media picker.Built-inIncluded. The Asset Manager handles uploads and a media library.
SerializationBuilt-inIncluded. The node tree serializes to JSON and loads back.Built-inIncluded. Project data serializes to JSON and loads back.
Storage layerCustomApplication-defined. You decide where the serialized JSON goes.Built-inIncluded. The Storage Manager persists locally or to your endpoint.
Undo and redoBuilt-inIncluded. An undo and redo history is part of the core API.Built-inIncluded. The Undo Manager, with commands you can bind to a panel.
Layer tree panelAdd-onAn official add-on package renders the tree.Built-inIncluded. The Layer Manager panel comes with the core.
Plugin architectureCustomNo plugin system. You compose your own packages and the community's.Built-inIncluded. A plugin is a function that receives the Editor and extends it.
Framework approachReact-focused by design.Framework-agnostic core, integrated per framework.
HTML and CSS workflowCustomApplication-defined. You render React and produce markup yourself.Built-inNative. Clean HTML and CSS are the primary output.
SaaS page buildersPossible. You build the surrounding editing surface.Strong fit. Most of that surface is already there.
White-label editorsPossible. The interface is yours from the first commit.Strong fit. Panels, icons, labels and translations are all replaceable.

Checked against both projects' own documentation on 2026-09-03: Craft.js 0.2.12 and GrapesJS 0.23.6. "Custom" is a description, not a criticism β€” for several rows it is exactly the reason a team chooses an unopinionated framework.

See what that means architecturally
Architecture

The Architectural Difference

The biggest difference is not simply the number of features. The two frameworks give developers different starting points for building a visual editor.

Craft.js

A linear chain. Craft.js owns the node tree; every other layer is yours.

  1. React Application
  2. Craft.js
  3. React Component Tree
  4. Your Editor Interface
  5. Your Styling System
  6. Your Storage
  7. Your Publishing
GrapesJS

A chain with subsystems. The engine arrives with its own editing modules.

  1. Your Application
  2. GrapesJS
    • Canvas
    • Components
    • Blocks
    • Style Manager
    • Asset Manager
    • Commands
    • Storage
    • Plugins
  3. Your Backend / CMS
  4. Publishing
  • Provided by the framework
  • Provided by you

Craft.js starts lower. It gives you a node tree, drag-and-drop connectors, serialization and history, and it deliberately takes no position on styling, assets, storage or the panels around the canvas. That is a design decision, and for a team that wants to own its whole editing experience it is the right one.

GrapesJS starts higher. The canvas, the Blocks panel, the Style Manager, the Asset Manager, the Layer Manager, commands and the Storage Manager are modules of the core, and a plugin API exists to replace or extend any of them.

Neither framework is a platform. Neither one supplies hosting, accounts, permissions, billing, multi-tenancy or a publishing pipeline. Those sit outside both boxes and remain your responsibility either way.

So the question is not which project has more features. It is which starting point leaves you building the parts you actually want to own.

If the layers you would have to build sit above Craft.js in that first column, GrapesJS is worth evaluating. If they sit below it, migrating buys you very little.

The honest case

When Craft.js May Be the Better Choice

Craft.js is a well-designed framework with a clear purpose, and several product shapes are simply a better match for it. These are not caveats β€” they are cases where choosing GrapesJS would be the wrong call.

  • Your product is deeply React-centric

    If everything from routing to state to rendering already lives in React, an editor built from React primitives stays inside one mental model. Nothing has to cross a boundary.

  • The editor should operate on a React component tree

    Craft.js edits an actual React tree. If what your users are arranging is your React components β€” not markup β€” that correspondence is the whole value, and it is not something an HTML-first model reproduces.

  • Your team wants to build most of the interface itself

    Craft.js does not impose panels, toolbars or a settings surface. A team with strong design opinions gets a clean slate instead of something to override.

  • You need very tight control over React rendering

    Memoization, context, suspense boundaries, render scheduling: when those details matter, keeping the editable tree inside React keeps them under your control.

  • You already have a mature Craft.js implementation

    A working editor with real users and real content is an asset. The cost of replacing it is rarely justified by a feature list alone.

  • Your component system is already built around Craft.js

    If your resolver, your settings panels and your content pipeline all assume the Craft.js node model, that coupling is deep and reproducing it elsewhere is real work.

In these situations, replacing Craft.js may create unnecessary migration work.

See the full decision matrix
The other direction

When GrapesJS Is a Better Fit

The signals below are about what you would otherwise have to build. Each card collects a few of them; if several describe your project, the evaluation is worth your time.

Hands on

Try the GrapesJS Editor

Don't just compare features. Try the editor yourself β€” drag a block in, select an element, restyle it, and switch the canvas to a phone width.

  • Drag & drop
  • Blocks
  • Layers
  • Style Manager
  • Responsive devices
  • Assets
  • Undo / redo
Component models

Craft.js Components vs GrapesJS Components

Both projects call the thing a user drags around a "component", but the two definitions are not interchangeable. This is the difference that decides how much work a migration is.

Craft.js

A React component the editor drives through connectors. Its editable surface is its React props.

  1. React Component
  2. React Props
  3. Craft.js Node
GrapesJS

A definition in the editor's own document model. Its editable surface is traits, attributes and styles.

  1. Block
  2. Component Type
  3. Component Tree
  4. Attributes / Traits / Styles

How the concepts correspond

  • Craft.js ComponentGrapesJS Component Type

    A React component with a Craft.js descriptor becomes a registered component type with a model and defaults. The markup it produces moves into that model.

  • React PropsTraits / Properties / Attributes

    Props that an editor user could change become traits. Props that only your code sets become attributes or fixed model properties.

  • Craft.js Editor StateGrapesJS Project Data

    The serialized node tree becomes project data. Both are JSON, but the shapes differ, so this is a transform you write and test.

  • Custom Editor UIGrapesJS UI + Custom Commands / Panels

    Settings panels you wrote in React are replaced by the built-in trait panel, plus custom commands and panels where you need behaviour the core does not have.

This is a conceptual mapping, not an automatic converter. No tool reads a Craft.js resolver and emits GrapesJS component types β€” the correspondence above is what you implement, once per component type.

Worked example

Migrating a Component From Craft.js to GrapesJS

The same idea β€” a hero section with an editable heading and description β€” defined on each side. Read them as two definitions of one concept, not as a before and after of the same file.

Hero.jsx β€” Craft.jsjsx
// Craft.js: a component is a React component plus a `craft` descriptor.
// The editor drives it through connectors from useNode().
import { useNode } from '@craftjs/core';

export const Hero = ({ title, description }) => {
  const { connectors: { connect, drag } } = useNode();

  return (
    <section ref={(ref) => connect(drag(ref))} className="hero">
      <h1>{title}</h1>
      <p>{description}</p>
    </section>
  );
};

Hero.craft = {
  props: {
    title: 'Build faster',
    description: 'Create beautiful pages',
  },
  related: {
    // The panel that edits those props is a React component you write.
    settings: HeroSettings,
  },
};
hero-type.js β€” GrapesJSjs
// GrapesJS: a component type owns its markup and its editable traits.
// Traits are the closest analogue to Craft.js props.
editor.Components.addType('hero', {
  model: {
    defaults: {
      tagName: 'section',
      attributes: { class: 'hero' },
      traits: [
        { name: 'title', type: 'text', changeProp: true },
        { name: 'description', type: 'text', changeProp: true },
      ],
      components: [
        { tagName: 'h1', type: 'text', content: 'Build faster' },
        { tagName: 'p', type: 'text', content: 'Create beautiful pages' },
      ],
    },
  },
});

// A block is what makes the type draggable from the panel. Craft.js derives
// the equivalent from your toolbox; in GrapesJS it is a separate registration.
editor.Blocks.add('hero', {
  label: 'Hero',
  category: 'Sections',
  content: { type: 'hero' },
});

// The trait panel edits those traits. You do not write it.

And the content that already exists

Component definitions are only half of it. Everything your users already created is stored in the Craft.js node format, and moving it means walking that tree and emitting the definitions your new component types understand.

migrate-content.jsjs
// Craft.js persists `query.serialize()` β€” a JSON map of nodes keyed by id,
// each with { type: { resolvedName }, props, nodes }. Migrating it means
// walking that map and emitting the GrapesJS component definitions your new
// types understand: a transform you write once, per component type.
const toGrapesJs = {
  Hero: ({ title, description }) => ({ type: 'hero', title, description }),
  // …one entry per resolver entry in your Craft.js editor
};

function craftNodeToGjs(nodes, id) {
  const node = nodes[id];
  const map = toGrapesJs[node.type.resolvedName];
  if (!map) throw new Error(`Unmapped Craft.js component: ${node.type.resolvedName}`);

  return {
    ...map(node.props),
    components: (node.nodes ?? []).map((child) => craftNodeToGjs(nodes, child)),
  };
}

const nodes = JSON.parse(craftSerializedJson);
editor.setComponents(craftNodeToGjs(nodes, 'ROOT').components);

Both samples are illustrative. They show the shape of the mapping and the shape of the transform; neither is a drop-in migration, and nothing in either project generates one for you.

Scope

How Difficult Is a Craft.js Migration?

Three broad levels. None of them carries a duration, because the honest answer depends entirely on your codebase β€” and a page that promises you a number it cannot know is not helping you plan.

  1. Simple

    Basic components, little custom editor logic

    A handful of component types, a small settings surface, and content that has not accumulated many variations yet.

    You are probably here if

    • Fewer than about ten component types
    • Settings panels are mostly text and number inputs
    • Little or no content in production yet

    Usually a relatively focused migration.

  2. Medium

    Custom components, editor interface, storage and templates

    A real editor with its own panels, a template library, saved documents and a component set that has grown to fit the product.

    You are probably here if

    • Custom settings panels with conditional fields
    • A template library your users can start from
    • Saved content that has to survive the move

    Requires component and data mapping.

  3. Complex

    Deep React rendering dependencies and custom behaviour

    Components that depend on app context, editor behaviour extended in non-obvious places, and business rules embedded in the editing experience.

    You are probably here if

    • Components read app state or context to render
    • Custom state management wired into the editor
    • Business rules that live in editor behaviour, not in data

    Requires an architecture review and a staged migration.

Migration complexity depends on how deeply the existing app is coupled to Craft.js.

Work through the checklist
The plan

Craft.js β†’ GrapesJS Migration Checklist

The order a migration actually runs in, grouped into four phases. Useful whether you do it yourself or hand it to somebody.

15 steps
01

Understand what you have

Before anything is rebuilt, find out what actually has to move.

  • Audit Craft.js components
  • Identify reusable business logic
  • Map components to GrapesJS component types
  • Map React props to traits and properties
02

Rebuild the editing surface

Component types, the palette, and the controls your users expect.

  • Rebuild blocks
  • Recreate editor controls
  • Map templates
03

Move the data

Existing content, where it is stored, and the media it references.

  • Plan project data migration
  • Connect storage
  • Configure assets
  • Rebuild custom commands
04

Verify and roll out

Prove it works, then move people over without a hard cutover.

  • Test responsive behaviour
  • Test publishing
  • Run old and new editors in parallel
  • Migrate users gradually

The boxes are a printable plan, not saved state β€” nothing here is stored in your browser. Copy the steps into whatever tracker your team already uses.

Talk it through with someone who has done it
The question everyone asks

Can I Reuse My Existing React Components?

Not automatically.

Craft.js and GrapesJS use different component and editor models. A Craft.js component is a React component the editor drives through connectors; a GrapesJS component type is a definition inside the editor's own document model. There is no adapter that turns one into the other, and any page that tells you otherwise is describing work you will discover later.

What teams actually do

  1. 1

    Rebuild the visual definition in GrapesJS

    Take the markup and styling your React component produces and express it as a component type with traits. This is the default path and it is usually less work than it sounds, because the markup already exists.

    Cost: One definition per component type, written by hand and reviewed like any other code.

  2. 2

    Reuse the business logic outside the editor

    Pricing rules, validation, data fetching and formatting rarely belong to the editor at all. Lift them into modules the editor calls, and they survive the move untouched.

    Cost: Requires separating logic from rendering first, which is often worth doing regardless.

  3. 3

    Build an integration layer where React rendering is genuinely required

    Some components really do need React at render time. Those can be rendered into a container the editor owns, with the editor treating the result as one component.

    Cost: The most expensive option. Use it for the few components that need it, not as a general strategy.

  4. 4

    Map the properties rather than the components

    The editable surface is what your users care about. Mapping each editable prop to a trait or attribute preserves the experience even when the implementation underneath is entirely new.

    Cost: Property names and types have to be reconciled, and defaults have to be re-established.

The ecosystem

Extend Your GrapesJS Editor Instead of Building Everything Yourself

One advantage of choosing GrapesJS is that you can extend the editor through plugins rather than implementing every feature from scratch. These are real listings from the GJS.Market catalogue β€” names, prices and images come straight from the marketplace, so nothing here can drift from what is actually for sale.

Product shapes

What Can You Build With GrapesJS?

Each of these is a different product, and each has its own guide with the architecture, the trade-offs and the plugins that apply.

Integration

What About React, Next.js, Vue and Angular?

GrapesJS has a framework-agnostic core and can be integrated into applications built with modern frontend frameworks. It renders into a DOM element it owns, so an integration is mostly a question of which lifecycle point starts the editor and which one tears it down. That is a different thing from GrapesJS working as a native component system for your framework β€” internally it keeps its own document model, whichever framework is hosting it.
  1. React / Next.js / Vue / Angular
  2. Integration Layer
  3. GrapesJS
  4. Your Component Types
  5. Your Backend
npm install grapesjs @grapesjs/react
VisualEditor.tsxtsx
import grapesjs from 'grapesjs';
import GjsEditor from '@grapesjs/react';
import 'grapesjs/dist/css/grapes.min.css';

// GrapesJS owns an iframe canvas and touches `window`, so it mounts on the
// client. In Next.js, load this from a client component.
export default function VisualEditor() {
  return (
    <GjsEditor
      grapesjs={grapesjs}
      options={{
        height: '100vh',
        storageManager: { type: 'remote', autosave: true },
      }}
      onEditor={(editor) => {
        // Register the component types you mapped from your Craft.js
        // components here.
      }}
    />
  );
}

The integration layer is thin on purpose. Your framework owns the page, GrapesJS owns the canvas, and your component types are registered once the editor exists.

Two routes

Should You Migrate or Start Fresh?

If you have decided GrapesJS fits, there is still a second decision: carry the existing editor across, or build a new one beside it. They cost different things.

Migrate

Carry the component set, the templates and the saved content across, and keep the product continuous for the people using it.

Choose migration when

  • You have many existing templates.
  • Existing users depend on the current editor.
  • Your component library contains reusable business logic.
  • You need a gradual transition.

More mapping work up front, far less disruption for the people who already rely on the editor.

See the checklist

Start fresh

Build the new editor as its own thing, take the content across once it is ready, and use the opportunity to fix what you would otherwise carry forward.

Consider starting fresh when

  • The Craft.js editor is still small.
  • There are few existing templates.
  • The component architecture is changing anyway.
  • You want to redesign the editing experience.

Less compatibility work, but the content transform still has to be written if documents already exist.

Try the editor first
The verdict

Which Editor Should You Choose?

One requirement per row, one starting point. Four of these point at Craft.js, which is what makes the other five worth reading.

Your requirementBetter starting point
An editor that operates on a React component treeCraft.js
A complete visual editor foundationGrapesJS
An HTML and CSS page builderGrapesJS
A deeply React-first architectureCraft.js
Built-in visual editing toolsGrapesJS
A highly custom React editor interfaceCraft.js
A plugin-driven editor ecosystemGrapesJS
A SaaS page builderGrapesJS
An existing, mature Craft.js applicationAssess the migration cost first

There is no universal winner. The right choice depends on your editor architecture and product requirements.

Professional help

Need Help Migrating From Craft.js?

GJS.Market builds and migrates GrapesJS editors. If you would rather not work through the checklist alone, these are the stages an engagement covers β€” and the first one is an assessment, which may well conclude that staying on Craft.js is the right answer.

  1. 1
    Stage 1

    Architecture assessment

    We read the existing editor, work out how deeply it is coupled to Craft.js, and say plainly whether a migration is worth doing.

  2. 2
    Stage 2

    Component and template mapping

    Each component type is mapped to a GrapesJS definition, with its editable properties turned into traits, and existing templates are mapped alongside them.

  3. 3
    Stage 3

    Data and asset migration

    The transform from serialized Craft.js content to project data is written and tested against your real documents, and media is moved with it.

  4. 4
    Stage 4

    Custom editor logic and plugins

    Behaviour that has no equivalent in the core is rebuilt as commands, panels or plugins, so it stays maintainable rather than patched in.

  5. 5
    Stage 5

    Storage and publishing

    The Storage Manager is wired to your backend and the publishing path is connected end to end.

  6. 6
    Stage 6

    Parallel running and testing

    Both editors run side by side against the same content so the new one can be verified before anyone is moved onto it.

Questions

Frequently Asked Questions

What is the best Craft.js alternative?

It depends on what you are building. GrapesJS is the closest alternative for teams that want a visual editor foundation with components, blocks, styling, assets and storage already assembled. Puck is closer to Craft.js in spirit if you want to stay React-first. There is no single best answer, which is why this page is a comparison rather than a recommendation.

Is GrapesJS a replacement for Craft.js?

Not a drop-in one. The two have different component models, so moving means redefining your components and transforming your stored content. GrapesJS is a replacement in the sense that it can do the same job, not in the sense that you can swap the dependency.

What is the difference between Craft.js and GrapesJS?

Craft.js is a React framework for building page editors: it owns a node tree of your React components and leaves styling, assets, storage and the surrounding interface to you. GrapesJS is a visual editor framework whose core already includes a canvas, blocks, a Style Manager, an Asset Manager, a Layer Manager, commands, storage and a plugin system.

Is GrapesJS React-based?

No. The core is framework-agnostic and has no React dependency. There is an official React wrapper package, but internally GrapesJS maintains its own document model rather than a React tree.

Can GrapesJS work with React?

Yes. An official wrapper mounts the editor as a React component, and you can equally start it yourself from a ref and an effect. The React app hosts the editor; the editor still owns its own canvas.

Can I reuse my Craft.js React components?

Not automatically. A Craft.js component is a React component the editor drives through connectors; a GrapesJS component type is a definition in the editor's own model. Most teams rebuild the visual definition, keep the business logic in modules outside the editor, and add an integration layer only for the components that genuinely need React at render time.

Can I migrate Craft.js components to GrapesJS?

Yes, by mapping them rather than converting them. Each Craft.js component becomes a registered component type, its editable props become traits, and the markup it rendered moves into the type's model. It is hand-written work, roughly one definition per component type.

How does Craft.js component state map to GrapesJS?

Props an editor user can change map to traits. Props only your code sets map to attributes or fixed model properties. Application state that a component reads at render time has no direct equivalent and usually has to move out of the component and into the code around the editor.

Can I migrate existing Craft.js templates?

Yes, once the component types exist. A template is stored content, so it goes through the same transform as any other document: walk the serialized node tree, emit the equivalent GrapesJS components, and save the result as a template in the new system.

Can I migrate Craft.js project data?

Yes, with a transform you write. Craft.js persists a JSON map of nodes, each carrying a resolved component name, its props and its children. GrapesJS loads project data in its own JSON shape. Both are JSON, so the migration is a tree walk plus one mapping function per component type.

Is GrapesJS suitable for SaaS page builders?

It is a common use for it. GrapesJS supplies the editing layer; accounts, plans, permissions, templates, hosting and publishing remain yours to build. The SaaS page builder guide covers how those responsibilities divide.

Can I use GrapesJS with Next.js?

Yes. GrapesJS is client-only β€” it touches browser globals when it starts β€” so it is loaded lazily and rendered outside server rendering. That also keeps roughly 300 KB out of your first payload.

Does GrapesJS support TypeScript?

Yes. The package ships its own type definitions, so no separate types package is needed. The TypeScript guide covers the version floor and the types that are declared but not exported.

Can GrapesJS be white-labeled?

Yes. Panels, buttons, icons, labels and translations are all replaceable, and the plugin API can remove or rebuild parts of the interface entirely. That is what makes it viable as an editor embedded inside somebody else's branded product.

Can I extend GrapesJS with plugins?

Yes. A plugin is a function that receives the Editor and registers component types, blocks, commands, panels or storage adapters. This is the main extension mechanism, and it is what the marketplace listings are built on.

Where can I find GrapesJS plugins?

GJS.Market is a catalogue of GrapesJS plugins, blocks, presets and integrations, organised by catalogue section. The plugins section of this page shows current listings with live prices.

Should I migrate from Craft.js or start a new project?

Migrate when you have many templates, users who depend on the current editor, or business logic worth carrying across. Start fresh when the Craft.js editor is still small, there is little saved content, or the component architecture is changing anyway. Either way, existing documents still need a transform.

Can GJS.Market help migrate a Craft.js editor?

Yes. An engagement starts with an architecture assessment, then covers component and template mapping, data and asset migration, custom editor logic, storage and publishing, and a period of parallel running. The assessment can conclude that staying on Craft.js is the right answer.

Next step

Ready to Move Beyond Craft.js?

If your current editor requires too much custom infrastructure, evaluate GrapesJS with a real project. Start with the editor, extend it with plugins, and customize the architecture around your product.

Free

Try GrapesJS

Use the editor running further up this page, then take the official demo and the marketplace demos for a longer run.

Open the editor
Marketplace

Explore Plugins

Components, blocks, rich text editing, design systems, storage and assets β€” extensions that replace work you would otherwise write.

Explore Plugins
Services

Talk to a Migration Expert

An assessment first, then component mapping, data migration and parallel running. Including an honest answer if migrating is not worth it.

Request Migration Help