setono/editorjs-php
Setono Editor.js PHP is a PHP library for parsing, sanitizing, and rendering Editor.js JSON as HTML. It provides custom block handlers, validation, and extensible configuration, making it easy to safely display Editor.js content server-side with clean, controlled output in Laravel or any PHP applica...
Architecture fit. setono/editorjs-php is a framework-agnostic PHP rendering SDK for Editor.js block JSON: you hand it the blocks array emitted by the editor and it returns HTML via pluggable block renderers. That is a clean, narrow responsibility — no persistence, no HTTP layer, no opinion about your domain model — which makes it a good fit for a Laravel app that needs server-side rendering of rich text authored in Editor.js (blogs, CMS pages, marketing content, knowledge-base articles). It is not a Laravel package: expect no service provider, facade, config publishing, or Blade components. Treat it as a library you wrap, not a framework integration you install.
Integration feasibility. Low-to-moderate. composer require setono/editorjs-php plus a thin application-level wrapper (a ContentRenderer service that validates the JSON, enforces a block allowlist, and delegates to the SDK) is typically a day of work for a mid-level Laravel developer. The real effort is not the library — it is the content contract: which Editor.js tools your front end enables, what data shape each produces, and which of those the SDK renders out of the box versus which you must implement as a custom block handler.
Technical risk. Modest but non-trivial, concentrated in three areas:
raw or embed block is the highest-severity failure mode.Key questions to resolve before approval.
Stack fit. Compatible with a standard Laravel application on PHP 8.x. Because there is no auto-discovery, register it deliberately: bind a EditorJsRenderer singleton in AppServiceProvider, keep block-to-renderer mapping in config/editorjs.php, and expose a single application service (render(array $blocks): string) so the rest of the codebase never touches the vendor API. This insulates you from an upstream fork or replacement and gives you one place to enforce sanitization and logging of unknown blocks.
Migration path. Store the canonical Editor.js JSON (a json or longtext column) as the source of truth, and store a rendered HTML cache column alongside it. Render on save and expose a console command to re-render the corpus; this gives you cheap read paths, full-text search over HTML, and a clean re-render lever when the renderer, block allowlist, or sanitizer policy changes. For existing HTML or other-editor content, migrate lazily: convert to Editor.js JSON where tooling exists, otherwise keep a legacy content column with a discriminator. Do not attempt a big-bang conversion.
Compatibility. The contract is Editor.js's {time, blocks:[{id,type,data}], version} payload. Client-side editor upgrades (Editor.js core or individual tools) can change data shapes without a corresponding PHP change — pin the editor and tool versions on the front end, and add a fixture-based test suite that captures real editor output per tool version. Verify the transitive sanitizer dependency's PHP extension requirements (e.g., intl, mbstring) in CI early.
Sequencing.
Maintenance. Expect to own this dependency more than a typical Composer package. Pin an exact version (avoid ^), vendor it if policy allows, and budget a named engineer as owner. Track upstream issues and be prepared to fork — the code surface is small enough that a fork is a realistic contingency rather than a rewrite.
Support. Community-only, best-effort GitHub issues; no commercial backing or SLA. Internal documentation of the block contract and wrapper API is the real support mechanism. Escalation path for content-rendering bugs is your own team.
Scaling. Rendering cost is negligible: parsing a block array and emitting strings is microseconds-to-low-milliseconds even for long documents. Do not expect this to be a throughput bottleneck. The scaling decisions that matter are architectural — render-on-write with a cached HTML column and cache invalidation on re-render, versus render-on-read. Prefer render-on-write.
Failure modes to instrument and test.
raw/embed/attaches blocks → sanitizer misconfiguration. Treat as a security regression suite.data shape → renderer produces malformed HTML. Mitigate with version-pinned editor plus fixture tests.Ramp-up. A Laravel developer unfamiliar with Editor.js needs roughly half a day to a day to be productive: install, render a sample, read the renderer interface, add one custom block. The TPM-side work is larger than the engineering work — agreeing the tool allowlist, the sanitization policy, and the storage/rendering strategy across front-end, back-end, and security reviewers is where the schedule risk sits. Plan a short spike with a written go/no-go gate on block coverage before committing the package to the architecture.
How can I help you explore Laravel packages today?