This site originally ran on a custom Node.js/Express server with Jekyll, hosted on Azure with an Nginx reverse proxy. You can read about that setup in the original post. It went offline sometime around 2014 and stayed that way for over a decade.
In 2026 I rebuilt it from scratch. The old content was preserved, the infrastructure was not.
What it is now
The entire site is static HTML generated by Astro. There is no server. The build takes under a second and produces a handful of HTML files that can be served from anywhere.
Source
Same repo as before: github.com/kaiwalya/kom.
git clone https://github.com/kaiwalya/kom.git
Project structure
src/
consts.ts # Site-wide constants (name, social links, nav)
content.config.ts # Blog collection schema (Zod)
content/blog/ # Markdown posts (frontmatter controls drafts)
data/resume.json # Structured resume data
components/ # BaseHead, Header, Footer, ThemeToggle
layouts/ # BaseLayout, BlogPost
pages/ # index, about, resume, blog/[...slug], 404, rss.xml
styles/global.css # CSS custom properties, reset, typography
How it works
Blog posts are Markdown files in src/content/blog/. Astroβs Content Collections validate frontmatter with a Zod schema at build time:
schema: z.object({
title: z.string(),
date: z.coerce.date(),
summary: z.string().optional(),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
})
Posts with draft: true show up during development but are excluded from production builds.
Styling
Vanilla CSS with custom properties. No framework. Dark mode respects your system preference and can be toggled manually β the choice persists in localStorage. The entire stylesheet is about 130 lines.
What was removed
- Node.js server and Express framework
- Nginx reverse proxy
- Azure Websites and Azure VM
- Docker container
- Jekyll static site generator
- Facebook authentication
- Google Analytics (the old Universal Analytics, which Google has since shut down)
- Loggly and New Relic monitoring
- Bower package manager
- 27 favicon files (replaced with one SVG)
What was kept
- All published blog content
- Resume data
- The repo and its git history
Development
cp .env.example .env
npm install
npm run dev
SITE_URL in .env is the only environment variable. The build fails if itβs missing.