Skip to content
Sajith JeewanthaSoftware Engineer
All posts

1 min read

Portfolio v1.0.0 — from Django to a static Astro site

Why I rebuilt my portfolio as a static site, how the content is stored as JSON and Markdown, and what changed in the design.

  • #astro
  • #architecture
  • #devops

My first portfolio was a Django application: a PostgreSQL database on Supabase, logos in a Supabase storage bucket, a container on Google Cloud Run and Terraform running from GitHub Actions. It worked well, and building it taught me a lot about infrastructure.

But a portfolio is mostly read-only content that changes a few times a month. For v1.0.0 I asked a simple question: what is the least infrastructure that does this job well?

The new architecture

The site is now built with Astro and Tailwind CSS, and compiled to plain HTML at build time.

Before (v0) Now (v1.0.0)
Django + Gunicorn on Cloud Run Static HTML on a CDN
PostgreSQL on Supabase JSON files in Git
Logos in a Supabase bucket Images in the repo, optimised at build
Django admin dashboard Edit JSON / Markdown, commit, deploy

Content as data

Every section of the home page is a JSON file in src/data/, and each one is validated by a schema at build time:

{
  "id": "docker",
  "name": "Docker",
  "category": "devops",
  "logo": "docker",
  "visible": true
}

If I mistype a category or reference a logo that doesn’t exist, the build fails — so a mistake never reaches the live site. Blog posts like this one are Markdown files in src/content/blog/.

Design

The new look blends a modern AI / engineering aesthetic with subtle cathedral touches: stained-glass colours, a rose window whose tracery is drawn as a neural network, and pointed-arch frames. It supports light, dark and system themes.

Simple systems are easier to trust — and easier to keep running.

What’s next

  • More write-ups of my projects, starting with the API Shield Platform
  • Notes from my MPhil research on intelligent systems