Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Chart Of Accounts Laravel Package

alimarchal/laravel-chart-of-accounts

Professional-grade Chart of Accounts and double-entry accounting module for Laravel with one-command install. Supports Jetstream and Breeze, a versioned REST API, 10 financial reports, role-based permissions, and balance enforcement at the database and application layers.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The package is a full vertical slice for a Laravel monolith: service layer + Actions pattern, Eloquent models mapped to accounting_* tables, a versioned REST API, and a dual frontend driver (inertia for React/Breeze, blade for Livewire/Jetstream). That is architecturally aligned with a conventional Laravel app and would be a hostile fit for a service-oriented or event-sourced ledger design.
  • Data model is standard and legible: AccountingPeriod, ChartOfAccount (hierarchical), JournalEntry/JournalEntryLine, Currency with fx_rate_to_base, TaxCode/TaxRate, CostCenter, AccountBalanceSnapshot, AccountingAuditLog. A TPM can map these to requirements without reverse-engineering.
  • Correctness posture is the strongest signal: balance enforced at DB layer, application layer, and UI (draft save disabled until debits = credits), plus post/void/reverse semantics rather than destructive edits — the right lifecycle for a ledger.
  • Dependency footprint is heavier than a "chart of accounts" package implies: Spatie Permission, Spatie Activity Log, jQuery 3.5.1 and Select2 4.1.0 published into public/vendor/accounting/, plus "database objects (stored procedures, views, triggers)." The last item is the most consequential architectural coupling and is the first thing to interrogate.
  • JournalEntry::record() is a two-line convenience API (one debit account, one credit account, single amount). Useful for simple GL postings; insufficient for multi-line vouchers, tax splits, or invoice-level AR/AP. Treat it as sugar over the service layer, not the integration surface.

Integration feasibility

  • Install is a single artisan command, but accounting:install is 11 mutating steps against the host application: publishes and runs migrations, publishes Spatie migrations if absent, seeds master data, syncs DB objects, and assigns super-admin to the first user. In a greenfield app this is convenient; in an existing app it is an unacceptably broad blast radius and must be decomposed manually (vendor:publish, review migrations, run accounting:seed separately, assign role deliberately).
  • Host-app coupling points, all requiring review: HasRoles added to the User model; hardcoded ['web','auth'] middleware (no documented hook to append tenant, audit, or MFA middleware); fixed route names accounting.* even when the URL prefix changes.
  • Frontend choice (ACCOUNTING_UI_DRIVER) is a pre-install decision. There is no documented path to switch drivers after install — an operational trap worth designing around up front.
  • API exists and is documented with resources, filters, sorting, and pagination, which is a real differentiator at this price point. Authentication is stated only as Authorization: Bearer {token}; whether that is Sanctum, Passport, or hand-rolled is unstated — a blocking question for any SPA or external integration.
  • Documentation inconsistencies that predict integration friction: the config block defaults api_prefix to api/v1/accounting while the README declares the base URL as /api/accounting/v1; the package description advertises multi-company, AR/AP, payroll, tax, and WhatsApp, while the README substantively covers COA, journals, periods, and reports only. Description-vs-docs drift is the single clearest vaporware risk here.

Technical risk

  • Vendor concentration: 5 stars, 0 dependents, one author with a personal email as the support channel. There is no production social proof, no third-party knowledge base, and no second maintainer. Bus factor is 1.
  • Self-graded quality: the README's "Quality Score: 9.2/10" is author-authored marketing, not an independent audit. It should carry zero weight in a procurement decision; the CHANGELOG, the test suite, and CI status are the actual evidence.
  • Scope overreach: claiming payroll, AR/AP, multi-company, and WhatsApp messaging in the package description while documenting none of them suggests either an aspirational roadmap or unpublished surface area. For a TPM this is a scoping hazard — do not plan against the tagline.
  • Database object dependency: stored procedures, views, and triggers created by accounting:sync-db-objects are the highest-risk architectural element. They constrain DB portability (SQLite/Postgres parity unverified), introduce invisible behavior outside migrations, complicate blue/green and read-replica deploys, and can silently drift after a package upgrade.
  • Balance enforcement bypass: DB-level constraints mitigate, but any code path that writes JournalEntryLine directly rather than through the service layer is a correctness hazard. Whether model events or guards block direct writes must be verified, not assumed.
  • Upgrade overwrites customization: accounting:update re-publishes views, assets, config, and JS. If the team customizes published views in place, upgrades will silently revert them. Customization must be confined to overrides outside the publish paths.
  • Asset supply chain: jQuery 3.5.1 is the last 3.x release (functionally fine, but dated) and is vendored into public/; a CDN fallback exists. Acceptable, but it means the accounting UI drags a legacy jQuery stack into an otherwise modern app, and the fallback introduces an external runtime dependency.
  • Missing ledger capabilities not mentioned: FX revaluation, multi-currency settlement, allocation/reconciliation of AR/AP, entry-number sequencing under concurrency, and backdating rules against closed periods are all unverified and are exactly where ledgers break in production.

