JSON & YAML Editor plugin screenshot
Dark mode ready
Multilingual support
Supports v5.x

JSON & YAML Editor by asign

Community

JSON and YAML editors with code and tree modes, live validation, JSON Schema rules and highlighted infolist entries.

Tags: Forms Form Field Infolist Entry
Supported versions:
5.x
asign avatar Author: asign

Package health

Automated checks of this plugin's Composer package

100 / 100
Security 100
Maintenance 100
Ecosystem 100
15 checks
  • Passed: GitHub Actions pinned to SHA
  • Skipped: GitLab CI includes pinned to SHA
  • Passed: Open security advisories
  • Passed: Dependabot PR responsiveness — No stale Dependabot PRs.
  • Skipped: Renovate MR responsiveness
  • Passed: Dependabot or Renovate configured
  • Passed: Dependency update cooldown configured
  • Passed: Provides a security policy
  • Passed: Abandoned or archived — No consulted source marks the package abandoned (packagist, github).
  • Passed: Commit and release recency — Active: last commit 0 days ago; last release 0 days ago.
  • Passed: composer.lock not committed by library — composer.lock is absent from the released dist archive.
  • Passed: Dist archive is lean
  • Passed: Current Laravel version supported — Package dependencies resolve together with current Laravel 13.0.
  • Passed: Current PHP version supported — Constraint ^8.3 supports current PHP 8.5.
  • Passed: Current Symfony version supported — Package dependencies resolve together with current Symfony 8.1.
Third-party plugin. This is built by the community, not the Filament team. Filament does not review, endorse, or vet the security of plugins outside the filament/ namespace. Review the source and install at your own risk. Found malware or an unresolved security issue the author won't address? Report it .
Powered by Plumb Last scanned 12 hours ago

Documentation

Stand With Ukraine Latest Version on Packagist Tests Total Downloads License Plumb score

Filament JSON & YAML Editor

JSON and YAML editing for Filament 5: two form fields and two infolist entries.

Filament 5 ships a CodeEditor, but it is a plain text editor: no tree view, no validation, no schema, no formatting. The popular Filament 3 plugin for this (invaders-xx/filament-jsoneditor) has no Filament 4/5 release, and YAML editing has had nothing at all.

  • JsonEditor: a code view (highlighting, line numbers, folding) and a tree view (expand / collapse, edit values, rename keys, change types, add and remove), live validation with the error line, a Format button, optional JSON Schema.

  • YamlEditor: the same code view with the YAML language and a live js-yaml lint that shows the error line.

  • JsonEntry / YamlEntry: read-only highlighted, collapsible blocks with a copy button, for infolists.

  • Server-side rules for all of it: JsonRule, YamlRule (symfony/yaml) and JsonSchemaRule.

  • Screenshots

  • Requirements

  • Installation

  • Usage

  • Configuration

  • Gotchas

  • Translations

  • AI agents

  • Testing

#Screenshots

JSON code view with highlighting and a Format button

JSON tree view with edit, add and remove

YAML editor with a lint error on the offending line

Dark mode

Read-only entries with collapse and copy

#Requirements

  • PHP 8.3+
  • Filament 5, Laravel 12 or 13
  • symfony/yaml and phiki/phiki (installed with the package)
  • Optional, for JsonSchemaRule: opis/json-schema (preferred) or justinrainbow/json-schema

#Installation

composer require asignua/filament-json-yaml-editor
php artisan filament:assets

