For a SaaS builder
Editor + pages + storage + templates
SaaS architecture guidePageKit — the self-hosted GrapesJS site builder, sold as source. Get early access
Let your users build pages visually while your development team controls the editor, components, design system, data, permissions and publishing workflow. You build the product. GrapesJS is the editing engine inside it.
Layers
Home page — draft
Settings
This is GrapesJS itself, booted in your browser on this page — not a screenshot and not a video. Drag a block in, select an element, restyle it. Everything on the canvas is plain HTML and CSS, which is exactly what your users would be producing.
You are not installing a page builder. You are adding a no-code editing feature to a product you already own — with your users, your permissions, your data and your publishing. The visual editor is one layer of that, and it is the layer you do not have to write.
The chain, end to end
Every layer above and below the engine is your product. That is where your differentiation lives — and it is where your engineering time should go.
The single most useful thing to settle before you write any code: which subsystem belongs to your application, which ships with the editor, and which you can buy off the shelf. Anything that needs a server is on the left.
Nothing that requires a server is listed under GrapesJS. The editor runs in the browser; it has no notion of who is signed in.
A visual editor looks like a drag-and-drop demo until you ship one. These are the subsystems that turn out to be mandatory, roughly in the order a user's gesture travels through them — and each one has to keep working while all the others change.
None of that is your product. Building the product around an existing editor engine is a fundamentally different project from building the editor engine itself — the first ships a feature, the second commits a team to maintaining an editor forever.
GrapesJS is an open-source visual editor framework you self-host and embed. It gives you the editing layer — canvas, components, styling, panels, commands — as documented modules you configure, extend or replace. Every module below links to its own documentation, so you can check each claim before you commit.
Version 0.23.6, licensed BSD-3-Clause; the official React wrapper @grapesjs/react is MIT. Both permit commercial use. What GrapesJS does not ship is equally important: no backend, no users, no permissions and no publishing pipeline — see the responsibility boundary above.
A professional no-code builder never exposes the whole editor to every user. That is the difference between a toy and a product feature. Your team decides — per role, per template, per component — how much of the editor a given person can reach.
Ten decisions that stay yours
const editor = grapesjs.init({
container: '#editor',
// 1. The user only ever sees blocks you registered.
blockManager: { blocks: approvedBlocks(user.role) },
// 2. The Style Manager only offers properties you allow.
styleManager: { sectors: allowedSectors(user.role) },
// 3. Devices are your breakpoints, not arbitrary widths.
deviceManager: { devices: BRAND_BREAKPOINTS },
});
// 4. Lock the chrome: a marketer never edits the header or the footer.
editor.on('component:add', (component) => {
if (LOCKED_TYPES.includes(component.get('type'))) {
component.set({
editable: false,
draggable: false,
removable: false,
copyable: false,
});
}
});
// 5. Hide panels this role has no business seeing.
if (!user.can('edit_code')) {
editor.Panels.removeButton('options', 'export-template');
}
// Every line above is a RENDERING decision. The server still checks
// user.can('publish') before it accepts the payload.Everything above is a rendering decision. Hiding a panel is not a permission — a determined user can still call the editor's API from a console. Your backend must re-check the same rules before it accepts a save or a publish. See the roles section below.
You do not need three editors to serve three kinds of user. One GrapesJS instance, configured from the signed-in user's role, produces three genuinely different products. Each column below lists what it adds to the one before it.
For people who have never opened a design tool and never should have to.
Adds everything a campaign owner needs to ship without a developer.
Adds the controls an in-house designer or agency operator expects.
The configuration is data, not code. Which means the difference between your Starter plan and your Enterprise plan can be a row in a table.
The fastest way to make a visual editor safe is to give it nothing unsafe to offer. Feed your tokens into the Style Manager and your components into the Block Manager, and "off-brand" stops being a review problem — it becomes unreachable.
Colour
Type & scale
Spacing
Available in the editor
Not reachable
Users create real content without being able to break brand consistency — and your design team stops reviewing pages one at a time. If you already ship a component library, those components become the blocks.
A blank canvas is not freedom, it is a blank stare. The single biggest driver of whether non-technical users succeed in your builder is whether the first thing they see is a curated set of sections that already look like your product.
Headline, sub-line, one call to action.
Two to four column feature grid.
Plan cards wired to your own plan data.
Quote, attribution, optional logo.
Question and answer pairs.
One message, one button.
Form fields posting to your endpoint.
Usually locked, always present.
Blocks answer "what can I add". Templates answer "where do I start". Ship a small, opinionated set — a page kind your users actually create, not a gallery.
Template kinds worth shipping
Templates are ordinary saved projects with a flag on them. Storing them is your application's job, which means so is versioning them.
The best no-code experience does not force users to design everything from zero.
Into your database, on your endpoints, under your schema. GrapesJS's Storage Manager is an HTTP client with a load URL and a store URL — it is not a hosting service, and GJS.Market does not hold your customers' pages.
What actually happens on save
grapesjs.init({
container: '#editor',
storageManager: {
type: 'remote',
autosave: true,
autosaveIntervalMs: 10_000, // debounce: one write, not one per keystroke
stepsBeforeSave: 20,
options: {
remote: {
urlLoad: `/api/pages/${pageId}`,
urlStore: `/api/pages/${pageId}`,
headers: { Authorization: `Bearer ${token}` },
},
},
},
});
// The editor sends you project JSON. What that JSON is allowed to
// become — a draft, a revision, a published page — is your API's call.GrapesJS provides the editing layer. Your application controls how projects are stored and published — which is also why drafts, revisions and rollback are yours to design. Autosave belongs on a debounce; a save per keystroke is a denial-of-service attack on your own API.
Two artifacts, two jobs
The component tree, styles and assets the editor needs to reopen the page exactly as it was. Versioned, diffable, never served to visitors. This is what a revision is.
What `editor.getHtml()` and `editor.getCss()` produce: a static page you sanitize, store and serve. A visitor should never load the editor runtime.
Editing and publishing are different actions with different risk profiles, and a production no-code product separates them. The two gated stages below are where an authorization check belongs — not in the editor, in your API.
A project row with no live URL.
Autosaved project JSON, revision per session.
Rendered output on a signed, temporary URL.
A reviewer sees the preview, not the editor.
A state change your API authorizes and records.
Sanitized output written to your production site.
Authorization checked here
Permissions, approvals and publishing logic belong to the application and its backend. GrapesJS has no concept of a draft, an approval or a live URL — those states live in your database, and rollback is simply publishing an earlier revision.
Four roles cover most builder products. Each one gets a genuinely different editor because each one loads a different configuration — but every one of them is enforced in the same place: your backend.
Configures the editor, templates and roles
Edits layout and styling
Previews and approves; cannot edit
Edits text and images; cannot change layout
How one permission decision travels
Application-level authentication and authorization are handled by your backend. The editor is the last stop in that chain, never the first: it renders the consequences of a decision your server already made, and your server must make it again when the save arrives.
The same architecture — your product, your users, the editing engine, your API — carries seven quite different products. Each card links to the guide that covers that one properly.
Your customers create pages inside your SaaS, on your plans, against your quotas.
SaaS architecture guideUsers build complete multi-page websites visually, with your components as the vocabulary.
Drag-and-drop mechanicsMarketing teams launch campaigns without waiting on a developer or a deploy.
Landing page guideEditors compose content visually while the CMS stays the source of truth.
Headless CMS guideUsers assemble email layouts without touching table-based HTML.
Email builder guideCustomers customise controlled content inside a portal you fully define.
Embedding guideOffer the editor as part of your own branded product, under your name.
White-label guideThis table is deliberately narrow: it compares the editing engine only. Everything on the responsibility boundary marked "your application" is your work either way — that is the point.
| Capability | Build from scratch | GrapesJS |
|---|---|---|
| Visual canvas | Build | Available |
| Components | Build | Available |
| Drag & drop | Build | Available |
| Blocks | Build | Extensible |
| Styling | Build | Available |
| Layers | Build | Available |
| Commands | Build | Available |
| Storage integration | Build | Configurable |
| Custom components | Build | Supported |
| Plugin architecture | Build | Supported |
| Product-specific UX | Build | Customizable |
Capabilities checked against the GrapesJS 0.23.6 documentation; catalogue listings and prices verified 2026-09-03.
Don't build the editor engine if your real product is the application around it.
Real listings from the GJS.Market catalogue, grouped by the job you are doing rather than by the catalogue's own taxonomy. Prices come from the live catalogue, so what you see here is what a product costs today.
Replace or reshape the editor chrome so it reads as part of your product.
Browse this categoryA panel-less editor shell — the clearest starting point when the default chrome is not your product.
React components for the editor UI, so the panels live in your own component tree.
Filter the Style Manager down to the properties a given role should see.
Rulers and guides on the canvas, for users who care where things line up.
The palette and the starting points your users actually work from.
Browse this categorySave any selection as a reusable block your whole team can drag in.
Manage a template library inside the editor instead of bolting one on.
A Tailwind-native block set, if your design system is already Tailwind.
A Bootstrap 5 block set, if that is the framework your output already uses.
Store projects in Directus with no custom persistence layer to write.
Firebase-backed persistence for teams already on Firebase.
Local persistence — useful for offline drafts and for prototyping before your API exists.
Throttle how often the editor writes, so autosave cannot flood your API.
Multi-page projects: the difference between a page editor and a site builder.
Switch between saved projects from inside the editor.
Reusable instances that update everywhere at once — your design system's shared parts.
The web-page preset: a sensible default configuration to start a site builder from.
Point the Asset Manager at Cloudinary instead of building an uploader.
Uppy-powered uploads with resumable transfers and your own storage target.
Expose exactly the fonts your brand allows, and no others.
Crop and adjust images inside the editor instead of sending users elsewhere.
Export the produced HTML, CSS and assets as a downloadable archive.
Push the produced output straight to a Netlify site.
Per-component code view for the power users who ask for it.
Turn stored project JSON into HTML and CSS on the server, at publish time.
Two things you will need are deliberately missing from these shelves, because the catalogue does not have them: a roles and permissions plugin, and an approval-workflow plugin. Both belong in your application anyway — see the roles and publishing sections above, or bring them to our implementation team.
Three combinations that get a working builder in front of users quickly. Each is a starting point, not a bill of materials — swap any row for the equivalent that fits your backend.
Editor + pages + storage + templates
SaaS architecture guideBlocks + templates + assets
Landing page guideCustom UI + controlled styles + shared components
White-label guidePrices are read from the live catalogue at build time. Free plugins are open source and self-hosted like the core.
White-labelling is not hiding a logo. It is making the editor read as a feature of your application rather than as a third-party tool someone embedded in it.
Your colours, type and iconography throughout the editor chrome.
Rebuild the toolbars around your users' actual tasks.
Your design system's components, named the way your team names them.
If your users say "module", the editor should not say "component".
Removing controls is the most under-used customisation there is.
Defaults, empty states and onboarding that match the rest of your product.
Removing the GrapesJS branding is trivial and permitted by the BSD-3-Clause licence. Making the editor feel like your product is a design project — panels, terminology, defaults, and everything a user does not see.
GrapesJS renders into a plain DOM element, so integrating it is mostly a question of which lifecycle hook calls `grapesjs.init()` and when it is cleaned up. Pick your framework for the specifics.
An effect that initialises on mount and destroys on unmount. The official @grapesjs/react wrapper (MIT) is available if you want the editor's own UI as React components.
See React integrationA composable calling init from `onMounted` and destroy from `onBeforeUnmount`. There is no official Vue wrapper — you call the same API directly.
See Vue integrationA component using `ngAfterViewInit` and `ngOnDestroy`, with the editor kept outside Angular's change detection. No official Angular wrapper exists.
See Angular integrationClient-side only: the editor touches `window` at module scope, so load it through a dynamic import with SSR disabled.
See Next.js integrationYour framework powers the application. GrapesJS powers the visual editing layer.
The gap between "the editor works" and "we can put customers on it" is roughly this list. Each group links back to the section that argues it.
What the user can reach, and what they cannot.
Register blocks per role, not once globally.
Persistence a user can trust with a day of work.
Debounced autosave, not a write per keystroke.
Everything the editor produces came from a user.
Sanitize on the way out, on the server.
The difference between adoption and a support queue.
Templates beat an empty canvas every time.
Editing and publishing have different risk profiles.
Rollback is publishing an earlier revision.
The editor is now part of your product's uptime.
Log editor errors with the project id attached.
A no-code builder is, by construction, a feature that lets users put arbitrary content into your product. Treat everything it produces as untrusted input, because it is.
Run produced HTML and CSS through a vetted sanitizer on the server before it is stored or served.
Check type, size and dimensions server-side, and serve user media from a separate origin.
Every save, approve and publish is authorized again on the server, whatever the editor showed.
A hidden panel is a UI state. The editor's API is still reachable from a browser console.
Project JSON is user input too. Validate its shape before you feed it back to a renderer.
If you allow a custom-code component, decide deliberately where it runs and who may add one.
Rate-limit them, scope them per project, and log every call.
GrapesJS is an editing library, not a security boundary. It makes no guarantee about the safety of the markup it produces, and it cannot: the markup came from your user. Sanitization, validation and authorization are your application's responsibility.
The editor is a heavy client-side application living inside your product. Most of the wins come from not loading it — and from not loading it twice.
Boot the editor when a user opens it, not when the route loads.
Dynamic-import plugins the current role can actually use.
Every registered plugin costs bundle size and start-up time forever.
Hundreds of blocks slow the palette down and paralyse the user.
Resize and re-encode on upload — users will drop 8 MB photos into a hero.
One write every few seconds, not one per keystroke.
Inlined base64 images turn a project row into megabytes. Store references, not data.
The published page must never carry the editor. A visitor loads HTML and CSS; only an author loads the engine.
AI in a page builder is most useful, and least dangerous, when it is treated as another user of the same editor — one that can only produce what a human in the same role could have produced.
Assemble a section from your registered blocks, not from free-form markup.
Fill an existing layout's text nodes, leaving structure untouched.
Propose an arrangement of approved components for a stated goal.
Rewrite for length, tone or locale in place.
Draft a new component definition for a developer to review — never to auto-register.
Suggest edits against measurable criteria and let a human approve them.
AI should operate inside the same component and design-system constraints as human users. If a generator can emit arbitrary HTML that your block palette would never offer, you have re-opened every hole you closed.
The capabilities above describe a pattern you can build on the editor's own APIs, not a shipped GJS.Market feature. The catalogue does have an AI shelf — thumbnail generation, GPT-backed helpers — and it is linked above.
Implementation
Most teams do not get stuck on `grapesjs.init()`. They get stuck on the parts this page says are theirs — permissions, publishing, storage, and making the editor feel like their product. That is what our team does.
Give your users the freedom to build visually without giving up control of your product.
Tell us what you are building and get a scoped plan for the editor inside your product.
Start Building with GrapesJSBlocks, storage adapters, editor UIs and components — real listings with current prices.
Explore GJS.Market PluginsIntegration, custom components, permissions and publishing workflows, built with your team.
Talk to an ExpertYour product. Your users. Your rules. Your editor.