A CMS page editor library you embed, then own
If you run a CMS, a course platform, or any app where your users need to compose rich pages, you have two bad options: build a drag-drop editor from scratch (months of work, then years of maintenance), or rent a hosted visual-CMS that meters your usage and owns your data. BuilderJS is a third path. It is a ~140KB vanilla-JS drag-drop editor library that mounts into any DOM node — React, Vue, Svelte, Angular, Next.js, Laravel, or plain HTML. Your users drag from 42 element types across 59 controls; BuilderJS hands you back clean JSON via getData(), and load() restores it losslessly. BuilderJS is the editor — it does not host or publish anything. You host the pages, you store the JSON, you render the output, you own the source. One-time CodeCanyon license (item 27146783), self-hosted, no monthly fee, no per-seat charge, no usage metering, no phone-home. See it live at builder.emotsy.com.
What BuilderJS is (and what stays yours)
BuilderJS is the embeddable editing surface — a drag-drop canvas your users interact with inside your CMS or LMS. It is not a platform: it does not host your pages, publish them to a URL, run a CDN, manage content models, or process traffic. That separation is the point. You keep your own routing, your own database, your own rendering layer, and your own hosting. BuilderJS produces two artifacts you control completely: a lossless JSON document (the source of truth you store in your tables) and rendered output HTML. When a learner or author finishes editing a lesson page or a marketing page, you call getData(), POST the JSON to your route, and persist it however you already persist content. To re-open for editing, you call load() with that same JSON and get a pixel-identical canvas back. Nothing round-trips through a vendor server.
Mounts in the stack you already run
BuilderJS ships as a DOM-mount bundle — dist/builder.js plus dist/builder.css — not a published npm React or Vue component. You mount it client-side into a container element after the DOM exists: in React from a useEffect, in Vue from onMounted, in Angular from ngAfterViewInit, in Svelte from onMount, or in plain HTML with a single script tag. In Next.js, load it via a dynamic import with ssr:false inside a 'use client' component, because the editor is browser-only. This DOM-node mount model is why one bundle works across every framework instead of forcing you to adopt a specific one — a real concern for a CMS that may outlive its current frontend. Persistence is your call: getData() returns JSON, you POST it to your own backend route, and you render it server-side or client-side however your CMS already does.
JSON-first persistence built for a content store
A CMS lives and dies by how cleanly content serializes. BuilderJS is JSON-first by design: getData() emits a structured document, load() restores it with no lossy export step in between. That JSON is yours to store in MySQL, Postgres, SQLite, a document store, or anywhere else — version it, diff it, migrate it, search it, attach it to a course module or a page record. Because the canonical form is JSON rather than baked HTML, you can re-render the same content into different output targets: page HTML for the web, or — through the EmailExportPipeline — Outlook-safe email HTML (flexbox collapsed to tables, SVG rasterized to PNG, @media mobile-stacking, MSO conditionals, CSS inlined). So the same editor that builds your course landing pages can also build the lesson-reminder email template your app then sends through whatever ESP you already use. BuilderJS builds the markup; you bring the sending and the hosting.
Extend it for your domain without forking
Course platforms and CMSes always need bespoke blocks — a quiz embed, a video-lesson card, a pricing table tied to your plans, a callout your editorial team standardized on. BuilderJS lets you register custom Elements, Widgets, and Controls through Builder.registerElement without touching or forking the core bundle, so vendor updates never collide with your customizations. It ships 42 element types, 59 controls, and 31 overlays out of the box, plus themeable styling and i18n across 20+ locales with RTL support. AI hooks are pluggable and vendor-neutral — you wire in whatever model you already pay for, or none. The library is multi-tenant capable through closure-captured configuration, but tenant isolation, seat limits, and billing remain your application's responsibility, exactly where a CMS wants that logic to live. Reference PHP backends (MySQL/SQLite/S3 save, upload, and auth) are included for you to copy and own outright, and they port cleanly to Node, Go, or Python.
How it compares to finished open-source editors
The closest finished, supported alternatives are open-source, and they are genuinely good — the honest comparison is about fit, not price. GrapesJS is a free, BSD-3-Clause embeddable web-builder framework (v0.23.2, no required backend) that also targets email via an MJML plugin; source at github.com/GrapesJS/grapesjs, as of June 2026. Puck is a free, MIT-licensed visual editor (v0.21.3) that is React-only — it is a React component, so it fits React apps beautifully but does not drop into a Laravel or plain-HTML CMS the same way; source at github.com/puckeditor/puck, as of June 2026. Hosted visual-CMS products like Builder.io sit at the other end: its free tier is capped at 5 users and metered with Agent Credits (25 daily / 75 monthly on the free plan), with paid Pro/Team tiers billed per user per month (builder.io/m/pricing, as of June 2026) — a recurring, metered model. BuilderJS's distinct position: it is framework-agnostic (any DOM node, not one framework), it builds both web pages and Outlook-safe email from one JSON source, it is finished and supported, and it is a one-time license you self-host with no metering. Evaluate all of them against your stack — that is the honest way to choose.
Frequently asked questions
-
Does BuilderJS host or publish the pages my users create?
No. BuilderJS is the editor you embed, not a platform. It does not host, publish, serve, or run a CDN for anything. It produces JSON (via getData()) and rendered HTML; you store that content in your own database and serve it from your own CMS, on your own hosting. That is the intended division of labor — you keep full control of your pages.
-
Is BuilderJS an npm React component I can just import?
Not exactly. It is a DOM-mount bundle (dist/builder.js + dist/builder.css), not a published npm React/Vue component. You mount it client-side into a container element after the DOM exists — in React from useEffect, Vue from onMounted, Angular from ngAfterViewInit, Svelte from onMount, or a plain script tag. In Next.js use a dynamic import with ssr:false inside a 'use client' component, since the editor runs in the browser only.
-
How do I persist what users build, and is the round-trip lossless?
BuilderJS is JSON-first. Call getData() to get a structured JSON document, POST it to your own backend route, and store it wherever you store content. To re-open for editing, call load() with that same JSON — the round-trip is lossless, so the canvas comes back exactly as the user left it. Reference PHP backends for save/upload/auth (MySQL/SQLite/S3) are included for you to copy, own, and port to Node, Go, or Python.
-
Can I add custom blocks for my course platform without forking?
Yes. Register custom Elements, Widgets, and Controls via Builder.registerElement without modifying or forking the core bundle, so vendor updates stay clean. It includes 42 element types, 59 controls, and 31 overlays, plus themes, i18n across 20+ locales with RTL, and pluggable vendor-neutral AI hooks you can wire to your own model.
-
What does BuilderJS cost, and is it a subscription?
It is a one-time CodeCanyon license (item 27146783) — Regular at $52 and Extended at $99. You own the source and self-host it: no SaaS, no monthly fee, no per-seat charge, no usage metering, and no phone-home. Author support is time-boxed (roughly 6–12 months). By contrast, hosted visual-CMS products typically bill per user per month with usage metering — for example Builder.io's free tier is capped at 5 users and metered with Agent Credits (builder.io/m/pricing, as of June 2026).