Runtime and services
Laravel and PHP
PHP's standard application framework; the Consonas CRM codebase is Laravel 11 with a Vue front end on MySQL and Redis.
Laravel is the framework most professional PHP is written in. Routing, an ORM, migrations, queues, a scheduler, mail, validation, authentication and templating all arrive in the box, and the conventions are strong enough that a developer who has never seen a particular codebase can still guess where things are. PHP itself starts fresh for each request, which is unfashionable and quietly useful: state cannot leak between requests because there is nowhere for it to live.
How we use it
Consonas is the CRM, and the codebase is Laravel 11 on PHP 8.2. Sanctum issues tokens, a modules package splits contacts, deals, documents and activities into separately enabled modules, and two well-known packages carry the parts a CRM buyer asks about first: roles and permissions, and an activity log written in the same transaction as the change it records, so the audit trail cannot disagree with the data. Spreadsheet import and export runs through the usual Excel package, MySQL holds the data, Redis carries cache, sessions and queues, and files go to object storage through the S3 driver. The interface is Vue 3 with Vite. Our view on why small teams stop using CRMs at all, which shaped the product more than the framework did, is in why three person companies abandon their CRM.
Two things we would say in the first meeting rather than the fifth. The codebase began as a fork of an existing self-hosted CRM rather than as an empty directory, and its multi-tenant layer is a third party commercial module, not our work.
What it costs you
You need somewhere for it to live. A PHP process manager for requests, separate long-running worker processes for the queues, and a cron entry for the scheduler: three things to keep alive and monitor rather than one deployment. The framework boots on every request, which costs milliseconds an edge runtime does not spend, and that is the price of the isolation between requests.
Eloquent is pleasant enough that the accidental query in a loop is easy to write and invisible until a customer has enough rows to notice. Assume you will spend time on eager loading and on reading query logs.
The fork is the real bill on this project. Every upstream release has to be merged into a tree that has diverged, and the divergence grows. The commercial module adds a licence check against someone else's endpoint, which is a runtime dependency on a third party's uptime for a product that sells on isolation. The container deployment scaffolding in the repository is unfinished: the image as committed serves a placeholder page rather than the application, so anyone reading it should treat it as an intention rather than a deployment.
When we would choose something else
For a new product with no PHP already in the building, we would start on Workers with Hono and pay nothing while it has no users. Where a team is TypeScript from browser to database and wants the same batteries Laravel provides, NestJS is the closer match, at a higher standing cost. And where the requirement is a website with forms on it rather than an application, a framework of this weight is the wrong tool by an order of magnitude.
Where we have used it
Every build below lists this in its stack, so the claim is checkable.