DEV Community

Cover image for From a single-HTML-file finance app to a Notion template β€” lessons in shipping for usersπŸ₯Ή
Balaji K
Balaji K

Posted on

From a single-HTML-file finance app to a Notion template β€” lessons in shipping for usersπŸ₯Ή

I've spent 12+ years writing automation systems for production platforms β€” test frameworks, API testing pipelines, the kind of code that runs invisibly so people upstream can ship faster.

A few weeks ago I shipped Finfolio β€” a single-HTML-file personal finance tracker. No backend. No sign-up. Your data never leaves your browser. It tracks every asset class an Indian investor actually holds β€” mutual funds, SGBs, FDs, ESPP/RSU, PPF, NPS, real estate β€” pulls live NAVs from AMFI, has Gmail OAuth to auto-categorize bank alerts into expenses, and has an AI layer that analyzes your portfolio with your own API key.

Repo here. MIT licensed. Free forever.

This weekend I shipped a Notion template that does ~30% of what Finfolio does. And honestly, I think it might be more useful for more people.
Here's why.

The lesson Finfolio taught me

Finfolio works. I use it every day. People who like full-control technical tools genuinely like it.

But here's what shipping it taught me: most people don't want a tool. They want a system.

Finfolio asks: "What's your AMFI scheme code? Do you want to enable Gmail OAuth? Where do you want to host this β€” Netlify, Vercel, fly.io, or just open it locally?" Those are perfect questions for engineers. They're terrible questions for my mother-in-law who just wants to see if her FDs and SIPs are doing OK.

The friction wasn't bugs or features. It was that the bar for entry was "be technically curious enough to enable Gmail OAuth." That's a small population.

So I asked a different question:

What if I rebuilt the core of Finfolio in a tool people already open every day, with a structure flexible enough to bend around their needs instead of mine?

For me β€” and a lot of knowledge workers β€” that tool is Notion.
So I started over with a hard constraint: two databases, three pages, and formulas that do all the work. No script to run. No API keys. No deployment step. Just duplicate and use.


The constraint became the feature.

The architecture: 2 databases, 3 pages

Finfolio has 12+ asset class trackers, an expense module, a goals module, an alerts hub, and AI-powered analysis. It's a suite.
The Notion version is the opposite. Aggressively minimal:
WealthOS Lite/
β”œβ”€β”€ Dashboard (page)
β”‚ β”œβ”€β”€ Net worth callout
β”‚ └── Quick-start instructions
β”œβ”€β”€ Portfolio (database)
β”‚ β”œβ”€β”€ Asset Name (title)
β”‚ β”œβ”€β”€ Category (select: Stocks, Mutual Fund, FD, Gold, etc)
β”‚ β”œβ”€β”€ Invested Amount (number)
β”‚ β”œβ”€β”€ Current Value (number)
β”‚ β”œβ”€β”€ Gain/Loss (formula)
β”‚ └── Return % (formula)
└── Budget (database)
β”œβ”€β”€ Description (title)
β”œβ”€β”€ Type (select: Income, Expense)
β”œβ”€β”€ Category (select)
β”œβ”€β”€ Amount (number)
└── Date (date)
That's the whole thing. Two databases, three pages, six properties on Portfolio, five on Budget.

This was the hardest design discipline in the entire project. I've already built the complete version β€” Finfolio knows about insurance renewals, EMI calculators, gold purity, post office schemes. Adding any of that to Lite would be one afternoon's work.

But here's what I learned: the Lite version of anything is usually the better product. People who get value from 2 databases will reach for the 12-database version when they're ready. People who never start because the template is overwhelming never come back.

The 3 formulas that do all the work

Notion formulas are limited in ways that frustrate engineers β€” no recursion, no loops, no array methods on relations. Coming from Finfolio's JavaScript codebase where I can do anything, this felt like a downgrade.
It isn't. For personal finance, you don't need any of that. You need three formulas.


Formula 1: Gain/Loss

prop("Current Value") - prop("Invested Amount")
That's it. The interesting part isn't the formula β€” it's that Notion recalculates it the moment you change either input. No sheet refreshes, no "press F9 to recalculate," no broken cell references when you reorder rows.
In Finfolio, I had to write reactive state management to make this work. Notion gave it to me for free.

Formula 2: Return %
if(
prop("Invested Amount") > 0,
round(
((prop("Current Value") - prop("Invested Amount")) / prop("Invested Amount")) * 10000
) / 100,
0
)

Three things going on here:

Guard clause β€” if(prop("Invested Amount") > 0, ...) prevents division by zero when you create a new row before filling values.
The math β€” standard return percentage formula.
The round / 10000 * 100 dance β€” Notion's round() only rounds to integers. To get 2 decimal places, you multiply by 10000, round, divide by 100. Quirky but works.

The third bit is the kind of gotcha you only learn by hitting it. Notion's docs don't really call it out.

Formula 3: The conditional that handles asset-class quirks
This is the formula I'm proudest of, and it's worth sharing because it solves a common gotcha that bites every personal-finance template author.
When you add a Fixed Deposit to your portfolio, "Current Value" doesn't quite make sense β€” the value IS the invested amount until maturity. Same with cash holdings, recurring deposits, and bonds you're holding to maturity.

