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
ResultandOptiontypes, - 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.