vanilo/contracts
vanilo/contracts defines the shared PHP interfaces behind Vanilo’s e-commerce components, providing consistent contracts for products, orders, customers, pricing, and related services so Laravel packages can interoperate cleanly.
What the package actually is. vanilo/contracts is a pure interface/abstraction package: no services, no migrations, no runtime behavior, no configuration. Its entire value is defining the vocabulary (products, orders, pricing, payments, shipping, promotions, customers, addresses, etc.) that every other Vanilo component and any custom extension must speak. Treat it as an API specification published as a Composer package, not as a library you "use."
Architecture fit. Strong fit if we are either (a) adopting Vanilo as our commerce foundation, or (b) building our own commerce layer but want a proven, framework-native domain vocabulary to code against. It is the correct dependency target when writing custom modules, because binding to interfaces rather than to vanilo/product or vanilo/order concrete Eloquent models is what keeps our code portable across Vanilo releases and lets us swap implementations (e.g., our own Product model implementing Vanilo\Contracts\Product). If we are not on Laravel, or we plan to keep commerce on an existing platform (Shopify, commercetools, Medusa), this package has near-zero utility — it is not an anti-corruption layer we can reuse outside the Vanilo ecosystem.
The score requires interpretation. A 0.105 composite score, 3 stars, and "0 dependents" is not a quality signal — it is a measurement artifact. Interfaces packages are always consumed transitively via vanilo/framework and the component packages, and GitHub's dependency graph does not see Composer resolution. The honest read: this package is architecturally load-bearing but has essentially no standalone community, which means no blog posts, no third-party examples, and no Stack Overflow surface. Our developers will be reading source and the Vanilo docs, not searching for answers.
Technical risk is concentrated in one place: contract churn. Interfaces are a public API with hard semver implications. Every method added to a contract is a breaking change for anyone who implemented it. Vanilo majors (1.x → 2.x → 3.x → 4.x) have reshuffled contracts, so upgrading means auditing our implementations against a diff of interface definitions. The risk is not that the package breaks at runtime — it cannot — it is that our custom classes silently stop satisfying a contract until PHP throws a fatal on an unimplemented method. This is a compile-time-style risk that surfaces only when the class is loaded. Mitigations: pin the exact minor, keep our implementations behind a thin adapter layer, and add a contract-conformance test suite that instantiates every custom implementation and asserts instanceof for each contract we claim to satisfy.
Vendor concentration risk. Vanilo is a small, largely single-maintainer ecosystem. This package has an MIT license and, by virtue of being only interfaces, is trivially forkable and vendorable if maintenance stalls — that materially reduces the bus-factor risk compared to a package with real logic. We should record in the ADR that the fallback is a vendored fork with a renamed namespace, and that the fork cost is days, not weeks.
Key questions to resolve before committing:
Product with extra columns) or use the shipped ones with attribute extension? That decision determines how much contract surface we actually touch.vanilo/* packages?Stack fit. Laravel 9/10/11 with Composer and PHP 8.1+. The package is a normal PSR-4 autoloaded dependency with no service provider of its own. It slots in as a required dev-and-runtime dependency of our own domain module, and is already present transitively the moment we install vanilo/framework.
Migration path. Do not install this package in isolation — there is nothing to run. The realistic path is: install vanilo/framework (which pulls contracts), then adopt the contracts incrementally as the boundary for our customizations.
composer show vanilo/contracts and enumerate the interfaces. Map each to the Vanilo component that consumes it and to the concrete class that implements it. This mapping is the single most valuable artifact we produce, and it is not published upstream.Product or Order, implement the contract, bind it in a service provider, and override Vanilo's container binding. Keep these implementations thin — extend Vanilo's base model and add an implements clause rather than writing from scratch.Compatibility. Hard requirement: every vanilo/* package in composer.json must share a compatible major. A mixed set (e.g. contracts 3.x with order 2.x) will resolve but fail at runtime with signature mismatches that are painful to diagnose. Add a Composer constraint or a CI check that asserts all vanilo/* requirements resolve to the same major.
Sequencing. Contracts last, not first. Do not attempt to design our own commerce abstractions against this package before we have a working Vanilo install and a concrete feature to build. The abstractions only make sense once we have seen the shipped implementations — otherwise we will implement interfaces incorrectly, which is worse than not implementing them at all.
Maintenance burden is low but non-zero and lumpy. Day to day, nothing happens: no cron, no migrations, no config cache to clear, no runtime footprint. The burden arrives in bursts at Vanilo upgrade time, when contract diffs must be reconciled against our implementations. Budget this as a recurring upgrade project, not as ambient maintenance.
Support. Community support is thin given the ecosystem size. Practical implication: our team must be capable of reading vendor/vanilo/contracts/src unaided. Do not plan on external consultants or a large pool of Vanilo-experienced hires. This is a real but bounded risk given MIT licensing and forkability.
Scaling. The package itself has zero scaling characteristics — it is interfaces. Scaling concerns live entirely in the implementations (database, queue, payment provider throughput). The one scaling-adjacent consideration: over-implementing contracts creates coupling. Each contract we choose to implement is a permanent obligation to satisfy its future shape. Implement the minimum set required by our features, and resist the temptation to implement interfaces "for completeness."
Failure modes, in rough order of likelihood:
vanilo/* — signature mismatch between a contract and a component expecting an older shape. Mitigation: single-major constraint enforced in CI.Ramp-up. A mid-level Laravel developer unfamiliar with Vanilo needs roughly one to two days to be productive with this package: it is plain PHP interfaces and self-documenting by inspection. The real ramp is on the surrounding domain — understanding which contract maps to which business concept and which component consumes it. That is a one-to-two week curve and is gated by our Phase 0 mapping artifact, not by the package's documentation. Assign that mapping as the first task for whoever owns the commerce integration; it pays for itself on the first upgrade cycle.
How can I help you explore Laravel packages today?