Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Jodit Laravel Package

nasirkhan/laravel-jodit

Laravel Jodit integrates the Jodit WYSIWYG editor through one reusable Blade component, working in plain Blade templates, view components, and Livewire. Includes a bundled file browser and uploader, CDN assets, and a publishable config.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. nasirkhan/laravel-jodit is a thin presentation-layer wrapper, not a content platform. The architecture is a Blade anonymous component that renders a <textarea> plus Jodit initialisation JS, backed by an optional connector controller for file browse/upload. It is framework-native (service provider auto-discovery, publishable config, asset stacks, route registration) and imposes no persistence model, no migrations, no content schema, and no opinion on how HTML is stored or sanitised. That is the right shape for a package in this class: it slots into existing form request → validation → Eloquent save flows without touching them. It is a poor fit only where the frontend is not Blade-rendered (Inertia/Vue/React SPA surfaces), since the integration vector is a server-rendered component and Livewire's wire-model.

Integration feasibility. High for a standard Laravel 11/12/13 monolith on PHP 8.2+. The surface area is one component tag, two optional props (wire-model, connector-url), and a config file. The Livewire path is handled explicitly — the wrapper is set to wire:ignore to survive DOM diffing, with a 300 ms debounced JS flush back to the component. Two prerequisite couplings to validate up front: the layout must emit @stack('after-styles') and @stack('after-scripts') (or these must be renamed in config), and the connector route is registered by default with ['web', 'auth'] middleware. Both are cheap to confirm in a spike but are silent-failure modes if missed — no stack means no assets and no editor, with no error surfaced.

Technical risk. The dominant risks are not in the Blade wiring; they are in the connector and the asset delivery path.

  • Upload security is the primary exposure. Defaults allow svg in allowed_mimes against the public disk, with max_file_size at 10 MB. SVG is an active-content format and a well-known stored-XSS vector when served same-origin from a public path. There is no documented per-user or per-tenant path isolation, no documented re-encoding pass on images, no malware scanning, and no documented base_path traversal hardening. Route::any on the connector is broader than the protocol requires and ships without throttling by default. Treat the built-in connector as a convenience, not a hardened upload surface.
  • Content sanitisation is out of scope by design. The package stores and round-trips arbitrary editor HTML. Any UGC or low-privilege-author use case requires an independent server-side sanitiser (HTMLPurifier-class allowlist) in the ingest path. This is the single largest gap between "demo works" and "production safe."
  • CDN-hosted assets. Pinning Jodit 4.1.16 to unpkg is simple and removes a build step, but introduces an external runtime dependency on every page with an editor: availability, latency, CSP script-src/style-src allowlisting, supply-chain trust in the pin, and offline/air-gapped infeasibility. No Subresource Integrity is documented. Mitigation is to self-host the two URLs via config, which is supported but must be an explicit decision, not a default.
  • Hard dependency on intervention/image ^4.0. A substantive transitive dependency pulled in solely for resize/crop. It brings GD/Imagick build requirements into the container image and a major-version upgrade obligation. If the team already standardises on a different image pipeline, this is duplicated capability.
  • Livewire sync semantics. Debounced JS flush plus wire:ignore means there is a real window where editor content is not yet in the Livewire property. A submit or navigation inside the debounce interval can persist stale content. Verify the component's flush-on-submit behaviour before trusting it in high-stakes forms; a plain Blade submit with the underlying textarea is materially safer.
  • Supply-chain and maturity signals. 2 stars, 0 dependents, one maintainer (the author of Laravel Starter), documentation limited to the README, and no evidence of a test suite beyond a lint badge and a CI workflow added at v1.7.0. The v2.0.0 release notes describe only README and error-message changes — a major version bump for documentation signals loose semver discipline, which means "minor" releases are not reliably non-breaking. Bus factor is 1.

Key questions.

  1. Is the target use case trusted-author content (admin/CMS) or untrusted-user content? If the latter, what sanitiser owns the ingest path, and who signs off on the allowlist?
  2. Will we run the built-in connector or register it ourselves under an admin prefix with our own middleware, throttling, and a non-public disk?
  3. Self-hosted Jodit assets or CDN — and if CDN, do we have script-src policy and SRI in place?
  4. Does the Livewire path guarantee a flush before form submit, or do we need an explicit wire:model-adjacent hidden field fallback?
  5. Who is the named owner for this integration, and what is the fork-and-maintain trigger if the upstream maintainer goes dormant?
  6. Is intervention/image v4 already in our dependency tree, or are we accepting a new image-processing contract for resize/crop alone?

Integration Approach

Stack fit. Best fit: Laravel monolith, Blade-first views, Livewire for interactive forms, standard session auth. Acceptable fit: Blade-only apps with no Livewire (use the plain :value path). Poor fit: API-only services, Inertia/SPA frontends, or multi-guard/multi-tenant apps where the default auth middleware on the connector resolves to the wrong guard — that must be overridden regardless.

