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

armincms/json

A Laravel package that simplifies working with JSON data in Eloquent models. Fluent helpers let you read, write, query, and cast JSON columns, making nested structures and dynamic attributes easier to manage throughout your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Gate on compatibility before you install anything. The last release was June 2020 — Nova 2/3, Laravel 6/7, PHP 7.x territory. A current stack (Nova 4/5, PHP 8.1+) will most likely fail resolution outright:

composer require armincms/json --dry-run
composer why-not armincms/json

If Composer refuses to resolve, stop treating this as a dependency and treat it as source material — read the Gotchas section before you spend an afternoon fighting it.

Install and publish the front end. A Nova field is a PHP class plus a compiled Vue component. If the asset never publishes, you get a blank cell or a bare textarea:

composer require armincms/json
php artisan vendor:publish --tag=nova-assets   # confirm the actual tag in src/

Look inside src/ for the service provider — the README is thin and the publish tag is defined there, not documented.

Read the field class before writing a single resource. You need three facts from the source:

  1. The exact FQCN (Armincms\Json\Json vs something else — don't guess).
  2. What it extends (Field vs Text — this determines rules(), resolveUsing(), etc.).
  3. How it writes to the model: raw request string, decode-aware, or cast-aware.

That one read saves an hour of "renders but doesn't save" debugging later.

First use case: one low-risk resource on a branch. Point it at a settings or metadata JSON column, save, reload, and inspect the raw column value in tinker. Confirm the round-trip and the storage format (double-encoded string vs object) before touching anything real. This is the whole spike — a few hours, not a sprint.

Implementation Patterns

Basic wiring.

// app/Nova/Setting.php
use Armincms\Json\Json;   // confirm FQCN from src/

public function fields(Request $request)
{
    return [
        Json::make('Payload')
            ->rules(['required', 'json', 'max:65535'])
            ->help('Arbitrary JSON. Validated before save.'),
    ];
}

Decide the cast strategy first — this is the pattern that matters. If the model declares protected $casts = ['payload' => 'array'] and the field writes a JSON string, you can double-encode. Pick one of:

  • No cast on the model — column stores the string the field produced. Simplest, matches what the field was likely designed for.
  • array cast — but only if the field's write path is cast-aware (check the source). Otherwise wrap the field.

Verify after a save, on both create and update paths:

$setting->refresh()->payload;                                  // what the model sees
DB::table('settings')->where('id', $setting->id)->value('payload'); // what's actually stored

Wrap it in your own field class. Even if you install the package directly, subclass it so upgrades and fixes have a single seam:

namespace App\Nova\Fields;

class JsonEditor extends \Armincms\Json\Json
{
    public function rules()
    {
        return array_merge(parent::rules(), ['json', 'max:65535']);
    }
}

Now a Nova upgrade, a fork, or a full replacement is one file, not every resource.

Enforce schema server-side. The field is a text box; it does not validate your domain. json catches syntax errors. For a bounded shape, add a custom rule:

Json::make('Payload')->rules([new ValidSettingsSchema()])

Scope authorization — the field is not a security boundary. Restrict visibility/editing and mirror it in the policy:

Json::make('Payload')
    ->canSee(fn ($request) => $request->user()->isOperator())
    ->canEdit(fn ($request) => $request->user()->isOperator());

Escape on the way out. The field only gets you into the column; every consumer is a separate XSS decision. {{ $setting->payload }} is safe; {!! json_encode(...) !!} over user-entered content is not.

Instrument during the spike. resolveUsing / fillUsing let you log what the field reads and writes — invaluable for cast bugs:

Json::make('Payload')
    ->resolveUsing(fn ($v) => tap($v, fn ($x) => logger('json read', ['v' => $x])))
    ->fillUsing(fn ($req, $model, $attr, $reqAttr) =>
        $model->{$attr} = $req->input($reqAttr));

(Signature varies by Nova major — verify against your version.)

Gotchas and Tips

  • Composer constraint conflicts are the most likely failure. An abandoned field usually pins old Nova/PHP versions. If you override constraints, watch for render-time breakage — Nova 4 moved the field layer to Vue 3, so a PHP-compatible override can still fail in the browser.
  • Blank field / fallback textarea almost always means assets weren't published, or you're on a Nova major whose component contract no longer matches.
  • Silent malformed writes are the worst failure mode. A raw editor passes the string straight through. Without a json rule plus schema validation, semantically wrong JSON persists quietly and breaks every downstream reader — backfill territory.
  • "Renders but doesn't persist" is a cast/attribute mismatch, not a broken package. Check whether ->make('Payload') matches an actual column and whether the cast is eating the value. Log with fillUsing to confirm the request arrives.
  • Double-encoding with array casts is the single most common data bug with fields like this. Test create and update, and inspect the raw column, not the hydrated property.
  • Stored XSS via {!! !!} on admin-entered JSON is real. Audit every consumer, not just the field.
  • Description claims to verify: dot-notation access, change tracking, cast handling are all in the package blurb. Read src/ and confirm — if they're not there, implement them as model accessors/mutators and stop relying on the field for anything but editing.
  • Fork with discipline. With 0 dependents and no releases since 2020, assume zero upstream fixes. Vendor into an internal namespace (e.g. internal/nova-json-field) via a VCS repository entry, keep the MIT attribution, and name an owner. An unowned fork fails silently during a Nova upgrade and becomes a mid-migration blocker.
  • Budget the front-end skill. Fixing a Vue component is a narrower skill than backend Laravel. If nobody owns that half, accept in writing that the fork only ever gets backend patches.
  • Bound the payload. Large JSON blobs make Nova pages heavy and are miserable to edit. Enforce a max: rule and a "one sub-document, not a whole config tree" convention.
  • Don't use it for customer-facing config, anything needing audit trails, or anything where a silent bad write is expensive to unwind. This is internal-ops tooling, full stop.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
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