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

Nova Trumbowyg Field Laravel Package

outl1ne/nova-trumbowyg-field

An Outl1ne Laravel Nova field that brings the lightweight Trumbowyg WYSIWYG editor into your admin resources. Add a clean, customizable rich-text input for editing HTML content without the weight of larger editor packages. Simple to install and use in Nova forms.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

The package is a single-purpose Nova field: a thin PHP class (src/NovaTrumbowygField.php) that serializes a JSON-safe options array to a Vue component, plus compiled Trumbowyg JS/CSS in dist/. It inherits Nova's standard text resolution and fill behavior, so it drops onto any TEXT/LONGTEXT column with no schema change, no migration, and no publish step (service provider is auto-discovered).

From a TPM standpoint this is the right shape for the requirement: it is a configuration lever, not a subsystem. It does not introduce a content model, an API surface, or a storage abstraction. That means the durable asset is the HTML in the column, and the package is replaceable — which is what keeps the long-term risk bounded even though the package itself is thinly maintained.

The one architectural decision the package forces on us is the reintroduction of jQuery into an otherwise jQuery-free Nova 4/5 (Vue 3) frontend bundle. That is a real, if contained, coupling.

Integration feasibility

Low effort, high confidence on the happy path. Install via Composer, reference the field on a resource, validate the create → save → reload round-trip. The recommended pattern — a RichText base field class in App\Nova\Fields that centralizes btns, semantic, resetCss, height, and default rules — keeps resources declarative and gives us a single place to change toolbar policy. Extension should stay in our subclass plus our own Vue overrides, never in vendor/.

Feasibility caveats worth surfacing before commitment:

  • The README may lag the code on the option-passing API (->options([...]) vs. dedicated helpers). A developer must read the class itself rather than trust documentation.
  • Options must be primitives and arrays — closures, models, or Carbon in the options array fail silently or throw.
  • Image upload is callback-based in Trumbowyg, so enabling it means we own storage, URL generation, delete handling, and likely a Nova route plus custom JS.

Technical risk

Risk Severity Mitigation
Bus factor 1 — 6 stars, 0 dependents, unverified release cadence High Pin 2.0.*; budget a bounded fork into a private package
XSS — field stores whatever HTML it receives High Server-side sanitizer (HTMLPurifier/mews/purifier) on write, plus render-side discipline
Silent mount failure after Nova upgrade Medium CI/post-deploy smoke check asserting the editor container mounts
jQuery collision with other Nova add-ons Medium Console watch for $/jQuery conflicts; pin/alias if needed
CSP blocking inline init / unsafe-eval Medium Test behind the admin CSP before rollout
Asset/provider not discovered on --no-dev deploy Medium php artisan package:discover in deploy checklist; lockfile check
Feature ceiling (no collaboration, media library, structured blocks) Low now Accept explicitly as a tactical bridge; HTML is the cheap migration path

The material risks are ownership and sanitization — both are engineering-scoped and well understood, not open research questions. The unverified release date in the listing should be reconciled against actual tags before we pin a constraint; "released 2026-06-10" is a signal to check, not a fact to rely on.

Key questions

  1. Which Nova major(s) are we on, and does the package's composer.json constraint actually cover it?
  2. Who owns the package long-term — a named engineer accountable for upgrades and a fork decision, or is it orphaned after rollout?
  3. What is the allowed-tag policy for authored HTML, and where does the sanitizer run (observer, mutator, or request layer)?
  4. Are translatable columns in scope (spatie/laravel-translatable with content->{locale}), and does resolveUsing/fillUsing behave correctly on our Nova version?
  5. Do we need image upload, tables, or color plugins — each adds bundle weight, jQuery surface, and CSP risk?
  6. Does any existing Nova add-on already bundle jQuery?
  7. Is the admin surface internal-only? If any of this content is customer-visible, accessibility and output quality become gating.

Integration Approach

Stack fit

Laravel + Nova, PHP-side only, Composer-distributed, MIT. It fits the existing toolchain with zero new infrastructure and no external service dependency. The only friction points are frontend-environmental: jQuery reintroduction, CSP, and dark-mode styling against Trumbowyg's light-theme CSS.

It fits cleanly if and only if Nova is a settled platform decision. Because the field runs exclusively inside Nova, adopting it is a small implicit reaffirmation of that layer. If the team is concurrently evaluating Filament or a custom admin, that conversation should be closed first — a field package must not anchor an admin-panel decision.

Migration path

  • Greenfield: point the field at an existing TEXT/LONGTEXT column. No migration, no backfill.
  • From Textarea: swap the field declaration; existing plain-text rows render as unstyled text in the editor. Acceptable for most cases.
  • From Markdown or plain text with formatting intent: run a one-off job to convert to HTML before cutover, otherwise authors lose formatting affordances on legacy rows.
  • Forward path off the package: because the stored content model is plain HTML, migrating to a TipTap/ProseMirror-based field or a headless CMS later is a re-render exercise, not a data remodelling exercise. This is the single strongest argument for the package and should be stated in the decision record.

