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

Translatable Laravel Package

brackets/translatable

brackets/translatable adds translation support to Laravel Eloquent models, letting you store and retrieve translatable attributes per locale without duplicating schema columns. A small, focused package for building multilingual apps on familiar Eloquent workflows.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

brackets/translatable follows the trait-plus-JSON-column pattern: a Translatable trait on Eloquent models, with each translatable attribute stored as a JSON object of {locale: value} in a single database column. This is a natural fit for a conventional Laravel monolith — no extra tables, no joins, no polymorphic translation records. It keeps the domain model flat and reads like normal Eloquent ($model->title, $model->translate('nl')->title). For a content-light product (marketing pages, category names, short copy) this is the lowest-friction shape available.

The trade-off is baked into the architecture: locale data is opaque to the relational layer. Anything requiring per-locale indexing, locale-scoped uniqueness, or relational integrity across translations will need generated columns or denormalization. It is also a content translation tool, not an interface localization tool — it does not replace Laravel's lang files.

Integration feasibility

Integration is genuinely small: composer require, publish the config (locale list, fallback), add the trait, cast the columns to json/array, and the API is live. A competent Laravel developer should complete a proof of concept in under a day and a first production model in two to three days including tests. The cost is not in the wiring; it is in the data migration and the decision to store translations this way permanently.

The real feasibility question is fit against alternatives the team already knows: spatie/laravel-translatable uses the same JSON-column model with orders of magnitude more adoption and active maintenance, and astrotomic/laravel-translatable uses a dedicated translations table with better query ergonomics at higher schema cost. Choosing this package over Spatie is only defensible if there is a specific behavioural difference you need — and that difference should be documented before adoption, not discovered mid-build.

Technical risk

This is the dominant concern. Eight stars, zero dependents, and a last release in October 2023 means effectively no external validation and no community safety net. The maintainer is an agency (BRACKETS by TRIAD) publishing an internal utility; there is no signal of a support commitment, and a package that has not shipped since 2023 is unlikely to have been validated against Laravel 11/12 and PHP 8.3+. Risk profile is high on two axes: abandonment (no one to fix a break) and correctness (untested edge cases in fallback logic, casting, and mass assignment go unnoticed when nobody else uses the code).

Mitigations exist — fork it, vendor it, pin it — but each converts a dependency into an owned asset, which changes the business case from "adopt a package" to "adopt a small codebase."

Key questions

  • What Laravel and PHP versions are declared in composer.json, and does it install and pass tests on our target version today?
  • How does fallback behave — silent substitution of the default locale, explicit null, or exception? Does that match our content and SEO requirements?
  • Are there query scopes for locale-filtered retrieval, and what SQL do they generate on MySQL and PostgreSQL?
  • Is there a supported path for locale-aware search, or is that out of scope by design?
  • Who owns this code if it breaks, and what is the vendor's stated maintenance posture?
  • What is the migration story from our current single-language columns, and is it reversible?
  • Which specific capability does this provide that spatie/laravel-translatable does not?

Integration Approach

Stack fit

Compatible with a standard Laravel + Eloquent + MySQL 5.7+/PostgreSQL stack. Requires JSON column support and a Laravel version within the package's constraint — verify this first, as it is the most likely hard blocker. No queue, cache, or service-provider complexity; it is a model-layer concern only.

Migration path

Three viable paths, in order of preference:

  1. Greenfield content types only. Apply the trait to new models, leave existing tables untouched. Lowest risk, immediate value, no backfill.
  2. Additive columns. Add JSON columns alongside existing scalar columns, dual-write during a transition window, backfill via a queued job that wraps current values as {default_locale: value}, then read exclusively from the JSON column and drop the old ones after a soak period.
  3. From Spatie. Near drop-in if the storage shape matches; validate accessor/mutator semantics and fallback behaviour before swapping, since silent differences here corrupt content on read.

Avoid migrating an entire content estate in one release. Column-level cutover per model, behind a feature flag, keeps rollback to a config change.

Compatibility

Test explicitly on the target DB driver: JSON path operators differ between MySQL and PostgreSQL, and any whereJsonContains usage needs verification. Confirm the package's casting interacts cleanly with existing $casts, $fillable, validation rules, and API resources — translation-aware validation (required per locale) is usually the first gap a team hits.

Sequencing

  1. Spike: install on a branch, instrument a throwaway model, and record the fallback and query behaviour. Timebox to two days.
  2. Decision gate: compare the spike against Spatie on the same model; adopt this package only if it wins on something concrete.
  3. Isolate: one low-traffic content model in production, with tests covering read, write, fallback, and locale switch.
  4. Backfill and expand model by model.
  5. Document the convention — locale list, fallback policy, and who owns the fork — before the second model adopts it.

Operational Impact

Maintenance

Expect to own this. Pin the version, commit the lockfile, and assume no upstream fixes. Budget a small recurring allowance — a few hours per quarter — to verify the package against Laravel upgrades and apply patches locally. If the team cannot commit that, the honest recommendation is to use a package with a maintained community instead; the cost of a fork is small but it is not zero.

Support

No community, no issue-tracker velocity, no documented SLA. Support is whatever relationship exists with the vendor, and for an eight-star package that relationship is the deciding factor. Escalation for a production bug is internal engineering, not vendor.

Scaling

Reads are cheap: translations arrive with the row, so no joins and no N+1. This is a genuine advantage over table-per-translation designs at high read volume. Writes are fine at normal CMS throughput. The scaling cliff is querying: locale-filtered search and sorting over JSON require generated columns and indexes, which must be designed deliberately. Full-text search across locales should be handled by an external index, not by JSON operators on a large table. Caching translated content per locale is straightforward but needs locale in the cache key — a common and quiet source of cross-language bugs.

Failure modes

  • Fallback drift — missing translations silently rendering the default locale in a production UI or sitemap.
  • Malformed JSON — direct DB writes or legacy imports producing values the cast cannot hydrate, causing hard model failures.
  • Cross-locale cache bleed — cache keys omitting the locale.
  • Search gaps — locale-scoped queries returning incomplete results with no error surfaced.
  • Upgrade breakage — a Laravel major release with no upstream patch and no local fork readiness.
  • Migration partial failure — dual-write divergence between old scalar and new JSON columns during backfill.

Ramp-up

Very low. Any Laravel developer is productive within an hour; the API surface is a trait plus a translate helper. The onboarding cost sits with the policy — which locales exist, what the fallback is, how editors enter translations, and how missing translations are surfaced — not with the code. Document those decisions in the repo before the second model adopts the trait, or locale handling will diverge team by team.

Assessment summary: technically low-cost and architecturally reasonable, but commercially unsupported and externally unvalidated. Adopt only for greenfield content types, only after a timeboxed spike against spatie/laravel-translatable, and only with explicit acceptance that the package becomes an internally owned asset.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core