Two months ago I posted a fairly standard SaaS portfolio tracker. The feedback was blunt but fair: asking people to upload their full financial transaction history into a random startup’s database is a bad trust model.
I listened and spent the last ~60 days undoing that decision. I deleted the database, removed signup entirely, and rebuilt the app to be 100% local-first. All portfolio data now lives in your browser (localStorage). No accounts, no backend storing trades.
While doing this rewrite, I realized the hardest part of the original system wasn’t charts or UI—it was parsing the inconsistent CSV exports from brokers. So I extracted that logic into a standalone, dependency-free npm package: @pocket-portfolio/importer, which currently handles CSVs from ~15 brokers (Robinhood, Fidelity, eToro, etc.).
Stack:
Frontend: Next.js 14 (App Router) + Tailwind
State: LocalStorage (custom hook for quota management)
Parsers: TypeScript (published to npm)
Hosting: Vercel (but added a Dockerfile for self-hosting)
pocketportfolio•1h ago
I listened and spent the last ~60 days undoing that decision. I deleted the database, removed signup entirely, and rebuilt the app to be 100% local-first. All portfolio data now lives in your browser (localStorage). No accounts, no backend storing trades.
While doing this rewrite, I realized the hardest part of the original system wasn’t charts or UI—it was parsing the inconsistent CSV exports from brokers. So I extracted that logic into a standalone, dependency-free npm package: @pocket-portfolio/importer, which currently handles CSVs from ~15 brokers (Robinhood, Fidelity, eToro, etc.).
Stack:
Frontend: Next.js 14 (App Router) + Tailwind
State: LocalStorage (custom hook for quota management)
Parsers: TypeScript (published to npm)
Hosting: Vercel (but added a Dockerfile for self-hosting)
Demo: https://www.pocketportfolio.app Source: https://github.com/pocket-portfolio/pocket-portfolio NPM: https://www.npmjs.com/package/@pocket-portfolio/importer