Compatibility

Verify against the installed Nova major before pinning; the failure mode of a mismatch is silent (blank field or uninitialized textarea), not a loud exception. Confirm jQuery has no conflicts, confirm the admin CSP permits the editor's init path, and add a small dark-mode override stylesheet in Nova assets rather than patching package CSS. For per-locale content, render one editor per configured locale using the content->{locale} attribute path and confirm resolution behavior against our Nova version.

Sequencing

  1. Spike on one low-traffic resource in a branch; verify install, provider discovery, and render.
  2. Round-trip smoke test — create bold/links/lists, save, reload, confirm exact HTML repopulates. Also test paste-from-Word. This single test catches most integration defects.
  3. Sanitization pipeline — stand up HTMLPurifier with an explicit allowed-tag policy in the model's saving hook or an observer. Do not defer this.
  4. Backfill legacy markdown/plain-text rows if formatting matters to authors.
  5. Pilot with one internal content team on one or two resources.
  6. Roll out resource-by-resource, documenting the fallback (native Text/Textarea) and the one-line rollback.
  7. Guardrail in CI — assert the editor mounts on an edit page so a Nova bump cannot degrade authoring silently.

Deliberately defer plugins (colors, table, upload, paste) until a specific requirement justifies the added bundle weight and CSP surface.


Operational Impact

Maintenance

This is the dominant operational cost, and it is organizational rather than technical. With 6 stars, 0 dependents, and a single maintainer, we should assume we are the maintainer of last resort. That means: pin an explicit constraint (2.0.*), track upstream release cadence, and pre-agree a fork trigger — for example, "if upstream has not shipped a Nova-compatibility fix within 30 days of a Nova major, we fork into a private package." The fork itself is bounded and small: a field class plus a Vue component plus compiled assets. Assign a named owner and put the fork trigger in the decision record.

No publish step simplifies deploys, but it also means failure surfaces at runtime, not at build time — hence the CI mount check.

Support

MIT, no vendor, no SLA, no support contract. Internal support burden is "whoever owns the field." Document the debug checklist in the runbook so on-call does not rediscover it:

  1. Network tab — did Trumbowyg JS/CSS load?
  2. Console — jQuery conflict or CSP violation?
  3. DOM — textarea present but uninitialized (options serialization failure)?
  4. php artisan package:discover — provider registered?
  5. Lockfile — Nova major vs. package constraint?

Scaling

Two dimensions:

  • Content volume and search. Rich HTML inflates columns and pollutes full-text search with tag syntax. Maintain a derived body_text column (tags stripped at index time) or strip at query time. This is a schema decision to make at rollout, not after search quality complaints.
  • Authoring sophistication. The package does not scale into collaborative editing, reusable content blocks, media libraries, or structured content modelling. When content operations become strategic — multi-channel publishing, localization at scale, editorial governance — this field is the wrong foundation and a deliberate migration is the right call. Because storage is plain HTML, that migration is cheap; keep it framed that way in roadmap conversations.

Failure modes

Symptom Likely cause Blast radius
Editor renders as plain textarea Provider not discovered (--no-dev deploy) or assets not served Authoring degraded, no data loss
Blank field, no error Nova upgrade broke component mount; or options serialization failure Silent, dangerous — needs CI guard
Toolbar button missing Malformed btns options or plugin not enabled Cosmetic
Editor broken intermittently across resources jQuery version collision with another Nova add-on Cross-feature, hard to diagnose
Editor won't initialize behind admin CSP Inline init / unsafe-eval blocked Environment-specific; staging may pass, prod fail
Stored XSS on public render No server-side sanitizer Security incident — the one failure that matters

The critical asymmetry: cosmetic and mount failures are recoverable and visible to authors; unsanitized HTML is silent until exploited. Sanitization is non-negotiable and belongs in the same release as the field, not a follow-up ticket.

Ramp-up

Low for anyone who has touched Nova. The field is a one-liner; the real onboarding is two conventions — centralize configuration in a base field class, and never edit vendor/. Budget roughly half a day for a Nova-fluent developer to complete spike, round-trip validation, and sanitizer wiring; add time for translatable columns or image upload if in scope. Non-technical ramp-up for authors is near-zero: it's a familiar toolbar.

The documentation gap (README lagging the code) is a minor onboarding tax — mitigate by having the first implementer write a short internal README covering the actual option API, the sanitizer policy, and the debug checklist. That artifact is worth more than the package's own docs and survives a fork.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle