Self-hosted service
InvoicePlane/InvoicePlane avatar
InvoicePlane/InvoicePlane

InvoicePlane: self-hosted invoicing on PHP, and what the 1.7.2 template change means

A self-hosted open source application for managing your invoices, clients and payments.

3,147 stars867 forksPHPNOASSERTION

At a glance

What is it?
InvoicePlane is a self-hosted PHP application for invoices, clients and payments. This review covers the Docker quick start, the ipconfig.php settings that break logins, the 1.7.2 custom template allowlist, and when Invoice Ninja is the better fit.
Who is it for?
Adopt InvoicePlane if you want invoice and client records on your own server, you are comfortable with PHP and MariaDB, and you are willing to read UPGRADE.md before every release. Do not adopt it if you need an API-first billing engine, a hosted service, or a modern JavaScript front end; the repository shows a CodeIgniter application with a Grunt and Sass asset pipeline, not a headless platform.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
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 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Who InvoicePlane is for, and who it is not for

InvoicePlane is a libre self-hosted web application for managing invoices, clients and payments, written in PHP and built on CodeIgniter. The unit of work is a small business or a freelancer who wants invoice and client records on a server they control, with no per-seat subscription. The README lists invoice and quote management, client records with transaction history, products, projects and tasks, payment tracking with reminders and gateways, template and theme customization, and reporting. That set describes a back-office billing tool, not an accounting system. There is no mention of double-entry ledgers, bank reconciliation or tax filing.

The people who should look elsewhere are the ones who need a hosted service or an API-first billing engine. The README documents a web interface and a template system; it does not describe a public REST API. If your product needs to create invoices programmatically from another service, this repository gives you no documented endpoint to call. Likewise, anyone who wants a single binary or a managed database should read the Docker section below carefully, because the development compose file is explicitly not a production configuration.

The stack behind InvoicePlane: CodeIgniter, MariaDB and a Grunt pipeline

The repository layout shows a conventional PHP web application. The application directory holds the CodeIgniter code, assets holds front-end sources, and resources holds Docker build contexts. The top level carries composer.json for PHP dependencies and package.json for the front end. That package.json names Grunt as the build tool, with grunt-sass, grunt-postcss, autoprefixer and grunt-contrib-uglify, and it pins jQuery 3.7, jQuery UI 1.14, Bootstrap Sass 3.4, Select2 4.0.13 and Font Awesome 4.7. The build script is simply "grunt build". Nothing here is a modern component framework; the front end is server-rendered pages with jQuery widgets layered on top.

Data lives in MariaDB. The development docker-compose.yml builds a MariaDB 10.9 service, and compose.yml uses the mariadb:11 image. Configuration is a PHP file, ipconfig.php, generated from ipconfig.php.example, holding the base URL and database credentials. In the container path, the same values arrive as environment variables: IP_URL, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE and ENCRYPTION_KEY. The README states that the container entrypoint generates the configuration and runs pending database migrations automatically on startup, so the container path skips the browser installer entirely.

Two details in that layout matter more than they look. First, ENCRYPTION_KEY is a real secret: compose.yml ships the literal value dev-key-change-me-in-production-00, and the README warns that the development file is for local testing only. Second, the repository carries phpstan.neon, phpstan-baseline.neon, phpcs.xml, pint.json and rector.php, which tells you the maintainers run static analysis and a coding-standard tool. A baseline file also tells you the analyzers still report known issues rather than a clean run.

Installing InvoicePlane with Docker and reaching the first invoice

The README labels the Docker route as recommended for development. It clones the repository, builds the app and database containers, and publishes the application on port 4895. The command block below is copied from the README; after it finishes, the README says to open http://localhost:4895, where the installer or the generated configuration should present a working application.

bash
git clone https://github.com/InvoicePlane/InvoicePlane.git
cd InvoicePlane
docker compose up -d --build

