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

Bree Laravel Package

packettide/bree

Bree is a Laravel package from Packettide that extends Laravel Breeze with team support, making it easy to create teams, invite members, and manage roles while keeping Breeze’s lightweight, minimal scaffolding. It’s ideal for quickly scaffolding multi-user applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Bree is a thin form layer over Eloquent: you declare fields on (or alongside) a model, and Bree turns that declaration into rendered inputs, validation rules, and a save path. The mental model is "schema-in-code, not schema-in-Blade" — the payoff is one definition reused across create/edit screens.

Minimal path:

  1. composer require packettide/bree — Laravel package discovery should register the service provider; if it doesn't, add it to config/app.php manually.
  2. Look for a publishable config (php artisan vendor:publish --provider="PacketTide\Bree\...") and check whether it exposes a field-package registry. That registry is the single most important thing to read first, because it tells you which field types exist out of the box.
  3. Read src/ before the README. With a package at this star count, the source is the documentation — particularly the base field class and any Field contract, since every customisation you make will hang off it.
  4. First use case: take an existing simple model (a Profile, Post, or settings table), declare two or three fields (text, textarea, a boolean), render it on one Blade view, POST it back, and confirm the model updates. Resist starting with relations or file uploads — get the render → validate → persist loop working on flat columns first.

If the package ships generators (make:field, make:form), run them once to see the expected class shape rather than hand-writing it.

Implementation Patterns

Declare fields once, render in two places. The core win is a single field definition powering both a create and an edit view. Structure your controllers so the form object is constructed in one place (store and update both call the same builder with a different model instance) and let the field layer figure out the difference between "empty" and "populated" state.

Treat fields as a mapping layer, not a UI layer. The healthiest pattern with packages like this is to keep the field class responsible for value in / value out / validation rule, and leave markup decisions to a Blade partial per field type. That way when a designer wants a different select markup, you override one partial instead of subclassing a field.

Validation belongs with the field. Put the rules next to the field definition (or expose them via a rules() method on the form object) so $request->validate($form->rules()) is a one-liner in the controller. Do not duplicate rules in a FormRequest and in the field definitions — that's the classic drift bug with form packages.

Persist through the model, not around it. Use $model->fill($form->validated())->save() style flows so observers, casts, and $fillable still apply. If Bree offers its own save() helper, verify it goes through fill()/save() and doesn't bypass events — if it does, prefer manual persistence.

Handle relations explicitly. Attribute fields are easy; belongsTo/hasMany fields are where form layers usually get leaky. Common workable pattern: the field exposes the raw foreign key for validation and a separate accessor for the display label, and you sync()/associate() in a small afterSave hook on the form class rather than inside the field.

Group fields into "form" classes for large models. Rather than dumping 40 fields onto a model, define a ProfileForm, BillingForm, AdminForm that each bind to the same Eloquent model but expose a different subset. This keeps the admin screen and the customer screen from fighting over one definition, and makes partial updates safe.

Custom field package = one class + one partial + one registration. When you need a bespoke input (a colour picker, a currency amount, a repeater), the extension point is almost always: subclass the base field, implement render()/rules()/setValue(), add the Blade partial, register the alias in config. Write an integration test that round-trips a value through it — this is the part of a form library that silently breaks on upgrade.

Test at the form boundary. Feature-test the endpoint (POST invalid → asserts errors; POST valid → asserts DB state). Unit-testing field classes individually gives false confidence because most bugs live in the binding between request data and model attributes.

Gotchas and Tips

  • Maturity risk is real. 15 stars and a single maintainer-ish footprint means you should pin an exact version in composer.json, commit your composer.lock, and be prepared to fork. Budget a day to read the whole source before betting a large form surface on it — it's small enough that this is feasible, and that's the main mitigation.
  • $fillable / $guarded interactions. Form layers often build an array of attributes to fill; if a column is guarded, values silently vanish with no error. When a field "doesn't save", check fillable before you debug the package.
  • Casts and empty strings. A boolean or date cast plus an empty string from an unchecked checkbox is the single most common source of Carbon exceptions. Normalise '' → null in the field's setValue() rather than in every controller.
  • Validation rule syntax drift. Some field packages return rules as strings ('required|max:255'), some as arrays, some as Rule objects. Check how the base class normalises them before you mix and match — merging a string rule with an array rule in Laravel can produce surprising results.
  • File uploads are the usual weak spot. Verify the field handles the "no new file uploaded on edit" case (keeping the existing value) rather than nulling the column. Test this explicitly; it's the bug most commonly shipped with form packages.
  • Blade escaping. If the field renders its own markup via {!! !!} inside the package, user-supplied labels or option text can escape the escaping. Audit any {!! in the vendor views before shipping.
  • Config cache. If the field registry lives in config, php artisan config:cache will happily serve a stale registry after you add a custom field. Clear it in local dev or register fields in a service provider instead of config.
  • Debugging technique. When a value doesn't round-trip, dump the form object after binding and the array it hands to fill(). The gap between those two is where nearly every bug in this class of package lives.
  • Extension points to prefer, in order: config-based field registration → Blade partial override → subclassing a field → forking. Forking is fine here given the size, but keep your changes in a separate class so you can drop the fork if upstream wakes up.
  • Don't fight it on complex UI. For a repeater, nested relation grid, or anything stateful on the front end, render that section with your own Blade + a small bit of JS and let Bree own only the flat fields. Form layers that "support a variety of field packages" get brittle fast at the complex end; keep the boundary deliberate.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource