Fastvest
Local-first portfolio tracker — open the app, see portfolio value and P&L, refresh market prices — no account and no server-side portfolio database.
- Stack
- Nuxt 4 · Vue 3 · TypeScript · Nitro · Tailwind CSS · shadcn-vue · Yahoo Finance · PWA · Vitest · Playwright
- Category
- Open Source · FinTech · Privacy
What shipped
- Local-first portfolio model — holdings live in browser localStorage and are never persisted server-side, logged, or sent to analytics.
- Server-side market-data gateway (Nitro API routes wrapping Yahoo Finance) with caching, timeout handling, and normalized errors.
- Cached stale-while-refresh quotes plus an offline PWA application shell.
- Zod schemas shared between client and server, with Vitest unit tests and Playwright end-to-end tests.
Fastvest is a local-first portfolio tracker. You open the app, your portfolio value and unrealized P&L are on screen immediately, and you can refresh market prices without creating an account — and without sending your portfolio anywhere. It is monitoring software for your own holdings, not financial advice.
The privacy model
Portfolio configuration lives only in browser localStorage. It is never persisted server-side, never logged, and never sent to analytics. Clearing browser storage removes your local portfolio unless you exported a backup. The only thing that travels is a market-data request; the server acts as a data gateway, not a portfolio store.
How it works
Holdings are entered and edited client-side — position count and cost basis per symbol, with no cost to record — and the portfolio and price data can be imported and exported as JSON. The UI shows total value, cost basis, unrealized P&L, today's P&L, an allocation view, and a sortable holdings table. A 60-second refresh cycle runs quotes through a stale-while-refresh strategy: cached prices render instantly while stale data revalidates in the background instead of blocking the screen.
Market data flows through Nitro API routes (/api/quotes, /api/search, /api/chart), which wrap Yahoo Finance with timeout handling, caching, and error normalization. Because the browser never talks to the data provider directly, quotes stay resilient to the flakiness of a third-party endpoint.
Engineering decisions
- Separating ownership from retrieval. Portfolio data and market data are different trust domains; keeping one client-side and the other server-side makes each boundary small and testable.
- Shared validation. Zod schemas are defined once and used on both sides, so client and server cannot drift on what a quote or search result looks like.
- Offline as default behavior. PWA application-shell caching means the app shell loads offline and previously cached prices remain visible.
- Testing the surface. Unit tests cover financial calculations and formatting; Playwright covers the flows that matter — launch, add a holding, refresh quotes.