tomatophp/tomato-resource
Tomato Resource generates complete CRUD resources for your TomatoPHP admin panel, turning Eloquent models into ready-to-use forms, tables, and pages with sensible defaults and configurable builders.
Architecture fit
tomato-resource is the schema-definition layer of the TomatoPHP admin stack, not a standalone library. Its value proposition is a single resource class per model that drives table columns, forms, filters, actions, and validation, plus a generator that emits the migration, model, and CRUD wiring. The architecture has two halves with different risk profiles: a build-time generator that writes files and migrations into app/, and a runtime base class that CRUD screens consume.
Fit is strictly conditional. If we are already on tomato-admin, tomato-crud, and tomato-forms, this package is a prerequisite that unblocks admin work. If we are not, installing it yields a config file and a base class and nothing renders. That makes it an all-or-nothing bet on one vendor's internal API surface — itself v1.x and fast-moving — rather than an incremental library adoption.
Integration feasibility
Mechanically trivial: Composer install, publish config/migrations/lang, migrate, clear cache. The real feasibility work is verification, because the package ships no supported Laravel/PHP matrix, no feature list, and no breaking-change notes beyond a changelog link. Feasibility must be established empirically — read composer.json, read the tagged diff, enumerate supported field types from config/tomato-resource.php, then run one end-to-end pass on a small resource and diff the emitted migration against intent.
Technical risk (ranked)
resources meta-table and writes migrations. Conflict with an existing schema, or an alter at deploy time, is a production-grade failure.Key questions to answer before a go decision
composer.json actually declare, and do they cover our target matrix?resources meta-table additive-only, and is it required in production?Stack fit
Laravel plus Tomato Admin only. Portability is near zero — the abstraction assumes Tomato's CRUD and form packages exist and render. A prerequisite gate should apply: confirm the admin panel boots before any debugging of this package begins, because failures at the screen layer are almost always upstream, not here. The honest comparison set is Filament, Nova, or Backpack; this package does not compete on documentation, hiring pool, or support history, and wins only on "we are already on Tomato."
Migration path
There is no migration from an incumbent admin framework — this is additive inside a Tomato codebase. If we are on plain Laravel, adopting this is adopting the Tomato stack, and should be scoped and approved as such rather than as a single-package addition. The exit path costs one class today: wrap the vendor base resource class in our own subclass and confine vendor references to that one file, so a future swap or fork stays cheap.
Compatibility
Pin 1.0.* — never an open constraint. Verify the version matrix manually against our environment. Validate the publishable migrations against a scrubbed copy of the target schema before touching anything shared. Assume config keys and class names churn between minors; treat every bump as a reviewed change, not a composer update.
Sequencing
config/tomato-resource.php in our checkout and enumerate supported field types and generation paths. This gates every later step.Bake these into the team's working agreement: the generator runs locally and never in CI or at deploy; generated files are committed and reviewed as code; customization lives in subclasses or traits, never inline; php artisan optimize:clear is the first debug step after any definition change.
Maintenance
Low run-cost, high drift-cost. There is very little to operate day to day, but a single 2023 release means any patch we need makes us the maintainer of a de facto fork. Mitigations are structural: interface boundary, pinned version, no vendor-file patches, and a deliberate upgrade cadence we schedule rather than chase. Budget a one-off fork-or-replace decision within roughly twelve months of adoption, and make that decision explicit now so it isn't forced later.
Support
Community support is effectively nil at 1 star and 0 dependents — internal ownership is mandatory, not a nice-to-have. The saving grace is that troubleshooting is tractable with a four-step runbook any mid-level developer can execute: confirm the panel boots, clear cache, inspect the emitted artifact, reduce the definition to the smallest failing field set. Escalation beyond that is binary — fork it or replace it. There is no vendor path.
Scaling
Technically, the admin surface scales fine for internal back-office volume, and the generator is dev-time so it imposes no runtime cost. Two things to watch: index pages that paginate without eager loading, where N+1s compound with row count and relationships, and schema breadth, since each new resource is another artifact set to review. Organizationally it scales poorly — the hiring pool for TomatoPHP is essentially zero, so ramp cost is paid per person rather than amortized, and the bus factor sits with whoever wrote the convention doc.
Failure modes and blast radius
optimize:clear as documented first-line response.Ramp-up
Days, not weeks, for an existing Laravel developer — but only if the base class and a short convention doc exist first. The convention is the actual deliverable: resource class owns schema, controller owns screen concerns, subclass owns shared defaults. Without it, per-screen divergence starts within a sprint. Ramp cost is asymmetric: cheap for Laravel natives, expensive for anyone from a Filament or Nova background, who will reasonably expect documentation and a support community that do not exist here.
Framing for the decision: this is a scoped, time-boxed pilot behind one internal tool with a named fallback — not a platform standardization. The cost of trying is genuinely low: one resource, one sprint, a pinned version, and artifacts under version control. The cost of standardizing prematurely is a single-maintainer dependency sitting in the critical path of every internal CRUD screen we ship.
How can I help you explore Laravel packages today?