BuilderJS

A Laravel Drag and Drop Builder You Embed in Your Own Blade Views

BuilderJS is a framework-agnostic, vanilla-JS drag-and-drop editor library (~140KB) that mounts in any DOM node — including a div inside a Blade view. It is the editor you embed, not a hosted platform: it builds the markup, and your Laravel app owns the routes, persistence, auth, and serving. Because the engine is plain JavaScript, there is no npm React/Vue component to wire up. You drop two assets into `public/`, render three container divs in Blade, instantiate `new Builder({...})`, and persist the canvas with a single `getData()` call POSTed to one of your own routes. It produces both responsive web/landing-page HTML and Outlook-safe email HTML from the same JSON. And it ships reference PHP backends for save, upload, and auth (MySQL, SQLite, S3-compatible) that you copy into your controllers and own outright — no SaaS account, no per-seat metering, no phone-home. Try the live editor at builder.emotsy.com.

Mount it

{{-- resources/views/builder.blade.php — client-side mount in a Blade view --}}
<link rel="stylesheet" href="{{ asset('builder/builder.css') }}">
<div id="WidgetsContainer"></div>
<div id="MainContainer"></div>
<div id="SettingsContainer"></div>

<script src="{{ asset('builder/builder.js') }}"></script>
<script>
  // Containers exist above, so mount immediately (client-side only).
  const builder = new Builder({
    mainContainer: '#MainContainer',
    widgetsContainer: '#WidgetsContainer',
    settingsContainer: '#SettingsContainer',
    outputMode: 'page', // or 'email' for Outlook-safe export
  });

  // Reload a saved design (JSON echoed from your controller).
  const saved = @json($design->data ?? null);
  builder.load(saved, {}, {}, '{{ asset('builder/media') }}/');

  // Persist via getData() → POST to your own Laravel route.
  window.saveDesign = () =>
    fetch('{{ route('builder.save') }}', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json',
                 'X-CSRF-TOKEN': '{{ csrf_token() }}' },
      body: JSON.stringify({ data: builder.getData() }),
    });
</script>

Mount it on a div — no npm component, no SSR

BuilderJS ships as a DOM-mount bundle (dist/builder.js + dist/builder.css), not a published Composer or npm package. The integration is deliberately boring: copy the two files into public/builder/, render three container divs in a Blade view (one for the canvas, one for the widget palette, one for the settings panel), include the script, and call new Builder({...}) once the divs exist in the DOM. It runs entirely client-side, so it never touches Blade's server render — you can put the whole thing inside a normal @extends('layouts.app') page, an admin panel, or a Livewire/Inertia screen. The constructor takes CSS selectors for its three containers (mainContainer, widgetsContainer, settingsContainer) plus an optional outputMode of 'email' or 'page', then builder.load(...) paints a starting template. That's the entire bootstrap.

Persist with getData() → your own Laravel route

The editor is JSON-first. builder.getData() returns a lossless snapshot of the canvas, and builder.load() restores it byte-for-byte on the next edit — a clean round-trip you store however you like. In Laravel that means a Route::post('/builder/save', ...) endpoint that accepts the JSON and the rendered HTML, validates them with a FormRequest, and writes to your model (a designs table, a JSON column, wherever). On the way back in, you echo the saved JSON into the Blade view and hand it to load(). There is no SDK lock-in to this shape: the payload is your data in your database, and the route is your controller. You decide CSRF handling, route-model binding, policy gates, and which guard protects the editor — BuilderJS has no opinion about any of it.

Reference PHP backends you copy and own

You do not have to invent the server side from scratch. The package includes working reference PHP backends for the three jobs an embedded builder needs — save a snapshot, upload an asset, and authenticate the request. The save handler validates payload size and path safety then writes the JSON + HTML; the storage layer has both a local-filesystem driver and an S3-compatible driver (same wire protocol as MinIO, Backblaze B2, and Cloudflare R2) that you repoint with one config key; the DB helper is a thin PDO factory that defaults to SQLite for zero-config dev and switches to MySQL via env vars. These are plain PHP you lift into your Laravel controllers and adapt — swap the PDO factory for Eloquent, swap the bare validator for a FormRequest, swap local storage for Laravel's Filesystem/S3 disk. The contract (accept JSON, return a URL or success) stays identical. If your stack isn't PHP, the same handlers port cleanly to Node, Go, or Python.

One editor for both email and landing pages

The same mounted builder produces two different outputs depending on outputMode. In 'page' mode you get responsive web/landing-page HTML. In 'email' mode an export pipeline rewrites the document to be email-client-safe: flexbox layouts become nested tables, SVG icons rasterize to PNG, @media rules collapse to mobile-stack, and Outlook MSO conditionals are injected, with a CSS inliner finishing the job. The bundled templates and samples were tested across 22 email clients via Litmus. So a single Laravel integration can power both your transactional-email template editor and your marketing landing-page editor — you flip one constructor option per use case. BuilderJS builds the markup in each case; bringing an ESP to send the email or a host to serve the page is your app's responsibility.

Own the source, extend without forking

BuilderJS is sold once on CodeCanyon (item 27146783) as Regular $52 or Extended $99 — you own the source, self-host it, and there is no monthly fee, no per-seat charge, no usage metering, and no phone-home. You extend it without touching engine internals: register custom elements, widgets, and controls through Builder.registerElement, ship your own themes, and localize with built-in i18n across 20+ locales including RTL. It is multi-tenant capable — the instance is closure-captured so you can run many editors — but your Laravel app owns tenant isolation, seats, and billing. AI hooks are pluggable and vendor-neutral, so you wire your own provider if you want generation features. Author support is time-boxed (roughly 6–12 months), which is normal for a one-time CodeCanyon license.

Frequently asked questions

Explore