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

Json Laravel Package

laragear/json

Laragear/Json makes JSON columns in Laravel easy to work with: cast attributes to typed objects, validate nested data, query values cleanly, and keep Eloquent models tidy. A lightweight toolkit for structured, schema-friendly JSON storage.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a major release (v4.0.0), so treat it as a fresh install rather than an in-place bump until you have read the changelog at the link in the release notes.

composer require laragear/json

Laravel's package auto-discovery registers the service provider; there is typically nothing to publish for basic use. Confirm in the README whether v4 adds a publishable config (php artisan vendor:publish --tag=...) — if it does, publish it early so config defaults are explicit in your repo.

Where to look first

  1. The README usage section — it is the fastest path to the v4 entry points (factory/helper, casts, and the fluent Json object).
  2. src/Json.php (or equivalent core class) — the public methods are your real API surface: get, set, has, forget, all, toArray, toJson.
  3. The casts directory — this is how the package integrates with Eloquent models, which is where most day-to-day value lives.

First use case: a JSON column on an Eloquent model

use Illuminate\Database\Eloquent\Model;

class Account extends Model
{
    protected $casts = [
        'settings' => \Laragear\Json\Casts\AsJson::class, // confirm exact cast name in README
    ];
}

$account->settings->get('notifications.email');
$account->settings->set('notifications.email', false);
$account->save();

The point of the package is that settings is no longer a raw array you index into — it is a fluent object with dot-notation reads and writes, so nested updates stop being a mess of Arr::get / data_set.

Second use case: normalising an API payload

$json = json($request->input('payload')); // or the factory shown in the README

$json->get('user.profile.name');
$json->has('user.profile.address');
$json->forget('user.password');

Start with one JSON column or one inbound payload and expand from there; the package does not need to own every array in your application to be useful.

Implementation Patterns

Cast JSON columns, then mutate nested paths

The highest-leverage pattern is the Eloquent cast. Replace array casts on structured columns with the package's JSON cast so that reads and writes are path-aware:

protected $casts = [
    'settings' => AsJson::class,
];

// read
$theme = $account->settings->get('ui.theme', 'light');

// write
$account->settings->set('ui.theme', 'dark');
$account->save();

If the cast is immutable, always assign the result back ($account->settings = $account->settings->set(...)) — see the Gotchas section.

Wrap request payloads at the boundary

Convert inbound array/string JSON into the package object in a form request or controller, then pass the object down instead of a loose array. This gives downstream code one consistent accessor style and removes repeated Arr::get calls.

$payload = json($request->validated('payload'));

$payload->has('items.*.sku'); // wildcard checks, if supported in v4

Validation and normalisation pipeline

Use the object after validation, not instead of it. Validate the structure with Laravel rules, then use the JSON object to normalise defaults and strip sensitive keys before persisting:

$data = json($validated);
$data->set('meta.created_at', now()->toIso8601String());
$data->forget('meta.internal_flags');

Build API responses fluently

For endpoints that assemble a response from several sources, build the envelope with the JSON object and let it serialise:

return response()->json(
    json(['data' => $resource])->set('meta.version', 'v2')
);

Compose with Eloquent accessors and resources

A clean integration is to keep the cast on the model and expose a typed accessor:

public function notificationEmail(): ?string
{
    return $this->settings->get('notifications.email');
}

This keeps dot-notation strings out of your controllers and views.

Use it for configuration-shaped data inside a single column

Feature flags, per-tenant preferences, and webhook payload snapshots are the sweet spot: deep nesting, frequent partial updates, and a need to read a single path without hydrating the whole structure.

Testing pattern

Assert on the serialised form rather than on internal state:

$this->assertSame('dark', $account->fresh()->settings->get('ui.theme'));
$this->assertJsonPath('meta.version', 'v2', $response->json());

Gotchas and Tips

v4.0.0 is a major bump — audit before upgrading. The release notes only link to the full changelog, so open https://github.com/Laragear/Json/compare/v3.0.0...v4.0.0 and look specifically for renamed classes, changed cast names, removed methods, and signature changes. Pin v3 in composer.json if you need time to migrate. Run your JSON-column test suite immediately after the upgrade; cast changes fail loudly only when a model is hydrated, so a green suite that never touches those models proves nothing.

Immutability will bite you. If the package exposes an immutable variant (or if v4 makes the default object immutable), $model->settings->set(...) can silently do nothing to the persisted model. Always check whether set returns a new instance and assign it back:

$account->settings = $account->settings->set('ui.theme', 'dark');
$account->save();

A missing save() after a mutating call is the single most common source of "my JSON column isn't updating" bugs.

Dot notation vs literal dots. If any of your JSON keys legitimately contain a ., dot-path access will misread them. Escape or avoid such keys; do not assume the package distinguishes them.

Type coercion at the boundary. JSON round-trips turn integers into floats in some encoders and turn empty objects into arrays. If a downstream consumer expects {} vs [], assert on the serialised output, not on toArray().

Encoding flags. If you need unescaped Unicode or preserved zero fractions, check how the package encodes. json_encode flags are easy to lose when you move data through a wrapper; verify with a payload containing accented characters and 1.0.

Avoid re-wrapping in loops. Building a fresh JSON object per iteration over thousands of rows is measurably slower than mutating one object and serialising once. For bulk exports, collect arrays and cast once at the end.

Debugging. dd($json) can be unreadable because the object proxies array access. Reach for $json->toJson() or $json->toArray() when dumping in a test or Tinker, and assert against the decoded array in tests so failures are diffable.

Extension points. Check the README for macros and custom casts. If you need application-specific accessors, a macro (Json::macro('tenant', ...)) keeps that logic reusable without forking the package.

Watch the cast name. Package majors sometimes rename casts (e.g. an AsJson vs AsJsonObject split). A wrong cast class name in $casts throws at model hydration time, which surfaces far from the line you edited — grep your models for the old class name after upgrading.

Laravel version support. Major package releases often bump the minimum Laravel/PHP version. Check composer.json constraints in the package before upgrading; a failed composer update is usually a PHP constraint, not a bug.

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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager