SolidInvoice: a Symfony 7 invoicing platform you host yourself
Simple and elegant invoicing solution.
At a glance
- What is it?
- SolidInvoice is an MIT-licensed PHP application for quotes, invoices and recurring billing, built on Symfony 7.1 and PHP 8.4. Its appeal is data ownership and multi-tenancy; its cost is that you run and upgrade the stack yourself.
- Who is it for?
- Adopt SolidInvoice if you already operate PHP 8.4 infrastructure and want invoices, quotes and recurring billing in a database you control. Do not adopt it if you have no one to run Composer, Doctrine migrations and Symfony Messenger workers, or if you need a hosted vendor to hold the pager.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The trade-off SolidInvoice is built around
The README states the premise directly: most invoicing tools force a choice between being easy to use and respecting your data. SolidInvoice's answer is to ship one codebase that can run either on your own server under the MIT licence or on the vendor's hosted service for a flat $8 per month. The target reader is named in the project description: freelancers and small businesses that send quotes and invoices and want the records to stay in their own database. The topics list on the repository adds self-hosted and freelancer alongside billing and quotes, which matches the pitch. What that means in practice is that the interesting comparison is not SolidInvoice against another invoicing SaaS. It is SolidInvoice self-hosted against SolidInvoice hosted, because the feature table in the README claims both versions ship the same codebase and feature set. The differences it lists are operational: updates, backups, branding and early access to new features. If you choose the self-hosted column, everything below the application layer becomes your problem.
Multi-tenancy, ULIDs and the Doctrine layer underneath
The architecture is a conventional Symfony application with an unusual amount of billing logic packed into it. The README lists Symfony 7.1, PHP 8.4, Doctrine ORM and API Platform 4 as the stack, with Tabler and Bootstrap 5.3 on the front end, Stimulus and Webpack Encore for assets, and Bun and Sass in the build. Primary keys are ULIDs rather than auto-increment integers, which matters if you ever merge or export data across installations. Multi-tenancy is handled with Doctrine filters, and secrets are stored encrypted. That combination is the part worth understanding before you deploy: running several companies from one install is a first-class feature, not an add-on, and the isolation is enforced at the ORM query layer rather than by separate databases per tenant. The README does not spell out the failure modes of that approach, so if you plan to host unrelated organisations in one instance, read the Doctrine filter configuration in the source rather than trusting the feature bullet. Invoices move through an explicit state machine (draft, pending, paid), tax rates are snapshotted when an invoice is issued, and monetary amounts are represented as Money objects rather than floats. The snapshot behaviour is the detail that prevents a later tax-rate edit from silently changing historical invoices.
Payments, the API and the MCP server
Payment handling is deliberately indirect. SolidInvoice uses Payum for gateways, with Stripe and PayPal named in the README, and the documentation states that card data never touches your server. You bring your own gateway credentials, and invoices carry online payment links. The API is built on API Platform 4 and can return JSON-LD, JSON-HAL, plain JSON or XML, authenticated with a token sent in the X-API-TOKEN header. There is also a built-in MCP server with OAuth2, aimed at AI agent automation, and Meilisearch integration for full-text search across records. Two of those deserve scrutiny. The MCP server is a relatively new surface in an application that also holds your client list and payment links; the README gives no detail on scoping or rate limits, so treat it as something to disable until you have read the configuration. Meilisearch is an external service, which means a self-hosted deployment is not a single container unless you skip search. Grid export and full company data export exist, which is the escape hatch that makes the lock-in argument credible.
Installing it: Docker is the documented path
The README's quick start offers two routes: sign up at solidinvoice.co, or self-host with Docker. The Docker image is published as solidinvoice/solidinvoice on Docker Hub, and the repository also references Helm charts for Kubernetes and opt-in Prometheus metrics. The README as supplied is truncated inside the hosted sign-up paragraph, so the exact docker run invocation, the required environment variables and the database setup steps are not reproduced here. Do not guess them. The project's own documentation site is the place to read the current command, and the Artifact Hub badge in the README points at the Helm repository if you are deploying to Kubernetes. What can be said from the stack list is what the container has to satisfy: PHP 8.4 or later, a database for Doctrine, and a Messenger transport if you want asynchronous processing rather than synchronous request handling. Recurring invoices, scheduled payment reminders and overdue notifications all imply background work, so a deployment that only runs the web process will look correct and then quietly fail to send anything. That is the first thing to verify after the container starts.
Where SolidInvoice is the wrong choice
The honest limitation is that this is an application you operate. The README's own comparison table puts manual updates and self-managed backups in the self-hosted column, and that is not a marketing caveat, it is the deal. Symfony 7.1 on PHP 8.4 is a fast-moving combination; the release history shows 3.0.0 in June 2026 and 3.0.1 shortly after, with 3.0.0-beta1 a month before that, which is a young 3.x line. The default branch is 3.1.x while the README links a 3.0.x licence file, so branch and documentation drift is already visible in the material. If your organisation cannot run Composer updates, apply Doctrine migrations and restart Messenger workers on a schedule, the hosted tier or a different product is the rational choice. A second boundary: the project is PHP-specific. If your team has no PHP, extending it means learning Symfony's service container, Doctrine and API Platform before you can change a PDF template. The README mentions eight built-in PDF templates, so template work may be configuration rather than code, but anything deeper is Symfony work.
What it is not: a comparison with Invoice Ninja
The obvious alternative in the self-hosted invoicing space is Invoice Ninja, which is also PHP and also offers a hosted tier alongside a self-hosted edition. The difference in approach shows up in the stack and the extension model. Invoice Ninja ships a Laravel application and has historically leaned on a broader built-in feature surface, including its own client portal and a large set of first-party integrations. SolidInvoice is Symfony 7.1 with API Platform 4 and Payum, and its README frames extensibility and integration as the reason the stack was chosen, with a REST API in four serialisation formats and a token header for auth. If your integration plan is to drive invoicing from an existing internal system, the API Platform foundation is the more natural fit. If your plan is to click through a finished product and never open the code, the difference matters much less, and the deciding factor becomes which project's release cadence and documentation you can live with. Neither choice removes the operational burden of self-hosting. Both do remove per-client pricing.
Licence, upgrades and what maintenance actually costs
The licence is MIT, stated in the README badge and the repository metadata, which permits forking, modification and redistribution. That is a genuine advantage over source-available invoicing products, and it means the hosted tier is a service decision rather than a licensing one. It is not legal advice, and if you redistribute a modified version you should read the licence text in the repository rather than this summary. On maintenance: the material supports the claim that upgrades are manual for self-hosters, but it does not give a migration guide, a supported-version policy or an end-of-life schedule for the 3.0.x line. That absence is itself the finding. Before you deploy, check which branch receives fixes, whether 3.0.x to 3.1.x requires a database migration, and whether the Docker image you pin is rebuilt for each release or tracks a moving tag. Pinning an explicit version tag rather than latest is the difference between a predictable upgrade and an incident.
Editorial conclusion
Adopt SolidInvoice if you already operate PHP 8.4 infrastructure and want invoices, quotes and recurring billing in a database you control. Do not adopt it if you have no one to run Composer, Doctrine migrations and Symfony Messenger workers, or if you need a hosted vendor to hold the pager. Before committing, verify the exact image tag and Messenger transport settings in the Docker documentation for your release, confirm the 3.1.x branch is where your fixes will land, and check that the Payum gateway you need is actually configured for your currency.
Community notes