In Finfolio I solved this with conditional rendering and per-asset-class form fields. In Notion, one formula:
if(
empty(prop("Current Value")),
prop("Invested Amount"),
prop("Current Value")
)

Default to Invested Amount when Current Value is empty. Now FDs and cash holdings work correctly without users needing to type the same number twice. Small thing, big UX win.

The pattern from Finfolio that survived: smart defaults beat configuration every time.

The screenshot you don't see in product photos
Most Notion template marketing shows the dashboard view β€” clean, populated, looks great.

What it doesn't show is the Notion creator's secret weapon: linked database views.

The Portfolio database lives in one place. But on the Dashboard page, I render it again as:

A grouped view (by Category) with sum aggregations
A donut chart (Notion's chart blocks read directly from databases)
A filtered "top gainers" view

Same database, three different visualizations. Updating one row updates every view simultaneously, including the chart. No refresh, no sync, no broken state.

This is the same separation of concerns I'd apply to any system β€” model, view, controller. Notion just makes the "view" layer ridiculously easy.

In Finfolio I wrote ~400 lines of Chart.js and DOM manipulation to do what Notion gives me out of the box.

What I left out for v1 (and why)

This is where Finfolio's complexity contrasted hardest with the discipline a marketplace template requires.
I had a list of ~15 features I wanted to ship. I cut it to 6.
What didn't make it to Lite:

❌ Live price sync β€” needs a companion script. Out of scope for a free Notion-only template.
❌ Gmail OAuth for expenses β€” Finfolio's killer feature. Notion can't do OAuth flows. Will need a different solution.
❌ Multi-currency support β€” sounds simple, balloons fast. FX rates? Historical conversion? Display vs storage?
❌ Goals, SIP planner, tax modules β€” each is its own database. Pulled them out to keep Lite lite.
❌ AI analysis β€” Finfolio has it (bring your own key). Notion has Notion AI but the integration story for templates isn't clean yet.
❌ Mobile-optimized layouts β€” Notion handles this OK by default. Custom mobile design = duplicate page structures = maintenance burden.
❌ Auto-categorization β€” would need formulas with brittle string matching. Manual is fine for v1.

The rule I kept telling myself: "If I can't ship it cleanly in v1, it goes in the v2 backlog. Period."

Most template creators on the marketplace fail because they ship 40-feature behemoths nobody can figure out. The Finfolio version of WealthOS exists β€” it's the GitHub repo. The Notion version had to be different.

What "shipping" actually felt like

I want to be honest about this because dev.to readers are also makers, and we don't talk about it enough.
For Finfolio, I knew the workflow: write code, test, commit, push, deploy. Even when it took a weekend, the process was familiar.
For a Notion Marketplace template, the technical work was maybe 30% of the total time. The other 70% was things I genuinely didn't anticipate:

  • Naming things β€” went through 11 names before settling on WealthOS. Each rejection ("taken on Gumroad," "trademarked elsewhere," "weird connotation in Hindi") was its own time sink.
  • Designing covers and gallery images β€” Notion Marketplace requires specific dimensions (2048Γ—1280 desktop, 750Γ—1500 mobile) with strict safe-zone rules. Got rejected once for cropped content I thought looked fine.
  • Writing the description β€” version after version. The first draft was technical. The second was sales-y. The fifth one finally felt right.
  • Removing every promotional reference before submission. Notion's editorial guidelines flag templates that "primarily advertise paid products." Even one upgrade callout in the template body can trigger a rejection.
  • Setting up creator profile, banner, bio, social links β€” all the meta-stuff that has nothing to do with the product but determines whether anyone clicks.

Compared to Finfolio (where I just needed git push and a GitHub README), shipping a marketplace template is closer to launching a small product. The ratio of "actual building" to "preparing the building to be seen" was inverse to what I expected as an engineer.

What's next

WealthOS Lite is on Notion Marketplace as a free template β€” the foundation. Two databases, formulas, charts, your data stays in your workspace.

There's a Pro version I'm working on that connects back to the Finfolio architecture β€” a small Node.js companion app for live price syncing across stocks, mutual funds, and gold. Same "your data never leaves your machine" philosophy as Finfolio, but bridged into Notion. More on that when it's ready.

The bigger lesson from this whole exercise: the same problem can have radically different shapes depending on who you're solving it for. Finfolio is right for people who want full control. WealthOS Lite is right for people who want a clean system in a tool they already use. Neither is "better" β€” they're just for different people.

If you're building personal finance things, Notion templates, or anything else for non-technical users coming from technical roots, I'd love to compare notes.

Try WealthOS Lite (free): [https://stirring-heart-701.notion.site/WealthOS-Lite-34b3afb1ab1a81bf98f6e72a26551f50]
Finfolio (the original): github.com/balajiregt/myFinance
Building in public: @buildwithbalaji on X

I'm planning to write more about the engineering decisions behind shipping consumer-facing products as someone whose day job is automation infrastructure. If that's interesting, let me know what you'd want to read next.

Top comments (0)