amranidev/laracombee
Laracombee is a Laravel package offering a simple, Laravel-friendly interface to the Recombee recommendation API. Manage users, items, interactions, and personalized recommendations for e-commerce, media, and marketplace applications.
Laracombee is a thin, opinionated Laravel adapter over the official recombee/recombee-sdk-php client. Architecturally it is a facade-plus-client wrapper: a service provider binds a singleton, a facade (Laracombee) proxies to AbstractRecombee, and the package layers Laravel conventions (config publishing, Artisan commands, Eloquent-derived schema) on top of Recombee's REST surface. It adds almost no business logic of its own, which is the right design for a vendor SDK bridge — the surface area you own is small, and upgrading tracks upstream.
Architecture fit. It fits cleanly into a conventional Laravel app: package discovery, publishable config, Artisan commands, and an extension point (AbstractRecombee::send()) for custom error handling or multi-database routing. The static $laracombee property on models is a lightweight schema-as-code mechanism that works well for a TPM-level governance story — property changes become reviewable diffs rather than console actions in a Recombee dashboard. That said, it is a synchronization layer, not an eventing layer: there are no model observers, no queue jobs, no outbox. Every write to Recombee is something your application must explicitly invoke. This is the single most important architectural fact for planning.
Integration feasibility. High for a team already committed to Recombee. Composer install, publish config, declare properties, run laracombee:migrate and laracombee:seed. The recommendation path is a single call. There is no auth bridge, no user provisioning, no data model translation beyond reading the $laracombee array — so feasibility is bounded almost entirely by how much of your domain you are willing to hand to a per-record, per-event API.
Technical risk. Several items a TPM should put on the risk register:
Laracombee::recommendTo($user, 10)->wait(). .wait() blocks the PHP worker. With a 2000ms default timeout, a degraded Recombee endpoint directly consumes your PHP-FPM capacity. There is no documented cache layer, circuit breaker, or fallback-to-popular-items path.http. The config default is plaintext. Credentials and behavioral data transit unencrypted unless someone explicitly sets protocol to https. This should be treated as a defect to override on day one, not a configuration preference.laracombee:reset is a footgun. It permanently wipes users, items, properties, ratings, views, purchases, bookmarks, and series. There is no environment guard, no confirmation prompt documented, no dry-run. In a multi-tenant or shared-database setup this is a production incident waiting for a fat-fingered Artisan invocation.send() yourself; recommendation methods fire immediately and return a promise. That asymmetry is a recurring source of bugs (double-sends, forgotten .wait(), unhandled rejections silently swallowed) and pushes error-handling discipline onto every developer.AbstractRecombee extension point helps with targeting and error handling but not with portability.composer.lock policy and a staging smoke test are non-negotiable.Key questions for the maintainer / your own team:
recombee/recombee-sdk-php, and is there a version-constraint policy?reset command's blast radius, and is a confirmation guard planned?Stack fit. Requires PHP 8.2+ and Laravel 10, 11, 12, or 13. Fit is excellent for a modern Laravel monolith or modular monolith where a single application owns the user and item entities that Recombee needs to see. It is a poor fit for polyglot or multi-service estates where the recommendation corpus spans services — you would be funneling every service's interaction events through one Laravel app, which turns that app into a synchronization bottleneck.
The dependency shape is favorable: a single vendor SDK plus Laravel's container. No middleware stack changes, no database migrations, no queue driver requirements.
Migration path. Two viable paths, and the choice should be made explicitly:
Path A — greenfield recommendations. Adopt from day one. Define $laracombee properties on User and your item model, run laracombee:migrate user / laracombee:migrate item in a CI or deploy step, seed historical data with laracombee:seed --chunk=... sized to your Recombee rate limits, then instrument interaction events. Cleanest sequencing, no backfill reconciliation.
Path B — replacing an existing recommender. Treat Recombee as a shadow system for a full cycle. Seed historical interactions, dual-write live interactions to both old and new, and shadow-serve recommendations (compute Recombee results, log them, but render the incumbent's). This lets you compare offline quality before cutover. Laracombee supports this because interaction writes are independent and batchable, but it does not give you an outbox — you must wrap the dual-write in your own job layer to avoid losing events when Recombee is unavailable.
Note that there is no data-migration tooling into Recombee beyond the seed command, and the seed command reads from your configured models. If your history lives anywhere other than Eloquent, plan a separate export.
Compatibility considerations. Pin the package to ^1.0 and pin the underlying Recombee SDK explicitly in your root composer.json. The Laravel 13 support arriving only in 1.0.0 is a warning about framework-version lag — budget a review each Laravel major release. Keep the Recombee database ID and private token in environment variables, never in the published config file, and set protocol to https in every environment including local.
Sequencing.
https, region, and timeout; store credentials in your secret manager.$laracombee on user and item models — start with the smallest property set that supports your first recommender (typically item category, price band, and a few user affinities). Property additions are cheap; deletions are disruptive.addDetailView / addPurchase / addCartAddition / addRating, with retry and idempotency keys derived from your domain event IDs. Do not call these inline from controllers.Maintenance. Low code-surface maintenance, but non-zero dependency maintenance. The package delegates to the Recombee SDK, so upstream breaking changes flow through quickly — historically the most common release reason. Expect a handful of upgrade reviews per year plus a forced review on each Laravel major. Budget roughly a few engineer-days per year for routine upkeep, plus a spike when a Laravel or PHP major lands. Because the package is small and MIT-licensed, the worst case is forking and vendoring AbstractRecombee — a genuinely viable escape hatch, which materially lowers the maintenance risk.
Support. Here you carry the burden. The package is a wrapper, not a managed service, and Recombee's own support covers the API, not Laravel-specific integration questions. With ~113 stars and few dependents, community answers will be sparse; expect to own debugging. Mitigate by keeping a documented internal runbook: how to regenerate a custom client class, how to add a property safely, how to reconcile a partial seed, and — critically — an explicit "never run laracombee:reset outside a disposable database" policy backed by CI permissions or an environment guard you add yourself.
Scaling. Three axes to watch:
Laracombee::batch() aggressively and push ingestion onto a queue with its own worker pool and concurrency limit sized to your Recombee plan. The package provides no built-in throttling, so rate-limit discipline is yours.--chunk flag on laracombee:seed and your batch sizing are the two levers that determine whether a backfill is a cheap overnight job or an invoice event. Model this before seeding production history.Failure modes and mitigations.
| Failure | Impact | Mitigation |
|---|---|---|
| Recombee API latency/outage | Blocking .wait() saturates PHP workers |
Cache results, short timeout, circuit breaker, popular-items fallback |
| Interaction events dropped during outage | Degraded recommendation quality, silent | Queue + retry + dead-letter; reconcile counts periodically |
Property schema drift between $laracombee and live Recombee DB |
Writes rejected or fields silently ignored | Run laracombee:migrate in deploy pipeline; schema assertion in CI |
laracombee:reset misfire |
Total loss of recommendation state | Environment guard, forbid in production config, restrict Artisan permissions |
protocol left as http |
Credentials and behavioral data in plaintext | Override to https in all envs; assert in config test |
| SDK major bump breaks client | Runtime exceptions on every call | Pin in composer.lock; smoke test recommendations in staging |
| Unhandled promise rejection | Silent failures, no alerts | Central send() wrapper in a custom AbstractRecombee subclass with logging |
| Multi-database misrouting | Data written to wrong Recombee DB | Explicit named classes via laracombee:new; no config-swapping at runtime |
Ramp-up. A competent Laravel engineer can be productive in half a day — the API mirrors Recombee's naming and the README is now accurate. The real ramp is domain ramp: understanding which interactions matter for your recommender, how property types constrain what you can filter on later, and why recommendations must never be on the critical path. Plan one engineer as the owner of the Recombee integration (schema, ingestion jobs, fallback behavior, cost) rather than treating it as ambient infrastructure. If you adopt the custom AbstractRecombee subclass pattern on day one — centralizing send(), logging, metrics, and timeout policy — you convert the package's main ergonomic weak point into a controlled seam, and the integration becomes genuinely low-drama to operate.
How can I help you explore Laravel packages today?