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

Filament Architect Laravel Package

wotz/filament-architect

Filament Architect streamlines building Laravel Filament admin panels, helping you scaffold resources, forms, and tables from your database schema so you can ship polished back-office interfaces faster with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and register

composer require wotz/filament-architect

The package is a Filament form field, so there is usually nothing to migrate. Check two things immediately after install:

  1. composer.json of the package — confirm the Filament major it targets (^3.0 vs ^4.0). With 2 stars and a 2026 release date, it is likely pinned to one major only. A mismatch will surface as a Class not found or a Livewire state exception the first time the field renders.
  2. Whether it ships a plugin class — if src/ contains something like FilamentArchitectPlugin implements Plugin, register it in your panel provider; if not, the field works standalone and you can skip panel registration entirely.

If there is a config or view to publish, do it now so upgrades don't silently overwrite your customizations:

php artisan vendor:publish --tag=filament-architect-config
php artisan vendor:publish --tag=filament-architect-views

Where to look first

  • README.md — probably short; treat it as a hint, not documentation.
  • src/ — find the class extending Filament\Forms\Components\Builder. Everything you need to know about the API is the public methods on that class and its setUp().
  • resources/views/ — this is your rendering contract. Whatever the field outputs (a block array, a nested layout tree), the shipped Blade files show the exact shape.
  • config/filament-architect.php (if present) — block registry, default templates, view paths.

First use case: replace the stock Builder on a content page

The realistic day-one win is a Page/Post model whose content column is JSON:

// migration
$table->json('content')->nullable();

// model
protected $casts = ['content' => 'array'];

// resource form
Architect::make('content')
    ->blocks([...])
    ->columnSpanFull();

Render it with the package's own Blade component if one exists (<x-filament-architect::render :blocks="$page->content" />); otherwise loop the array in your own partial. Verify the rendered output against the editor before you build anything on top of it — a mismatch between the editor's state shape and the renderer is the single most common early failure with builder-style packages.

Implementation Patterns

Keep block definitions in one place. Do not inline ->blocks([...]) in every resource. Put them in a static method or a dedicated App\Support\Blocks class and reference it from both the form and the renderer, so adding a block is a one-file change:

Architect::make('content')->blocks(Blocks::all())

Store raw JSON, render through a resolver. The field gives you an ordered tree; your app should not care about the tree's internal keys. Wrap rendering in a single partial or Blade component that switches on block type and delegates to resources/views/blocks/{type}.blade.php. That keeps the package at the edge of your codebase and makes it replaceable.

Treat block schemas as a public contract. Once editors have saved content, renaming a block key orphans data. Add new block types freely; when you must rename, write a one-off artisan command that walks the JSON and rewrites the key, and run it before deploying the new schema.

Shared content across resources. If the same block set appears on pages, posts and landing pages, define the field once as a custom form component (php artisan make:filament-form-component ContentBlocks) that wraps the package field, then reuse it. This avoids repeating ->blocks() and centralizes view resolution.

Testing. Builder-style fields are Livewire-driven, so test the state transition rather than the markup:

livewire(EditPage::class, ['record' => $page->id])
    ->fillForm(['content' => $fixture])
    ->call('save')
    ->assertHasNoFormErrors();

Keep a JSON fixture per block type in tests/Fixtures/blocks/ and assert the saved model round-trips it unchanged. That fixture set doubles as documentation for your renderer.

Integration with file uploads. If blocks contain FileUpload or RichEditor, the field is storing file paths in JSON. Register a model observer or a scheduled prune that removes paths no longer referenced in any content column — orphaned uploads accumulate fast and no builder package handles this for you.

Gotchas and Tips

Assume the docs are incomplete. Two stars and zero dependents means no Stack Overflow corpus and no blog posts. When something breaks, read the field's setUp() and the Blade views; the answer is almost always there. Budget an afternoon for source-reading on first adoption, and vendor-pin the exact version ("wotz/filament-architect": "1.2.*") so a silent patch can't change the JSON shape under you.

Filament/Livewire version drift is the main risk. With a single maintainer and a recent release, the package may lag Filament minor releases. If you see Unable to find component or a Livewire hydration error on a field that worked yesterday, check whether composer update bumped Filament, not whether your code changed.

Unknown block types must not 500 the page. Guard the renderer:

@if (view()->exists("blocks.{$block['type']}"))
    @include("blocks.{$block['type']}", ['data' => $block['data'] ?? []])
@endif

Without this, deleting or renaming a block class takes down every page that ever used it — including in production, because the JSON still references it.

Reordering and nested state. Nested builders are where Livewire state bugs appear: rows that lose their contents after a drag, or ->reactive() fields that don't re-render inside a block. Fixes to try in order: add stable ->key(), drop ->reactive() on fields inside blocks, and set ->collapsible() so collapsed blocks aren't re-mounted. If the package ships its own nesting, prefer it over composing two Builder instances yourself.

Translations. Builder JSON and spatie/laravel-translatable do not compose out of the box — the package writes one flat array per locale. Either use one JSON column per locale (content_en, content_fr) via ->hidden(fn () => app()->getLocale() !== 'en'), or store {"en": [...], "fr": [...]} and swap the bound state in afterStateHydrated. Decide this before content exists.

Assets after every upgrade. Run php artisan filament:assets and re-publish views if you have not customized them, then hard-refresh; stale compiled JS shows up as a field that renders but whose drag handles do nothing.

Extension points worth knowing. ->view() on the field to swap the editor view, a config-level block registry if one exists, and the public methods on the field class — anything not public is fair game to break in a patch release, so don't extend internals. If you need behavior the package won't give you, fork it: at this size a fork is cheaper than upstreaming and far cheaper than fighting it through workarounds.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource