Lesson 10
How to Build a Website Builder
In this lesson
How to build a website builder is the one question in this course that is pure engineering curiosity, and it deserves a real answer rather than a tutorial that stops at a draggable box. A builder is seven separate systems wearing one interface, and six of them are harder than the drag-and-drop everybody starts with.
This lesson covers those seven components, a stack that is realistic in 2026, what the open-source landscape actually looks like this month, and an honest estimate of the effort involved.
First, the thing nobody says out loud
Almost nobody should build a website builder. The market has large, well-funded incumbents and the surface area is enormous.
When people search this phrase, the question underneath it is usually different: how do I let my users edit pages visually inside a product I already have? That is a far smaller problem, it has good off-the-shelf answers, and it is worth checking whether it is your actual question before you commit six months.
If it genuinely is a builder you want to build, here is what is in one.
The seven components
- Editor and canvas — selection, hit-testing, drag handles, snapping, z-order, and an undo/redo stack. Undo is the item everyone underestimates. It has to be correct across every operation forever, and users abandon a tool within a day of discovering that undo lost their work.
- Component schema and registry — a declarative description of every component's name, its inputs and their types. This is the contract between editor and renderer, and it is the piece to design first. Get it wrong and everything downstream rots, because both sides have encoded assumptions about a shape that no longer holds.
- Drag-and-drop mechanics — drop-target resolution, insertion indicators, and constraint rules about what may nest inside what. Deceptively hard, because the visual feedback has to stay smooth while those rules are evaluated on every pointer move.
- Persistence — versioned JSON documents, draft versus published state, autosave, and conflict handling for the moment somebody has the same page open in two tabs. A page is stored as a tree of typed nodes with options, not as markup.
- Renderer and publisher — the same tree rendered twice, interactively inside the editor and cleanly for production. Keeping those two outputs identical is a permanent, recurring source of bugs, and it is why a builder preview and a published page sometimes disagree.
- Hosting layer — build and deploy pipeline, custom hostname registration, automatic TLS, CDN invalidation. This is an entire product by itself, and it is the one to buy rather than build.
- Template system — seed documents plus a design-token layer, so that swapping a template is a token swap rather than a re-authoring exercise. Skip the token layer and every template change becomes a migration.
How live editing actually works
Worth understanding before you design the canvas, because it shapes everything after it. Live editing in production builders is typically an iframe plus message passing. The application sends the page JSON into the preview, then sends patches describing what changed, and the SDK re-renders accordingly. Builder.io's technical documentation describes exactly this arrangement: the system keeps a map of component names to references and tells the preview what components exist and what inputs each one takes.
That architecture is why builder editors feel instant, and it is also why a published page can differ from what the editor showed you. You are watching two renderers agree most of the time. Deciding early whether your editor renders inside an iframe or in the same document as the editor shell is one of the few choices here that is genuinely expensive to reverse later.
A realistic 2026 stack
React or Vue for the editor shell. The component registry expressed as a typed schema. A JSON document store — Postgres with JSONB columns is entirely sufficient and saves you a second database. Server-rendered publish output. Object storage plus a CDN for assets. And an edge provider's custom-hostname API for domains and certificates, because automatic TLS at scale is a solved problem you should not re-solve.
Nothing on that list is exotic, and that is the point. The difficulty in a builder is almost never the technology choice. It is the correctness of the editor and the stability of the schema.
The open-source landscape, checked this month
Status below was checked against the GitHub API and the npm registry in August 2026. It is a status board, not a recommendation — choose by licence and by fit with your stack.
| Project | Licence | Latest release | Activity |
|---|---|---|---|
| GrapesJS | BSD-3-Clause | v0.23.5, 11 Aug 2026 | Active, around 26.2k stars |
| Puck | MIT | v0.23.0, 7 Aug 2026 | Active, around 13.2k stars; repo and package moved |
| Builder.io (open packages) | MIT | SDK releases through 21 Aug 2026 | Active, around 8.8k stars; only parts are open |
| Plasmic | MIT | loader 2.0.24, 20 Aug 2026 | Active, around 7.0k stars |
| Craft.js | MIT | 0.2.12, 14 Feb 2025 | Dormant for about 18 months, around 8.7k stars |
| Silex | AGPL-3.0 | v3.9.0, 26 Jul 2026 | Active, around 2.9k stars |
The dormant one
Craft.js has had no repository commits and no npm publishes since 14 February 2025 — about eighteen months. Its core package sits at 0.2.12. Plenty of 2026 roundups still present it as a maintained option, which is worth knowing before you build on it.
That is not a criticism of the code. Architecturally it remains an excellent reference for how to model an editable node tree, and reading it will teach you things. It is simply not a dependency to start a commercial product on in 2026 without knowing you are adopting it.
The one that moved
Puck now lives at the puckeditor organisation and publishes as @puckeditor/core, which reached v0.23.0 on 7 August 2026. The older @measured/puck package stopped publishing in September 2025. If you followed a tutorial written before the move and your dependency looks abandoned, it is not — you are pointed at the old package name.
The licence that changes the answer
GrapesJS is BSD-3-Clause; Puck, Plasmic, Builder.io's open packages and Craft.js are MIT. Those are permissive licences and they impose very little on you.
Silex is AGPL-3.0, which is a different animal. The AGPL extends copyleft obligations to software offered over a network, so building a hosted commercial service on it has real consequences for your own source. That is not a defect — it is a deliberate choice by its authors — but it is a decision to take with your eyes open and, if money is involved, with advice.
How long this actually takes
A usable drag-and-drop editor demo is a weekend, and that weekend is genuinely fun. What takes the time afterwards is undo/redo correctness, responsive breakpoints, an asset pipeline, document versioning, permissions and sharing, custom domains, TLS automation and billing.
We could not verify effort figures against any primary source, so treat the following explicitly as an estimate rather than data: roughly three to six months for a credible single-developer MVP, and multiple engineer-years for a commercially viable multi-tenant product. Those numbers are offered to set expectations, not to plan against.
The question behind the question
If visual editing is a feature of your product rather than the product itself, embed an existing editor. GrapesJS gives you the most complete whole-editor starting point; Puck is the natural fit if your front end is React. Either one removes six of the seven components above from your roadmap on day one.
Lock-in is a product decision, not a property of visual editing. Builder.io's own documentation describes the opposite model — you control your site, code and hosting, and the tool only passes content into your setup. If you build a builder, you get to choose which of those you are making.
Where this sits in the course
This is the last lesson, and the most optional one. If you arrived here from a search engine and what you actually need is a site of your own rather than a product, start at the beginning with how to make a website — it is a shorter road than this one.
Questions from the class
Should I build a website builder or embed an existing editor?
Is Craft.js still maintained?
Why does my Puck package look abandoned?
Does an AGPL licence matter if I only host the software?
Before you write any code
- You have written down whether you are building a builder or adding visual editing.
- The component schema exists on paper before the canvas exists in code.
- Undo/redo is in the first milestone, not a later one.
- You checked the last release date of every dependency yourself.
- You know the licence of everything you are depending on, and what it requires.
- Custom hostnames and TLS are being bought from an edge provider, not built.
That’s the syllabus. Put it together with the complete path from zero to live.