tomatophp/tomato-crm
TomatoCRM is a Laravel package from the TomatoPHP ecosystem that brings CRM capabilities to your admin panel. Manage customers, contacts, leads, deals, and sales pipelines through a ready-to-use Filament interface, with customizable resources and integrations for your workflow.
Architecture fit. The package is not a standalone CRM library; it is a TomatoPHP/Filament module that mounts accounts, contacts, leads, companies, deals, activities, and notifications into an existing admin panel. For a TPM this makes fit a binary gate rather than a spectrum: if the target application is already Laravel on Filament v3 with tomato-admin/tomato-support (and the sibling roles/settings/notifications packages), it slots in with a composer require, a config and migration publish, and a migrate. If the application is plain Laravel, or Filament without TomatoPHP scaffolding, "adopting the CRM" actually means adopting an opinionated admin stack — a much larger program than the feature request that triggered the evaluation. Frame the decision to stakeholders in those terms, because scope estimates differ by an order of magnitude between the two cases.
Integration feasibility. Mechanically straightforward inside the ecosystem: the published migrations are the primary artifact, the Eloquent models are the durable surface, and API routes live in routes/. The genuinely uncertain parts are the contract details the docs do not state — the API auth model (Sanctum? scopes? pagination shape? rate limiting?), whether models support soft deletes and audit trails, and whether any multi-tenancy exists. Treat these as discovery tasks with named owners and hard exit criteria, not assumptions to be validated after the sprint starts.
Technical risk. The maturity signal is the dominant risk: roughly 3 stars, zero dependents, a single maintainer, last release May 2024, and release notes that are nothing but compare URLs. Viability rests on internal ownership, not upstream. Secondary risks are brownfield migration collisions on users/accounts/notification tables, N+1 behavior on contact listings as CRM tables grow, and Filament major-version upgrades breaking the resource layer. None of these are blockers; all of them are schedule and staffing inputs.
Key questions to resolve before commitment.
tomato-admin + tomato-support? (Go/no-go.)deleted_at and any audit/history table, or are we building history ourselves?Stack fit and gating. Confirm fit empirically rather than from the README: composer show -a tomatophp/tomato-crm, then read vendor/tomatophp/tomato-crm/composer.json for Laravel version bounds and whether tomato-admin/tomato-support are hard requirements. Treat dependency conflicts discovered in a disposable spike repo as a go/no-go signal, not something to patch around mid-sprint. Budget the spike explicitly — it is the cheapest point at which to kill the initiative.
Migration path. For a greenfield or TomatoPHP-aligned app, the sequence is: composer require, vendor:publish --tag=tomato-crm-config, vendor:publish --tag=tomato-crm-migrations, review every published table/column/FK/index, php artisan migrate, then clear Filament caches so resources register. For brownfield, insert a mandatory schema-diff step before migrate: collisions on users, accounts, or notification tables produce partial migration state that is painful to unwind, and there is no upstream guidance for reconciliation. Plan the rollback before running the first migrate in any shared environment.
Compatibility and pinning. The tomatophp/* siblings release independently and irregularly, so pin exact versions for the evaluation window and commit the resulting composer.lock as the baseline. Decide the fork strategy in week one, not month six: vendor the package (internal fork or repositories path entry), name an owner, and document a divergence policy. Also decide the abstraction boundary early — a thin CrmService owning account creation, contact attachment, and notification dispatch, with thin local model subclasses for tenant scopes and audit hooks, so call sites survive a fork or a later replacement.
Sequencing. A pragmatic four-phase plan: (1) fit spike and dependency audit — go/no-go; (2) migration and schema reconciliation with the escape-hatch note written up front; (3) service layer, queued notification path, and feature tests capturing the API contract we expose (auth, pagination, filtering, error codes); (4) first end-to-end flow in the panel — create an account, attach a contact, verify the notification fires — which exercises models, relationships, and the notification path simultaneously. Notifications and the API contract are the two items most likely to bite in production, so they get tests in phase 3, not after launch.
Maintenance. Assume we own this. The fork needs a named owner, a quarterly maintenance allowance, and a branch-then-diff-then-test discipline for every upstream v1.1.x bump, since releases are opaque. Set a calendar reminder around Filament's release cycle, because the resource layer is the breakage point on major upgrades. Budget is engineering ownership time, not licensing — MIT means no fees, but also no vendor.
Support. There is no SLA, no commercial backing, and effectively no public knowledge base. Internal support means internal documentation: which tables are the package's, which models we subclass, which endpoints our service wraps, and what leaving would take. That escape-hatch note is a deliverable, not a nice-to-have — it converts a future fork-or-replace decision from emotional to concrete.
Scaling. The domain model is thin and the data volume risk is ordinary: contact listings grow fast and are the classic N+1 trap. Eager-load relationships in the service layer, measure query counts on the API before shipping, and do not assume pagination defaults are sensible. Multi-tenancy is unconfirmed — assume single-tenant and, if tenant scoping is required, implement it as a global scope on our subclass and verify the Filament resources honor it. Granular permissions and validated data-residency guarantees are out of scope until proven otherwise.
Failure modes to watch.
tomato-admin absent from the panel provider's plugin list.ShouldQueue; wrap dispatches in our own job to control retries and backoff.routes/api.php in the vendor tree before exposing anything.Ramp-up. Low for engineers already fluent in Filament/TomatoPHP; moderate for those who are not, since the code is the documentation and the README and release notes are thin. The fastest onboarding path is the spike repo plus a guided read of the migrations and route files, with the first end-to-end flow as the acceptance exercise.
Recommendation to carry into planning. Adopt for non-differentiating, internal-facing or MVP scope where the stack already aligns; do not anchor core platform strategy on it. Pair the adoption decision with a priced alternative — a one-to-two-week in-house accounts/contacts build — because for a domain this small that is often the cheaper strategic answer. Vet procurement and infosec before sprint planning, not during it, and if either will block low-maturity dependencies, surface that as a schedule risk on day one.
How can I help you explore Laravel packages today?