Nothing to register on the panel. The editor bundle (CodeMirror 6, js-yaml, the tree view; about 475 kB minified, 160 kB gzipped, against ~985 kB for Filament's own code editor that bundles 13 languages) is an Alpine component loaded on request: a page without an editor never downloads it. A 5 kB stylesheet is registered with Filament's assets.

#Usage

use Asignua\FilamentJsonYamlEditor\Enums\EditorMode;
use Asignua\FilamentJsonYamlEditor\Forms\JsonEditor;
use Asignua\FilamentJsonYamlEditor\Forms\YamlEditor;

JsonEditor::make('settings')
    ->asArray()                                   // the model gets an array (for `array` / `json` casts)
    ->modes([EditorMode::Code, EditorMode::Tree]) // default; one mode hides the switch
    ->defaultMode(EditorMode::Tree)
    ->format()                                    // the "Format" button (on by default)
    ->indent(4)                                   // Format / tree / array display
    ->height('28rem')                             // or ->height(400) for pixels
    ->schema($jsonSchema);                        // server-side JSON Schema

YamlEditor::make('config')
    ->asArray()     // parse to an array on save; array from the model is dumped for display
    ->inline(4)     // Yaml::dump(): the level where it switches to {a: 1} flow style (default 10)
    ->indent(2)
    ->schema($jsonSchema); // the parsed document is checked against a JSON Schema

State is text by default: what the user typed is what the model gets, comments and formatting included. ->asArray() hands the model a decoded array instead. An array (a Collection, an ArrayObject, an object) coming from the model is always shown as text. Blank text is stored as null.

Without an explicit ->asArray() the field follows the model's cast: a column cast to array, json, object, collection, AsArrayObject or AsCollection (and their encrypted variants) gets an array, because handing such a cast the text would store a JSON string literal instead of an object. ->asArray(false) forces text (for a column without such a cast, or one whose cast takes text). Outside a model (a custom page, a nested ->statePath()) nothing is detected: pass ->asArray() yourself.

With ->asArray() an empty JSON object {} stays an object in both fields: it is stored as {} (an empty YAML map a: {} too, while a: [] is stored as []), and when the form is reopened the text is built from the stored column, not from the cast's arrays (which would turn it into []). This holds for the plain JSON casts; an encrypted cast stores ciphertext, so its {} is shown (and saved back) as []. A non-empty object whose keys are 0..n ({"0": "x", "1": "y"}, or YAML 0: x) is a list to PHP and is stored as ["x", "y"]. YAML timestamps stay strings (released: 2024-01-01 is stored as "2024-01-01", at: 2024-01-01T00:00:00Z as "2024-01-01T00:00:00+00:00"), not unix integers.

Integers beyond PHP_INT_MAX change type with ->asArray(). PHP cannot hold them as numbers, so {"id": 12345678901234567890} is stored as {"id": "12345678901234567890"}: the digits are kept, but from then on the value is a string — the editor shows it quoted and a ->schema() with type: integer rejects it. If they must stay numbers, keep the column as text: remove the array / json cast from the model attribute and leave ->asArray() off, so the text is stored as typed. Do not combine ->asArray(false) with a column that keeps its array cast: the cast would encode the text again and store a JSON string literal. Translatable attributes (spatie/laravel-translatable) are never switched to an array automatically.

Both fields are ordinary Filament fields: ->required(), ->disabled() (read-only editor), ->live(), ->columnSpanFull(), ... work as usual.

#Validation

The syntax rule is added automatically (->validateSyntax(false) turns it off; the in-browser lint stays). With ->asArray() the rule stays regardless: text that does not parse would otherwise be saved as null over the stored value. The rules are also usable on their own:

use Asignua\FilamentJsonYamlEditor\Rules\JsonRule;
use Asignua\FilamentJsonYamlEditor\Rules\JsonSchemaRule;
use Asignua\FilamentJsonYamlEditor\Rules\YamlRule;

$request->validate([
    'a' => ['nullable', JsonRule::make()->containerOnly()], // object or array only
    'b' => ['nullable', new YamlRule],
    'c' => ['nullable', JsonSchemaRule::make($schema)],       // array, JSON string or decoded object
    'd' => ['nullable', JsonSchemaRule::make($schema)->yaml()->maxErrors(3)],
]);

JsonSchemaRule needs opis/json-schema or justinrainbow/json-schema; with neither installed it throws a LogicException instead of silently passing. Syntax errors are JsonRule / YamlRule's job: the schema rule skips text it cannot parse. Client-side schema validation is deliberately not bundled (an engine would double the bundle). With justinrainbow/json-schema only $refs to the bundled draft meta-schemas resolve; remote and file:// references are refused (reported as a validation error) so that a schema coming from data cannot make the server fetch URLs or read files. opis/json-schema does not fetch unregistered URIs either.

#Infolist entries

use Asignua\FilamentJsonYamlEditor\Infolists\JsonEntry;
use Asignua\FilamentJsonYamlEditor\Infolists\YamlEntry;

JsonEntry::make('settings')->collapsed()->maxHeight('16rem');
YamlEntry::make('config')->inline(4)->summary('config.yaml')->collapsible(false);

The state may be an array, an object, a Collection or text. Highlighting is done on the server with Phiki exactly like Filament's CodeEntry (light and dark themes, ->lightTheme() / ->darkTheme() / ->grammar() work), the block is a native <details> element, and the copy button copies the text. ->copyable(false) removes it.

#Configuration

There is no config file. Everything is a fluent option on the field or entry; see the method list above and the translations section for the labels.

#Gotchas

  • Tree view re-serialises on edit. Editing a value, a key or a type in the tree rewrites the document with JSON.stringify: integer-like keys ("1", "2") are re-ordered by JavaScript, and numbers beyond 2^53 lose precision. Expanding and collapsing nodes is not an edit and leaves the text alone; so does the code view.
  • YAML aliases are bounded. A document whose aliases expand past a budget (1M nodes plus 10 per byte of source) fails the syntax rule, so a "billion laughs" document cannot exhaust memory on save, schema validation or display.
  • YAML comments. They survive while the state stays text. ->asArray() parses to an array, so comments are gone.
  • YAML is parsed with no object flags. symfony/yaml never instantiates PHP objects from !php/object tags here.
  • JSON tree is JSON only. YamlEditor has no tree view.
  • wire:ignore. The editor owns its DOM; a state change from the server ($set, fill) is pushed into it. An array set that way is shown as text (JSON pretty-printed, YAML dumped by js-yaml).
  • Run php artisan filament:assets after install and after every update; the bundle is served from public/js/asignua/.

#Translations

English, Ukrainian, German, Spanish, French, Italian, Dutch, Polish, Brazilian Portuguese and Turkish, namespace json-yaml-editor::messages. Publish to override:

php artisan vendor:publish --tag=filament-json-yaml-editor-translations

#AI agents

The package ships Laravel Boost guidelines in resources/boost/guidelines/core.blade.php.

#Testing

composer test            # PHPUnit (Orchestra Testbench + workbench panel)
composer analyse         # PHPStan level 8
composer format          # Pint
npm ci && npm test       # node: pure JS logic, the tree view and a smoke test of the Alpine component (jsdom)
npm run build            # rebuild resources/dist/json-yaml-editor.js with esbuild (commit the result; CI fails when it differs)

#Changelog

See CHANGELOG.

#License

MIT. See LICENSE.

The author

asign avatar Author: asign

asign is a small web-dev company from Lviv, Ukraine. We build business applications on Laravel and Filament — CRMs, automation systems for standard and non-standard business processes, booking and content management systems, including our own Filament-based CMS. We open-source the parts that prove useful beyond a single project

Plugins
15
Stars
6

From the same author