The README is explicit that compose.yml is for local development and testing only, because it ships a fixed ENCRYPTION_KEY and database password. Named volumes keep uploads, storage and the database across restarts, but the credentials do not change. For a real deployment the README points to the container deployment document for the environment variables to set instead. The compose file shows the shape of those variables, including IP_URL, which must match the address users actually visit.

yaml
environment:
  IP_URL: http://localhost:4895
  DB_HOSTNAME: db
  DB_USERNAME: invoiceplane
  DB_PASSWORD: invoiceplane
  DB_DATABASE: invoiceplane
  ENCRYPTION_KEY: dev-key-change-me-in-production-00

The non-container installation is a file upload. The README says to download the latest release from the InvoicePlane website, extract and upload the files, copy ipconfig.php.example to ipconfig.php and set the base URL and database credentials, then open http://your-domain.com/index.php/setup to run the installer. If you want URLs without index.php, the README gives three steps: enable mod_rewrite, set REMOVE_INDEXPHP=true in ipconfig.php, and rename the htaccess file in the root directory to .htaccess.

One setting deserves attention before you finish. Session files go to PHP's default session save path unless SESS_SAVE_PATH is set in ipconfig.php to an absolute path. The README warns that an empty SESS_SAVE_PATH= line is passed to PHP as an empty session.save_path, which overrides php.ini and your vhost. Sessions then cannot be written, login fails, and the installer stays stuck on .../setup/language. On systemd distributions the README advises against /tmp, because services run with PrivateTmp=true and it gets wiped.

ini
SESS_SAVE_PATH=/var/lib/invoiceplane/storage/framework/sessions

If you mount a volume in Docker, the README says to include the configured session path among your persistent volumes.

The 1.7.2 custom template allowlist changes upgrade work

Since version 1.7.2, custom template names are added through an allowlist in ipconfig.php. The README states the filesystem is never scanned, and that this is what keeps the template system safe from remote code execution. That is a deliberate trade: you gain a smaller attack surface and you lose the convenience of dropping a folder into a templates directory and having it appear. If your workflow depended on the old behavior, the upgrade is not a drop-in file replacement.

The README points to CUSTOM_TEMPLATES.md for the how-to and to UPGRADE.md before upgrading an installation that already uses custom templates. It also says to check CHANGELOG.md before upgrading and to subscribe to GitHub Releases notifications so a security release is not missed. The repository has a .github/security directory for formal advisories. Read together, those pointers describe a project where the upgrade path is documented but manual: you check the changelog, you read the upgrade notes, and you adjust ipconfig.php yourself. There is no automatic migration step for templates mentioned in the README.

Version numbers matter here. The recent releases are v1.7.2-rc-1, v1.7.2-rc-2 and v1.7.2, and package.json records the version as 1.7.2. Anyone running an earlier release with custom templates should treat 1.7.2 as a configuration change, not just a patch.

Where a self-hosted invoicing tool stops being the right answer

The clearest limitation is operational. You own the PHP runtime, the MariaDB instance, the session path, the uploads volume and the encryption key. The README's warning about SESS_SAVE_PATH is not a corner case; it is a configuration line that silently breaks login and the installer when set wrong. The development compose file ships fixed credentials, and the README says so, which means the path of least resistance produces a deployment you should not expose to the internet. The container path removes the browser installer and runs migrations on startup, which is convenient until a migration fails on a live database and you are reading container logs.

The second limitation is integration. Nothing in the README describes a public API for creating invoices, clients or payments from outside the application. If your business logic lives in another system, you will be entering data by hand or extending the application. That is a real boundary, not a missing checkbox.

The third is the front end. The pinned dependencies in package.json are jQuery 3.7, jQuery UI 1.14 and Bootstrap Sass 3.4. That is a stable, well-understood stack, and it is also an older one. If you expect a single-page interface or a mobile-first client portal, the repository does not describe one.

Finally, the licence. The repository's LICENSE.txt exists at the top level, package.json declares MIT, and the repository metadata reports NOASSERTION. Those do not agree, and the README does not resolve the question. If your organization needs a clear licence position before adopting, that discrepancy is the first thing to check with the project, not something to infer.

