Poveroh is an open-source, web-based platform for tracking personal finances.
This platform was born from the desire to track personal finances in a detailed and structured way.
Ok, there are thousands of similar applications out there, but none of them truly fit certain needs. Many lack a clean and intuitive UI/UX, and the few that do are often expensive—locked behind subscriptions or premium plans. That’s why this project was started - it aims to provide a scalable, open-source alternative that is easy to use, fast, and flexible—built with simplicity and clarity in mind.
This platform is essentially a web-based version of a Google Spreadsheet finance tracker, enhanced with features to make everything more user-friendly (the mobile app is planned and is included in the roadmap :) ).
The platform aggregates multiple bank accounts.
Users can manually input transactions or upload them via CSV or PDF.
Since it’s designed to track personal wealth, a snapshot of the month (including investments) will be taken on the last day of each month. This allows users to keep a historical record, generate reports, and monitor the growth of their assets over time.
In addition to individual transactions and bank account aggregation, the goal is to provide a platform for tracking investments as well, allowing to add financial products such as ETFs, stocks, bonds, crypto, and more.
Note: Since this platform was designed based on personal needs, it may not be fully complete or include all the features that other users might consider essential.
If you notice something missing from the roadmap or have an idea you’d like to see implemented, feel free to open an issue and share your suggestion!
Poveroh uses a modular monolith backend: the API remains simple to self-host and operate, while the code is organized around finance domains instead of broad technical layers.
Backend modules live under apps/api/src/api/v1/modules/. A module owns its HTTP controller, service workflow, repository queries, Zod schema exports, response mapper, and local types. Existing route paths stay REST-compatible, but new backend work should grow inside modules such as financial-accounts, categories, subscriptions, transactions, imports, snapshots, dashboard, and reports.
The layer boundaries are intentionally explicit:
- Controllers handle HTTP concerns only: parsing request data, validating with Zod schemas, extracting the authenticated user, calling services, and returning
ResponseHelperenvelopes. - Services contain business workflows, ownership decisions, file handling orchestration, calculations, and lightweight domain event emission.
- Repositories are the only layer that talks to Prisma. They centralize
select/includeshapes, filtering, pagination, ownership scoping, soft-delete filters, and transactions. - Mappers convert database records into API DTOs so raw Prisma entities are not exposed directly.
Prisma access is isolated behind repositories. Repository methods must scope financial data by userId and automatically exclude records with deletedAt unless a workflow explicitly needs historical records. Financial history is soft-deleted by default so transactions, subscriptions, accounts, assets, and snapshots remain auditable.
Reusable contracts and validation live in packages/schemas and are shared by OpenAPI generation, API validation, and frontend forms. API responses use the standard envelope:
{
success: boolean
message?: string
data: T
meta?: {
pagination?: PaginationMeta
}
}The backend also includes lightweight internal domain events in apps/api/src/api/v1/shared/events. Events such as transaction.created, financial-account.updated, and snapshot.generated carry minimal IDs and user scope so side effects like cache invalidation, dashboard refreshes, analytics, or background jobs can evolve without coupling them directly to write services.
Dashboard and report features follow a CQRS-light approach: CRUD services handle write workflows, while dashboard/report modules should own read models and financial aggregations. Snapshots represent historical wealth state and should be treated as immutable financial records once generated.
Poveroh uses BullMQ for background jobs, with the implementation isolated behind @poveroh/queue. Application and domain code depend on a small JobDispatcher interface instead of importing BullMQ directly, so a future RabbitMQ adapter can replace the BullMQ adapter without changing services, controllers, or job payload contracts.
The queue package is organized around explicit contracts:
packages/queue/src/interfaces/defines the provider-agnostic dispatcher API.packages/queue/src/jobs/defines the typed job registry and payloads.packages/queue/src/adapters/bullmq/contains all BullMQ-specific code.apps/worker/consumes jobs and calls application services to execute workflows.
Redis configuration is reused from the existing API Redis infrastructure in apps/api/src/utils/redis.ts. The API exposes the same Redis URL/password configuration used by the cache client, and the BullMQ adapter receives that configuration through the queue abstraction. New queue code should not read Redis env values independently or introduce a parallel Redis configuration system.
Domain events and background jobs are intentionally separate:
EventEmitteris for lightweight local reactions such as cache invalidation, websocket updates, and synchronous side effects.- BullMQ jobs are for heavier or delayed workflows such as imports, snapshot generation, market sync, notifications, cleanup, and scheduled processing.
Workers should orchestrate workflows and call services; they must not access Prisma directly or duplicate business logic. Scheduler code lives under apps/worker/src/scheduler/ so cron-like behavior does not leak into domain services.
| Color | Hex |
|---|---|
| Primary Color | #4E594A |
| Secondary Color | #278664 |
| Background Color | #1C1C1C |
| Text Color | #FFFFFF |
To get a local copy up and running, please follow these simple steps.
This project uses:
-
Clone the project
git clone https://github.com/Poveroh/poveroh.git
-
Go to the project folder
cd poveroh -
Install dependencies
npm install
-
Copy
.env.examplefile to.env, then edit it with the necessary values. For more details, read docs.If you don't modify them, the default values are sufficient to run the project.
Warning: Since these are default values, security is not guaranteed.
Environment Files: The project uses a dual environment system:
.env- For local development (DATABASE_HOST=localhost:5432).env.production- For Docker deployments (DATABASE_HOST=db:5432)
Running
npm run setupwill automatically create both files from.env.example.
Docker and Docker Compose must be installed, up, and running on the machine.
-
Run
setupfilenpm run setup
Note: the setup flow may create a small local
proxyservice and to make local subdomains work you may need to add host entries (the repository includesscripts/setup/proxy.jswhich can add them for you).The command will execute the following steps:
- Create and run database docker image.
- Navigate to the
packages/prismadirectory. - Generate the Prisma client.
- Apply any pending migrations to the database using Prisma.
- Create and run CDN ngix docker image.
⚠️ Warning:
If you encounter any difficulties or something doesn't go as planned, read this file to execute it manually. -
Create a user; open a browser to localhost:3000/sign-up and sign up.
-
Optionally, you can run the following exactly script to generate and fill database with fake data:
npm run setup:data --user=<user_id_created_before>
You can find user ID on the personal information page
-
Build project
npm run build
-
Run project
npm run dev
-
First of all, create a folder
mkdir poveroh-selfhost
-
Navigate to this folder using the cd command.
cd poveroh-selfhost -
Download setup file
curl -fsSL -o setup.sh https://raw.githubusercontent.com/Poveroh/poveroh/refs/heads/main/scripts/docker/setup.sh
-
Make it executable
chmod +x setup.sh
-
Then run it
./setup.sh
The script will create
.envfile. If you do not modify it, the default values are sufficient to run the project.If you want to build and run from scratch, download the repo (run only Get start steps to download and setup), then run
npm run docker-dev
This repository follows the GitHub approach.
The development branch is main.
For more info, read the docs.
In running order:
- Login
- Categories & subcategories
- Bank accounts
- Subscriptions
- Transaction
- Manual insert
- Upload from CSV or PDF
- Month's snapshot
- Reports
- Investments
- Mobile app (iOS/Android) [probably in Flutter]
To give it an extra boost:
- Live investments
- What if: Based on monthly or annual spending, determine what you could have afforded if you hadn’t spent that money. This can help evaluate whether it’s necessary to reduce spending in non-essential categories to achieve certain goals.
- Memes
- Open banking
Poveroh is released under the GNU Affero General Public License v3.0 (AGPL-3.0).
See LICENSE.txt for more information.

