How my website works
October 26, 2023 · 4 min read

My website costs me $0 to run. Except for the domain which costs ~$12/year, I don't pay for anything else. Below are some of the stuff I did to make sure I don't have to worry about anything and focus on writing.

The stack

Next.js is probably one of the best things to happen to the React ecosystem. I have on days complained about how the ecosystem has evolved into an unnecessarily complex thing where you have to install a bunch of npm packages to build a simple form, but the Next framework has stayed simple and easy to use.

Tweet by @html_orgTweet by @html_org

I learned web development with PHP, so some of the stuff like React Server Components makes me wonder what was even the point if it was going to come back to where it started, but that is a question for another post. I did build an initial version of this website in Laravel but quickly migrated to Next because I felt front-end development with Blade had become incredibly complex and not something that I was used to. Also, PHP requires you to deploy to a proper server but with Next, I can do away with Vercel's generous free tier.

I use tailwind for styling. It is incredibly good and takes care of bundling and removing unused CSS so that I don't have to worry about it.

Writing

I hate complexity. In any software I build, I try to keep the architecture as minimal as possible without losing sight of the goal. I want a space where I can focus on writing instead of making a complex beast that creates more problems than it solves. So, when I wanted to write, I decided to go with the simplest of it all - Markdown

I have a directory in my codebase called posts which looks something like this -

├── posts
    ├── 001-hello-world.mdx
    ├── 002-git-reset-hard.mdx
    ├── 003-authenticating-sw-requests.mdx
    └── 004-better-indexeddb.mdx

and a script that loops through the directory and builds a type-safe JS array. How do I do that? Using a library called contentlayer. Each MDX file has the same format -

---
title: "Blog Title"
createdAt: 1970-01-01
---

<!-- Markdown content -->

Contentlayer helps convert this into JSON -

{
  "title": "Blog Title",
  "createdAt": "1970-01-01",
  "body": "" // markdown content
}

This is done at build time so there's no runtime generation of content, waiting for it to load over a slow network. The JSON is importable like a normal static file. The name of the file becomes the slug. 001-hello-world.mdx becomes /blog/hello-world and so on.

Markdown is incredibly powerful for writing, I can have images, bullet points, tables, code snippets and a lot more. I do not have to worry about building a CMS platform that has a complex text editor that will let me do the same thing - write in markdown and convert to HTML. This way, I cut the middleman and write content directly. Reduces the final bundle and makes the site snappier.

Performance, Analytics & other stuff

Not to sound braggy, but -

Chrome Lighthouse metricsChrome Lighthouse metrics

It does take quite an effort to make websites fast, but 2 things helped - keeping the UI minimal and ~5 years of experience building fast websites and optimizing for performance. It's not the fastest website, but it's fast enough.

Vercel Analytics is pretty useful and free for something that's a hobby. Both Vercel deployments and analytics have a very generous free tier.

I get 6000 build minutes per month and an average build takes ~30-45 seconds. So I'm never going to exceed the free tier anytime soon. And if my website does happen to get more than a million views (which is a big IF), I would be more than willing to pay the $20 fee for a pro plan.

Future

Commenting on posts might be good, but it would involve setting up authentication and a whole bunch of stuff to safeguard users and myself from spam. So it is on hold for now.

Upcoming changes would be

  • SEO-related changes like description, banner images etc
  • RSS feed & newsletter allowing users to subscribe to new posts