Before Writing Any Code: How I Laid the Foundations of My Portfolio & Risk Tracker SaaS

The project barely exists: a simple Next.js home page and a few empty F# projects. And yet, the most important part is already done. Before writing any feature, I focused on building solid foundations. Here’s how I prepare a SaaS so it stands tall from day one.

Published on December 2, 2025

Before Writing Any Code: How I Laid the Foundations of My Portfolio & Risk Tracker SaaS

When people talk about a new SaaS, they usually start with screenshots, features, demos.

My project doesn’t have any of that yet.
Right now, the Portfolio & Risk Tracker is nothing more than a minimalist Next.js home page and a few freshly created F# projects.

And yet, this is precisely when the most important decisions were made.

In this article, I’m not showing features — I’m sharing the thinking process.
Because designing the foundations is a crucial part of the Tech Lead mindset: build first, code second.


1. Starting with the “Why”

Before choosing frameworks or generating boilerplate code, I had to clarify what I truly wanted to build.

The initial need was simple:
a tool to track investments and understand risk clearly and intuitively, without fragile spreadsheets or overly complex platforms.

From there, the long-term ambition emerged:
a freemium SaaS, with a solid free tier and premium features for users who need deeper insights.

This early reflection helped define:

  • the target audience,
  • the long-term vision,
  • what should be built now vs. later,
  • and the scope for the first milestones.

Without this step, feature creep would have been immediate.


2. Designing the architecture before the codebase

Before opening VS Code, I defined the structure:

  • F# for the core domain,
  • C# for the API,
  • Next.js 15/16 for the frontend,
  • a monorepo to keep the whole system cohesive.

This setup is not over-engineering.
It serves three goals:

Simplicity

The domain stays independent.
The API remains replaceable.
The frontend can evolve freely.

Testability

F# encourages pure functions and predictable logic — perfect for rules, computations, and modelling.

Scalability

I don’t know yet how big this product might grow, but I want to stay ready for:

  • a potential gRPC API,
  • a second SaaS using the same backend,
  • modular or multi-tenant evolution.

The architecture shouldn’t restrict the future.


3. Why F# for the domain?

Portfolio & Risk Tracker is all about business rules, transformations, and financial calculations.
F# shines in these situations.

Key reasons:

  • expressive domain modelling,
  • no null issues,
  • pipelines and function composition,
  • built-in Result and Option types,
  • short, clear, maintainable logic.

This is not a niche decision.
It’s a practical one: F# reduces noise and increases correctness, which matters deeply in finance-related code.


4. Why C# for the API?

While F# excels at domain logic, C# remains the best tool for the API layer:

  • excellent ASP.NET Core integration,
  • mature ecosystem,
  • abundant documentation,
  • straightforward onboarding for other developers,
  • natural evolution toward gRPC.

F# defines the intent.
C# exposes it cleanly to the outside world.


5. Next.js 15/16, Tailwind and shadcn: A modern foundation for the frontend

For the frontend, I wanted a stack that was:

  • modern and fast,
  • friendly to server components (RSC),
  • flexible for design work,
  • ready for multilingual content,
  • easy to iterate on.

Next.js 15/16 fits perfectly.
Combined with TailwindCSS and shadcn/ui, it gives me:

  • rapid prototyping,
  • consistent styling,
  • a clean dark/light mode system,
  • responsive layouts by default,
  • designer-friendly component structure.

It’s a solid UI foundation before any real features exist.


6. Database choices: Starting with Neon, but keeping the decision open

I’m starting with Neon, a modern serverless Postgres.
But this is not a fixed choice.

Depending on the evolution of the SaaS, migrating to:

  • Azure Postgres,
  • Supabase,
  • Render,
  • or a managed instance
    would be completely viable.

The goal at this stage isn’t to pick “the best” database,
but to avoid locking the project into a provider too early.

Using plain Postgres ensures portability.

I also structured the database with multiple schemas (prt, auth, billing)
to prepare the ground for premium features and potential multi-tenant needs.


7. Monorepo vs multi-repo, single-tenant vs multi-tenant: A real hesitation

Like any Tech Lead preparing a long-term project, I faced architectural choices.

Monorepo or multi-repo?

A monorepo:

  • simplifies onboarding,
  • ensures consistency,
  • works well with devcontainers,
  • keeps the whole project coherent.

A multi-repo becomes relevant if the backend or F# engine becomes a standalone product.

For now, simplicity wins:
monorepo, but with an architecture that can split later.

Single-tenant or multi-tenant?

The MVP will be single-tenant — easier, faster, fewer moving parts.

But the domain and database layout are already prepared for future multi-tenancy without rewriting the whole system.

It’s about flexibility, not premature complexity.


8. Devcontainer: Thinking team-first, even when working alone

I could work without it.
But using a devcontainer gives me:

  • a fully reproducible environment,
  • identical tooling everywhere,
  • a seamless mix of Node.js + .NET,
  • easy onboarding for designers and developers,
  • smooth support for Codespaces.

Even as a solo developer, I prepare the project as if someone else might join tomorrow.

That’s part of building sustainable software.


9. A realistic roadmap: progress through small increments

To avoid the classic SaaS “tunnel effect”, I divided the journey into three stages:

MVP

  • add assets,
  • view portfolio,
  • basic performance indicators.

Risk analysis

  • simplified volatility,
  • per-asset risk,
  • global risk view.

Premium

  • projections,
  • alerts,
  • advanced analytics,
  • exports.

It keeps the scope focused while ensuring real progress.


10. Acting as a Tech Lead before writing real features

What I’ve done so far isn’t “coding”.
It’s engineering.

A SaaS doesn’t start with UI screens or endpoints.
It starts with:

  • purpose,
  • architecture,
  • clean project organisation,
  • a reproducible development environment,
  • choices made deliberately,
  • hesitations resolved consciously,
  • room for future evolution.

This invisible phase is essential — and an integral part of how I work.


Conclusion — The project is almost empty, but already stands strong

Today, the Portfolio & Risk Tracker has no visible features.
But it already has:

  • a clear vision,
  • a healthy architecture,
  • a structured F# domain,
  • a flexible C# API,
  • a modern Next.js frontend,
  • a reproducible environment,
  • well-thought technical choices,
  • a realistic roadmap.

The code will come later.
The foundations are in place.

Over the next weeks, I’ll share deeper articles on specific decisions:
why I modelled the domain in F#, how I built the multi-stack devcontainer,
and what an eventual shift to multi-tenant architecture could look like.

The SaaS is still in its infancy — but its structure is already solid.