Building This Website with Eleventy and Bulma

Lasantha Kularatne posts tech web development eleventy

After years of writing on Medium and creating internal documentation at work, I decided it was time to build my own personal website. As someone who values simplicity and maintainability in system design, I wanted the same principles to apply here.

Why Build a Personal Site?

Throughout my career, I've benefited enormously from engineers who shared their knowledge publicly. From blog posts that helped me understand distributed systems to open-source tools that accelerated my work, the community has given me a lot. This site is my way of contributing back.

Plus, having a central place to share my thoughts on AI/ML, SRE practices, and software architecture felt overdue.

The Tech Stack

Eleventy (11ty)

For the static site generator, I chose Eleventy. Here's why:

  • Zero client-side JavaScript by default - Fast, accessible pages
  • Flexible templating - Supports Nunjucks, Markdown, and more
  • Simple data cascade - Easy to manage global and page-specific data
  • Great developer experience - Fast builds and hot reloading

Having worked with complex build systems at scale, I appreciate Eleventy's simplicity. The configuration is minimal yet powerful:

module.exports = function(eleventyConfig) {
  eleventyConfig.addPassthroughCopy("src/assets");

  eleventyConfig.addCollection("posts", function(collectionApi) {
    return collectionApi.getFilteredByGlob("src/blog/posts/*.md")
      .sort((a, b) => b.date - a.date);
  });

  return {
    dir: { input: "src", output: "_site" }
  };
};

Bulma CSS

For styling, I went with Bulma - a modern CSS framework that's:

  • Pure CSS - No JavaScript dependencies
  • Modular - Use only what you need
  • Responsive - Mobile-first design out of the box
  • Beautiful defaults - Looks great with minimal customization

Loading it via CDN keeps things simple:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css">

Alpine.js

For the bits of interactivity I needed (mobile menu, image lightbox), Alpine.js is perfect:

  • Lightweight - Just 15KB minified
  • Declarative - Behavior lives in your HTML
  • No build step - Works directly in the browser

Project Structure

I organized the project to be intuitive and maintainable:

src/
├── _data/          # Global site data
├── _includes/      # Layouts and partials
├── assets/         # CSS, images, etc.
├── blog/           # Blog posts in Markdown
├── photography/    # Photo gallery
├── resume/         # Resume page
├── about.njk       # About page
└── index.njk       # Home page

Built with AI Assistance

I used Claude Code to help scaffold and iterate on this site. It's a great example of how AI tools can accelerate development - from generating boilerplate to debugging CSS issues. As someone who's led AI adoption initiatives, I practice what I preach.

Lessons Learned

  1. Start simple - You can always add complexity later
  2. Content first - The tech should serve the content, not the other way around
  3. Progressive enhancement - The site works without JavaScript enabled
  4. Force simplicity - A principle I follow at work applies here too

What's Next?

Some features I'm considering:

  • Dark mode toggle
  • Blog search functionality
  • RSS feed
  • More content on AI/ML and SRE topics

But for now, I'm happy with this foundation. It's fast, accessible, and easy to maintain - exactly what a personal site should be.

Feel free to reach out on LinkedIn if you want to chat about the tech stack or anything else!