Key questions

  1. What is the actual test suite — Pest/PHPUnit counts, coverage, CI badge, static analysis (PHPStan/Larastan) level? Can we see a green pipeline rather than a README score?
  2. Which features genuinely ship today: multi-company/tenant scoping, AR/AP subledgers, payroll, tax filing — or are the description's claims roadmap items?
  3. How is the API authenticated in practice (Sanctum? Passport? custom guard), and how is authorization applied per token scope?
  4. What exactly do the "stored procedures, views, triggers" do, and are they supported on PostgreSQL, MySQL 8, and SQLite? What happens on a DB engine we standardize on that the author did not test?
  5. Are posted journal entries immutable at the database level, and can any code path write lines outside the balance-enforcing service?
  6. Is there a published semver / BC-break policy, and what is the upgrade cadence? What is the author's support commitment and SLA, commercially or otherwise?
  7. How is entry numbering allocated under concurrency, and what prevents duplicate or gapped sequences?
  8. What is use_permissions behavior when the host app already runs its own RBAC — coexistence or collision?
  9. What is the retention/audit story: is accounting_audit_logs hash-chained or otherwise tamper-evident for audit or regulatory review?

Integration Approach

Stack fit

  • Best fit: a single-tenant, Laravel 11/12 monolith, MySQL or PostgreSQL, one company, standard COA, GL journals plus financial statements — the exact shape the README documents. Value is high here; the team avoids building double-entry correctness, period close, and ten reports from scratch.
  • Poor fit: multi-tenant SaaS (no documented tenant isolation despite "multi-company"), event-driven or microservice architectures, non-Laravel services needing ledger access, or any environment with an external auditor imposing tamper-evident controls.
  • Two valid adoption postures:
    • Embedded: install into an existing internal app as the accounting back office. Fastest time-to-value; highest coupling.
    • Isolated ledger service: stand up a dedicated Laravel app whose only job is accounting, expose the package's REST API to other systems, use JournalEntry::record()/the service layer for programmatic postings. Higher setup cost, dramatically lower blast radius, and the posture a TPM should default to. It also makes eventual replacement a routing change rather than a rewrite.

Migration path

  • There is no data-migration story in the docs: no importer, no mapping from an incumbent COA, no opening-balance procedure beyond seeding. Any migration from an existing system is bespoke work and must be scoped explicitly — map legacy accounts to the seeded COA, load opening balances as a single balanced opening journal per period, then replay open items.
  • Recommended migration of the codebase itself: pin an exact version, fork or vendor the package to an internal namespace/registry, and wrap every access point behind an internal Ledger interface (post entry, reverse, void, trial balance, GL) so the package is never called directly from domain code. This is the cheapest insurance available and costs days, not weeks.
  • Customization policy from day one: never edit published views/config in place; override at the app layer, and treat accounting:update as a reviewed change requiring a diff of republished assets.

Compatibility

  • PHP ^8.2 and Laravel 10–13 is a wide supported matrix — good for a team mid-upgrade, bad in that it implies none of the combinations is exhaustively tested. Pin to the combination you actually run and prove it in the spike.
  • Conflicts to check before committing: existing Spatie Permission installation and role naming (super-admin assignment is presumed), existing Activity Log configuration, an existing User model with its own RBAC, existing /accounting or /settings route collisions, and existing jQuery/Select2 versions in the host app.
  • The inertia vs blade decision must be made at kickoff and recorded as an ADR; reversing it later is an uninstall/reinstall, not a config toggle.

Sequencing

  1. Read-only spike (2–3 days) → verify: fresh Laravel on your target DB, installer decomposed manually, migrations reviewed, no unexpected DB objects, accounting:verify and accounting:health-check pass.
  2. Fork-and-pin + Ledger wrapper (3–5 days) → verify: your domain code compiles against your own interface, zero direct package references outside the adapter, contract tests green.
  3. Correctness proof (3–5 days) → verify: hand-computed trial balance, balance sheet, and income statement reconcile to the package's reports for a fixed fixture set; period close/reopen and backdating behave as specified; posted entries are provably immutable.
  4. AuthZ/tenancy integration (3–5 days) → verify: API token auth working, middleware extension point confirmed or a workaround documented, role mapping to the host app's roles, tenant scoping decision recorded.
  5. Pilot in one internal app behind a feature flag (2–4 weeks) → verify: real postings, real period close, accountant sign-off, runbook written.
  6. Go/no-go → promote, keep as isolated service, or replace with the internal interface intact.

