tomatophp/tomato-flutter
Tomato Flutter connects your TomatoPHP Laravel admin panel to Flutter mobile apps, exposing ready-made APIs, authentication, and CRUD resources so you can ship iOS and Android clients on top of your existing backend quickly.
Architecture fit. tomatophp/tomato-flutter is a Laravel-side bridge: a service provider, published config, API routes, a generator command, and Dart stubs that emit a Flutter client against your existing models and auth. It only fits one architecture — Laravel backend, Sanctum-style token auth, Flutter as the chosen client, ideally inside the TomatoPHP admin ecosystem. If any of those three are untrue, the value proposition collapses to "a code generator we'd have to rewrite." It is an accelerant for teams that have already made the platform decision, not an input to making it.
Integration feasibility. Mechanically straightforward on an existing Laravel app: composer require (pinned to 1.0.8), interactive vendor:publish, optional migrate, optimize:clear, then route:list --path=api to read the actual mobile contract and artisan list | grep -i flutter to find the generator. Real effort is not installation; it is the spike against your auth, your one real resource, and the decision of how generated Dart lives in the repo. Budget one sprint for a vertical slice (token login → list → show → create → file upload → 401 handling), not an afternoon.
Technical risk. The risks are portfolio-level, not code-level:
composer require is not proof the generator works on your runtime.Key questions a TPM must answer before funding the spike.
composer.json support them today?Stack fit. Assumes Laravel + Sanctum (or equivalent token auth already verified independently for a web client) + Flutter/Dart. Optional but strongly recommended: tomato-settings and the TomatoPHP admin panel to drive branding and generation from the panel rather than hardcoding. Do not fork the package to fit; forking converts every dependency upgrade into a merge project.
Migration path. There is no migration in the data sense — this adds a client-facing API layer alongside existing /api/*. The migration work is organizational:
route:list and adjust in config to avoid collisions with an existing SPA API.--dart-define=API_BASE_URL=...) so one client serves local, staging, production.Compatibility. Pin "tomatophp/tomato-flutter": "1.0.8" from day one — no floating ^1.0, given the absent changelog discipline. Verify runtime compatibility by running the generator on our actual Laravel version during the spike, not by reading constraints alone. Before any future bump, open the compare link, regenerate into a scratch directory, and diff emitted Dart. If the diff touches stubs/ output, that is a release review, not a routine update.
Sequencing.
git diff --stat before/after, or dry-run/--pretend if supported). Move customised stubs into our own path, point config at them, commit immediately so any vendor:publish --force shows up as a loud diff.stubs/ are cheap to correct once and expensive after a mobile dev has built screens against them.Maintenance. We own upgrade verification, permanently — the absence of documented changes here is a pattern, not an oversight. That is a standing tax on every Laravel upgrade, not a one-time cost. Keep a short internal changelog recording regenerated resources and diffs; "which of our twenty resources did that patch touch" must never be answered by reading Dart. Pin the version and treat patch bumps as releases requiring a smoke test.
Support. Community-maintained, single-maintainer ecosystem, no SLA, no security-review artifacts. Practical consequence: nominate one engineer as owner and first responder. If the integration is orphaned across a team change, the next Laravel upgrade will be discoverable only via a broken mobile screen. Do not put this on the critical path of a revenue-bearing release without an internal fallback (i.e., the exit plan).
Scaling. Generation itself is cheap; the risk curve scales with the number of generated resources and the number of shipped mobile versions in the field. At a large, long-lived mobile surface, hand-rolled, versioned, contract-tested endpoints usually win on maintainability — so treat this as an accelerant for the first release and a scoping decision to revisit, not a permanent architectural commitment. If we serve multiple heterogeneous clients or want OpenAPI-first, this is the wrong tool.
Failure modes to plan for.
config:cache. optimize:clear resolves most install-day confusion.vendor:publish --force overwrites customised stubs — bites at setup and again months later when someone "fixes" something.SANCTUM_STATEFUL_DOMAINS/CORS or lose an afternoon to a rejected preflight.Ramp-up. Expect the first hour to be source-reading, not tutorials: composer.json, the service provider, config/, routes/, then stubs/. Write the ten things learned in that hour into a short internal onboarding note, because the repository is the documentation and it will not improve. Flutter developers need the generated conventions (naming, pagination envelopes, error shapes) documented once by whoever reads the stubs; onboarding cost after that is low.
Bottom line for the TPM: real leverage if we already run Laravel plus Flutter and treat generation as a reproducible build step with pinned versions, owned auth code, and stub-based customisation. The cost is that we — not the maintainer — own upgrade verification and the mobile API contract. Fund a one-sprint spike on one real resource, require a measured exit cost before go, and pitch it internally as a pinned, reversible accelerant rather than an architectural commitment.
How can I help you explore Laravel packages today?