grumpydictator/firefly-iii
Firefly III is a free, self-hosted personal finance manager. Track income and expenses with double-entry bookkeeping, budgets, categories and tags, automate bank imports with rules, and explore clear reports, all in a privacy-friendly PHP/Laravel app with a JSON REST API.
Architecture fit. Firefly III is not a library — it is a complete, opinionated Laravel monolith (PHP 8.3+, Laravel 11.x, Blade + Vue/Inertia-style front end, MySQL 8 / PostgreSQL 13+ / SQLite back end). composer require grumpydictator/firefly-iii is not a supported consumption path, which is exactly why the dependents count is zero. Any evaluation must therefore frame "integration" as service integration or fork, never as a package dependency. It fits a stack when the requirement is "a personal-finance ledger and rules engine with an API," and fits poorly when the requirement is "a billing/subscription engine" or "a multi-tenant finance SaaS." The domain model is genuinely strong for the former: double-entry transactions, multi-currency with per-transaction exchange rates, budgets, categories, tags, piggy banks (savings goals), recurring transactions, bills, rule-based auto-categorisation, and a JSON:API surface with OAuth2.
Integration feasibility. High for read/write API integration; medium for deep customisation. The REST API is documented and reasonably stable within a major, and is protected by Laravel Passport (OAuth2 authorization-code + personal access tokens). Webhooks support HMAC-SHA256 signing with a per-webhook secret, which is workable for event-driven sync. Bulk historical data lands through CSV/OFX/QIF import, or via the separately maintained firefly-iii-data-importer service. There is no officially supported PHP SDK, so expect to hand-roll a thin client with retry, pagination, and rate-limit handling. Custom fields are limited — the data model is fixed, so anything Firefly does not model natively (e.g. approval workflows, cost-centre hierarchies, invoice attachments with structured metadata) becomes a fork or a sidecar database.
Technical risk. Four material risks, in order:
Secondary risks: financial data sensitivity (GDPR/CCPA scope, encryption at rest is your responsibility), dependency on third-party currency-rate APIs for multi-currency correctness, and webhook delivery being at-most-once with no built-in replay queue.
Key questions to resolve before commitment.
Stack fit. Firefly slots in cleanly as a bounded-context service in a container platform: official fireflyiii/core images, an external MySQL 8 or PostgreSQL 13+ instance, Redis for cache and queue, and a cron-driven scheduler. Treat it as an appliance with a database — not as a codebase you edit. The natural integration boundary is the JSON:API plus webhooks; everything else (identity, permissions, reporting, downstream accounting) should live in your own services.
Migration path. Sequence it as a strangler-style adoption rather than a rewrite:
Compatibility. Pin to a specific minor and pin the image digest. Maintain a written compatibility matrix across: Firefly major ↔ PHP version ↔ Laravel major ↔ MySQL/PostgreSQL major. Validate the data importer version against the core version — they drift independently. If you sit behind a reverse proxy with SSO (Authelia, oauth2-proxy), confirm the auth path you intend (Firefly supports LDAP and 2FA natively; OIDC is via proxy plus AUTHENTICATION_GUARD configuration) and test the API token flow separately from the browser flow, because proxied SSO and Passport tokens take different paths.
Sequencing. Weeks 1–2: licence review and POC deployment. Weeks 3–5: historical import validation and data-model gap analysis. Weeks 6–10: API client, webhook consumer, reconciliation job, monitoring. Weeks 11–14: security hardening (TLS, secrets management, DB encryption, audit logging, backup/restore drills) and a rehearsed upgrade. Then a staged rollout. Budget a recurring 1–2 days per month for upgrade triage regardless of path.
Maintenance. The recurring cost is upgrade management, not runtime babysitting. Firefly ships frequently; each major can require manual migration steps and occasionally a config or environment-variable change. Adopt a policy of staying one minor behind latest, upgrading monthly in staging, and never skipping a major. Database migrations are the highest-risk operation — take a verified snapshot immediately before every upgrade and test the rollback path, because Laravel migrations are not reliably reversible.
Support. Community-only. There is no vendor, no paid support tier, and no security advisory SLA beyond what the maintainer chooses to publish. For a finance-adjacent system this means you need an internal owner who can read Laravel stack traces and PHP logs. Response to a critical CVE in a transitive Laravel dependency depends entirely on the upstream release cadence — factor that into your risk register and be prepared to patch a fork on your own clock.
Scaling. Adequate for the intended scale (tens to low hundreds of users, hundreds of thousands of transactions) on modest hardware. Constraints appear as: report generation and dashboard queries becoming slow on large transaction tables without index tuning and materialised summary tables; queue backlog if the worker is undersized during bulk imports; and the single-database-per-instance model making horizontal scale-out tenant-by-tenant expensive. There is no sharding story. Plan for read replicas at the database layer rather than application-level scaling.
Failure modes to instrument explicitly.
storage/ tree grow unbounded; monitor and set retention.Ramp-up. Two distinct skill profiles. Operations (run stock containers, cron, backups, monitoring, upgrades): roughly 3–5 days for a competent platform engineer, provided the upgrade runbook exists. Engineering (API client, webhook consumer, reconciliation, eventual fork): 2–3 weeks for a Laravel-proficient developer to be productive in the codebase, longer to be safe in the domain model. Non-technical finance users need about half a day of onboarding to the accounts/budgets/rules mental model, and should be warned that Firefly's terminology (withdrawal/deposit/transfer, piggy banks) differs from mainstream accounting tools. Document the runbook before go-live, not after the first failed upgrade.
How can I help you explore Laravel packages today?