InvoicePlane and Invoice Ninja: two different bets

Invoice Ninja is the comparison people search for, and the difference is architectural rather than cosmetic. Invoice Ninja is built as an API-first application with a modern front end and an official hosted option; its documented surface is designed for programmatic access. InvoicePlane is a server-rendered CodeIgniter application whose documented surface is the web interface, a template system and a configuration file. If your requirement is "create an invoice from my own service", Invoice Ninja's approach matches that requirement directly and InvoicePlane's does not.

The trade runs the other way too. InvoicePlane's deployment story is a PHP application plus MariaDB, configured through a single ipconfig.php or a short list of environment variables. There is no queue, no separate API service and no Node runtime in production; the Grunt pipeline is a build-time concern. For an operator who already runs PHP and MariaDB, that is a smaller system to reason about. The cost is that you get the interface the project ships, and customization goes through templates rather than through an API.

Neither is a drop-in replacement for the other. Choosing InvoicePlane means accepting a web-first workflow and doing your own upgrades. Choosing Invoice Ninja means accepting a different deployment shape and, if you use the hosted option, a recurring cost the self-hosted project does not have.

Maintenance, releases and the cost of staying current

The repository is not archived, and the last push was on 2026-09-22, two days before this writing. Recent releases are v1.7.2 on 2026-08-28, with v1.7.2-rc-1 and v1.7.2-rc-2 in the weeks before it, so the project ships release candidates before final versions and documents each release in CHANGELOG.md. The default branch is develop, which is where work lands before a release is cut.

The upgrade cost is your own labor. The README's instructions are: check the CHANGELOG before upgrading, read UPGRADE.md for step-by-step instructions, and subscribe to GitHub Releases notifications so a security release is not missed. For 1.7.2 specifically, an installation with custom templates needs the allowlist entry added to ipconfig.php before it will see those templates again. That is a manual edit per installation, and it is the kind of step that is easy to skip on a server nobody logs into.

The asset pipeline is a second recurring cost, though only if you modify the front end. Rebuilding requires the Node toolchain and "grunt build". If you never touch assets, you never run it, because released packages ship built files.

On licensing, the metadata reports NOASSERTION while package.json declares MIT and LICENSE.txt sits at the repository root. That inconsistency is worth resolving before you redistribute the software or embed it in a product. This is not legal advice; it is a factual discrepancy in the repository that a legal review would need to settle.

Editorial conclusion

Adopt InvoicePlane if you want invoice and client records on your own server, you are comfortable with PHP and MariaDB, and you are willing to read UPGRADE.md before every release. Do not adopt it if you need an API-first billing engine, a hosted service, or a modern JavaScript front end; the repository shows a CodeIgniter application with a Grunt and Sass asset pipeline, not a headless platform. Before installing, verify three things: that your PHP version satisfies the installer, that SESS_SAVE_PATH is either a real absolute path or absent entirely, and whether you already use custom templates, because 1.7.2 moves them to an allowlist in ipconfig.php.

Frequently asked questions

How do I install InvoicePlane?

The README gives two paths. For development, clone the repository and run docker compose up -d --build, then open http://localhost:4895. For production, download the latest release from the InvoicePlane website, upload the files, copy ipconfig.php.example to ipconfig.php with your base URL and database credentials, and open /index.php/setup to run the installer.

What is a good alternative to InvoicePlane?

Invoice Ninja is the comparison the search data points to, and the difference is architectural: Invoice Ninja is built as an API-first application with an official hosted option, while InvoicePlane is a server-rendered CodeIgniter application configured through ipconfig.php or environment variables. If you need to create invoices from another service, that distinction decides the choice.

What is InvoicePlane?

InvoicePlane is a libre self-hosted web application designed to help you manage invoices, clients, and payments efficiently, according to its README. It is written in PHP and built on CodeIgniter, with MariaDB for storage.

Official sources

  1. InvoicePlane/InvoicePlane on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/invoiceplane-invoiceplane.svg)](https://hysenlabs.com/projects/invoiceplane-invoiceplane)