What is mamen
Eight surfaces, and the path a bank row takes through them: imported, given an issuer and a category, then counted.
- Transactions
- The curation surface: a filterable table of every imported row. Give one an issuer, a category or a note, hold it out of the spend totals, or group several into a single operation.
- Transfers
- Movements between your own accounts. mamen suggests the debit and credit pairings and you confirm or dismiss them; a confirmed pair is held out of spend.
- Recap
- Where the money went over a month, a calendar year or all time, broken down by issuer and by category. Spend only, so transfers and excluded rows are reported beside the totals rather than inside them.
- Import
- Upload a statement, preview every row it will create, and commit. Nothing reaches the database until you do.
- Accounts
- The accounts you import into, and a grid of which months have landed for each.
- Issuers
- Who money goes to and comes from. Each one carries a default category, an image, and matching rules that assign it to new rows at import time and to old ones retroactively.
- Categories
- A tree of any depth. Only leaves are assignable and folders total their children; a row takes its category from its issuer unless you override it.
- Two statement formats
- CSV, parsed in the browser, with one bank's parser shipping and a module per bank after it. PDF, extracted by whichever AI provider you picked in Settings, staged in a temp directory and deleted afterwards.
Run it yourself
mamen is not hosted anywhere for you. Clone it, point it at your own bank exports, and it runs on your machine against one SQLite file.
- Bun 1.3.4 The runtime, the package manager and the test runner. The repo pins its version.
- portless (optional) Fronts each dev server at a name instead of a port, which is what the start command expects. Without it, the same servers run directly on the ports listed below.
- The claude CLI (optional) Needed by PDF import on its default provider, which hands it the statement. Pick a hosted vendor in Settings instead, and nothing needs it. Every other part of the app runs without it either way.
Clone and install
Bun installs every workspace in the monorepo — the API, the web app and this page.
git clone https://github.com/lucasriondel/mamen.git cd mamen bun installWrite the encryption key
The API reads its environment from a file beside it. Everything in there has a working default except the key that encrypts the AI provider credentials you paste into Settings, which has none on purpose.
# packages/api/.env TOKEN_ENCRYPTION_KEY=<64 hex characters — openssl rand -hex 32>Start it
One command runs every dev server through Turborepo. The database is created and migrated on first boot, seeded with a base category tree. The servers come up behind portless, each fronted at a name instead of a port; without it installed they run directly, at the second address listed below.
bun dev
- web
https://mamen.localhost/app/http://localhost:5070/app/The app itself, under the prefix it is served at in production too. - API
https://api.mamen.localhosthttp://localhost:5500The HTTP API, with its Scalar docs and the OpenAPI spec it emits. - landing page
https://landing.mamen.localhosthttp://localhost:5080This page, as the deployed site serves it at its root.
TOKEN_ENCRYPTION_KEYThe one setting with no default, because a default would be a published encryption key. The app starts without it and every feature but AI credentials works.
How to contribute
The repository is public because there is no reason for it not to be, not because it is looking for users. There is no roadmap, no release cadence and no support promise, and the maintainer is one person.
Bug reports are welcome, and so is a parser for another bank's export — that is the one extension point the code is deliberately shaped for. Read the guide before spending time on anything larger.

