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.