Migration path. Content is portable in both directions. Jodit emits HTML into a textarea, so migrating from TinyMCE, CKEditor 4/5, Summernote, or Trumbowyg is a swap of the editor shell around the same stored field; no content rewrite is required in the common case, though editor-specific artefacts (custom embeds, shortcodes, inline style conventions) will render differently and need a sampling audit. Migrating away later is equally low-cost, which is the main argument for accepting the maturity risk: the blast radius of replacement is one component and one config file. The non-portable surface is uploaded media — those live on whatever disk base_path points to, so plan a storage layout and a URL strategy that survives a future editor swap (stable, non-Jodit-specific paths).

Compatibility. Confirm three things before committing: PHP 8.2+ and Laravel 11/12/13 in the target app; the layout's asset stacks match after-styles/after-scripts or the config is overridden; and the container can satisfy intervention/image v4 (GD or Imagick extension, memory limits adequate for image resize during request handling). Watch the semver signal — pin to an exact version in composer.json rather than floating a caret range, and review each upstream release diff rather than trusting the version number.

Sequencing.

  1. Spike (1–2 days). Install in a branch, publish config, render one editor in a non-critical admin form, verify asset stacks, verify plain-Blade submit round-trips HTML, verify Livewire wire-model sync and the submit-race behaviour.
  2. Harden the connector before any second use. Disable the package route (route.enabled => false), register JoditConnectorController behind the admin prefix with explicit middleware, add throttling, move to a private/non-web-root disk with a signed-URL or controller-served read path, drop svg from allowed_mimes unless there is a documented need and a serving strategy that neutralises it, and reduce max_file_size to the actual product requirement.
  3. Own the asset delivery. Self-host the two pinned Jodit files, or accept CDN with SRI and a documented CSP change. This is a one-line config change; make it a decision record, not a default inherited from the README.
  4. Add the sanitiser at ingest. Server-side allowlist sanitisation on save and, if the content is displayed to other users, on render. This belongs to the consuming app, not the package — budget it explicitly.
  5. Pilot one form, then broaden. Roll out to admin-authored content first; hold UGC or public-facing authored content until the sanitiser and upload hardening are proven in review.
  6. Instrument the exit. Document the fork-and-maintain procedure and the replacement candidates (self-hosted Jodit without the wrapper, or a maintained alternative) so the team is never blocked on upstream.

Operational Impact

Maintenance. Low steady-state effort, with two recurring obligations. First, Jodit version currency: the editor version is a config string, which makes upgrades trivial but also easy to leave stale — schedule a periodic review of the pinned version and upstream CVEs. Second, composer constraint hygiene: given the imprecise semver observed, exact-pin and review release diffs. The consuming team owns everything the package deliberately does not provide — sanitisation, upload hardening, storage lifecycle and retention, and any cleanup of orphaned media when content is deleted. Assume no upstream support SLA.

Support. Effectively none. Single maintainer, 2 stars, 0 dependents, README-only documentation, no community channel of consequence. Escalation path is reading the source and forking under MIT. That is acceptable for a small, self-contained Blade component — the code volume is small enough to own — but it must be a conscious acceptance, not a surprise. Name an internal owner.

Scaling. The editor itself is client-side and scales trivially. The connector does not: uploads and any resize/crop work execute synchronously inside the PHP request cycle, so large images or concurrent uploads translate directly into worker occupancy and memory pressure. There is no queueing, no async processing, and no CDN offload documented. Mitigations in order of preference: cap max_file_size tightly, raise proxy client_max_body_size in step with it (a mismatch here produces opaque 413s), offload reads to a CDN or object store, and move image transcoding out of the request path if upload volume is material. Multi-tenant deployments should treat media isolation as an app-level concern the package does not solve.

Failure modes. Ranked by likelihood and blast radius:

  • Missing asset stacks — component renders, editor silently never initialises, authors see a bare textarea. Cheap to detect, easy to ship past in code review. Add a smoke assertion.
  • CDN unavailable or blocked by CSP — same silent degradation, potentially across every editing page at once. Self-hosting converts this into a deploy-time problem.
  • Debounce race in Livewire — content submitted within 300 ms of the last keystroke may persist stale. Highest data-loss risk in the set; verify explicitly or keep high-value forms on the plain-Blade submit path.
  • Upload rejections — size/mime mismatches between proxy, PHP upload_max_filesize, and package max_file_size produce failures that read as generic editor errors. Align the three and surface the real message.
  • Storage misconfiguration — wrong disk, unwritable path, or a public symlink not created: uploads appear to succeed or fail inconsistently; media links break after content is saved.
  • Stored XSS via SVG or unsanitised HTML — the low-probability, high-severity case. This is the failure that turns a convenience decision into an incident; the mitigations in Integration Approach steps 2 and 4 are the control.

Ramp-up. Developer ramp-up is genuinely small — one tag, one config file, a documented prop table and button reference. An engineer unfamiliar with the package is productive in under a day. The real ramp-up cost sits with security and platform review, not with the developers: the connector hardening, sanitiser selection, asset-hosting decision, and CSP change each require a reviewer who understands the exposure. Budget that review as part of adoption rather than discovering it at launch. Overall verdict: a reasonable, low-coupling choice for trusted-author content in a Blade/Livewire Laravel app, on the explicit condition that the upload and sanitisation surfaces are hardened by the consuming team and a single internal owner is named.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log