Operational Impact

Maintenance

  • Ongoing cost is dominated by two things: upgrade re-publication (views/assets/config overwritten by accounting:update, requiring a diff-and-restore discipline each time) and DB-object drift (triggers and procedures outside the migration ledger). Budget a named owner and a per-upgrade checklist; this is not a "composer update and forget" dependency.
  • Pinning is mandatory. Given a single maintainer and an unpublished BC policy, floating version constraints are an unacceptable operational risk.
  • The fork is the real maintenance artifact. Once forked, you own merges — roughly 0.5–1 engineer-day per upstream release to review, and a standing obligation to track upstream security fixes in jQuery/Select2 and Spatie dependencies.

Support

  • Support model is effectively "email the author." There is no vendor SLA, no paid tier documented, no issue-tracker responsiveness history to inspect given 5 stars and 0 dependents. Any production incident traces to a single individual in an unknown timezone.
  • Mitigation: fork ownership sits with the internal team; the Ledger interface bounds the worst case to reimplementing an adapter rather than an application. Treat the author as a supplier of source code, not a support contract.
  • Accountant involvement is non-optional and should be staffed from day one: the seeded COA, tax codes, and period conventions are the author's defaults (defaults lean Pakistani: base currency PKR, account codes 1101/3101/5201) and must be reviewed and re-seeded for your entity.

Scaling

  • Read path is the constraint: GL reports aggregate over accounting_journal_entry_lines, which grows monotonically. AccountBalanceSnapshot plus accounting:rebuild-snapshots is the intended escape hatch; whether reports actually use snapshots or recompute from lines is unverified and determines whether reporting stays fast past a few million lines.
  • Stored procedures concentrate report computation in the database — potentially efficient, but it means report latency scales with DB instance size and is invisible to PHP-level profiling. Capacity planning must target the database, not the app tier.
  • No documented support for partitioning, read replicas, or queue-based report generation. For a mid-size single-company ledger this is likely fine; for high-volume or multi-entity deployment, plan to benchmark before committing.
  • UI scaling is a lesser concern, but jQuery/Select2 dropdowns populated with full account and cost-center lists are a known pattern for slow pages at large COA counts — worth measuring against a realistic COA.

Failure modes

  • Installer run against an existing app: mutates schema, seeds master data, and grants super-admin to the first user. Highest-severity footgun; never run on shared or production environments. Decompose the 11 steps.
  • Upgrade silently reverting customizations: views/assets/config overwritten by accounting:update; user-facing regressions discovered post-deploy.
  • Unbalanced postings via direct model writes: bypassing the service layer defeats the invariant; DB constraints must be proven to catch it.
  • Period-boundary errors: backdating into closed periods, and close/reopen races if more than one operator manages periods concurrently.
  • Stored-procedure/trigger drift: after upgrade or a DB restore, reports or constraints silently misbehave with no application-level error.
  • Concurrency on entry numbering: duplicate references under parallel postings if allocation is read-then-write.
  • RBAC collision: package permissions shadowing or conflicting with the host app's existing role model after HasRoles is added to User.
  • Auth gap on the API: an under-specified bearer-token scheme shipping with permissive defaults would be the most damaging possible failure; verify before exposing any endpoint.

Ramp-up

  • A competent Laravel engineer reaches productivity in roughly 2–3 days: the README is unusually thorough (install, three posting paths, full API table, config, artisan commands, permissions matrix), and the service/Actions structure is idiomatic. The gap is not the docs — it is the absent community, so every non-documented behavior becomes an email or a source read.
  • Expect a further 3–5 days for the team to internalize accounting semantics (period state machine, post/void/reverse, snapshot rebuild, fiscal-year close) — this is domain ramp-up, not package ramp-up, and it is unavoidable regardless of build-vs-buy.
  • Onboarding artifacts the TPM should require before the pilot exits: an ADR for driver and posture, an upgrade runbook, a period-close runbook, an incident playbook for report/balance discrepancies, and a documented mapping from package permissions to internal roles.

TPM recommendation Buy-and-harden, scoped. Building COA + double-entry + period close + ten financial reports + RBAC + REST API in-house is realistically 10–16 engineer-weeks of parity work; this package plausibly delivers 60–70% of that for zero license cost. The trade is a single-maintainer dependency and deep database coupling. That trade is acceptable for an internal, single-entity back office deployed behind an internal Ledger interface with a pinned fork. It is not acceptable, on current evidence, for multi-tenant SaaS, external-facing financial products, or any context requiring tamper-evident audit — those need the key questions answered and probably upstream hardening before commit.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo