## Why Build Your Own Portfolio Instead of Using a Template?

Two reasons. First, a custom-built portfolio demonstrates real skills better than any resume. Second, building it taught me more than any tutorial.

My portfolio at nilesh.smportfolio.xyz has two modules — a public-facing site and a full admin panel. Here are the decisions behind it.

## Decision 1: ASP.NET Core MVC over React/Angular

I work in .NET. My strongest skills are in the .NET ecosystem. Building the portfolio in React would have taken twice as long and the result would have been mediocre compared to what I can do in ASP.NET Core.

**The principle:** Play to your strengths. A portfolio isn't the place to learn a new framework — it's the place to demonstrate mastery of the one you know.

## Decision 2: Dapper over Entity Framework

The data model for a portfolio is simple. Projects, skills, experiences, blogs, contact messages. No complex relationships. No heavy domain logic.

EF's overhead is justified when you have a complex domain. Here, it would have been unnecessary weight.

**Dapper gave me:**
- Faster queries
- Full control over SQL
- Stored procedures working cleanly

```csharp
public async Task<IEnumerable<Project>> GetVisibleProjectsAsync(int portfolioId)
{
    using var db = new SqlConnection(_conn);
    return await db.QueryAsync<Project>(
        "sp_GetProjectsByPortfolio",
        new { PortfolioId = portfolioId },
        commandType: CommandType.StoredProcedure
    );
}
```

## Decision 3: Stored Procedures for All Database Operations

This made sense for two reasons. One, I was coming off government project work where stored procedures were required — I was already thinking in that mode. Two, stored procedures give me a clean separation between application logic and data logic.

Every CRUD operation has a corresponding stored procedure. The naming convention is consistent: sp_GetX, sp_CreateX, sp_UpdateX, sp_DeleteX.

## Decision 4: Two-Module Architecture

**Public module:** read-only, cached where possible, optimized for performance
**Admin module:** full CRUD, JWT protected, separate area

Separating these from the start was the right call. Admin features would have polluted the public-facing code if I hadn't drawn a clear boundary early.

## Decision 5: SQL Server over MySQL

I know SQL Server better. My professional projects use SQL Server. For a personal project, using what you know deeply beats using something new superficially.

## What I'd Do Differently

**Add proper caching from day one.** The public portfolio makes the same database calls repeatedly. Redis or even in-memory caching would have improved performance significantly with minimal effort.

**Write tests.** I didn't write unit tests for the portfolio. I regret this whenever I make a change and have to manually verify everything still works.

**Better image management.** Currently images are stored on the server. A CDN or cloud storage (Azure Blob, AWS S3) would have been the right call for a production application.

## The Result

The portfolio is live. It has a proper admin panel where I can manage everything without touching code. Adding a new project, blog post, or experience takes 2 minutes.

More importantly — building it deepened my understanding of ASP.NET Core, Dapper, and SQL Server in ways that only shipping something real can do.

## Conclusion

Build your portfolio. Not to show employers — though that's a bonus — but because the process of making architectural decisions and living with the consequences is one of the best learning experiences available to a developer.