How I built this website
Sharing the decisions I made and the tools I used to create this website.
The design and code are handcrafted by me. I use Figma as my design tool. I use Visual Studio Code as my code editor.
I like to use my personal website as a way to experiment and learn. Over the years, I've redesigned (and refactored) it numerous times. I've built it in Angular and React, and used static site generators like Jekyll and Gatsby.
Although not every iteration makes it to production, it's still exciting to experiment with new frameworks, browser APIs, and technologies.
For the process of designing the site, I started with larger viewports to make sure I wasn't limiting my imagination for what the experience could be like.
Although I designed with larger viewports in mind first, I developed from a mobile-first perspective. (My media queries use
The deployment process kicks off with me pushing changes to GitHub. A build then gets triggered on Netlify.
I have 2 plugins enabled for my site: one for checking the accessibility of my pages in case I missed anything silly, and another for checking that I don't have any dead links.
For new commits on my main branch, a production build is triggered. This runs a build script in my package.json that turns my pre-compiled code into compiled code that I can serve in the browser.
For feature branches, I configured Netlify to spin up a non-production deployment so I can test my changes. This runs the same build script in my package.json as for the
Framework vs. Frameworkless
Since this iteration of my personal site has very little functionality, I decided to stick to an HTML templating language instead of inflating my bundle size with a framework. The templating language compiles into pure HTML, so there's no increase in the HTML sent to the client.
CSS vs. Sass
Although I could have gone with pure CSS for styling, I still opted for Sass. The convenience of nesting styles and creating mixins still edged out CSS. It's not all about variables, after all. In terms of bundle size, Sass doesn't—though it can—increase the size of the CSS delivered to the browser.
I also opted for the SCSS syntax, as I feel most comfortable working in that way. Funny enough, though, the Sass syntax is closer to the benefit you get from writing Pug instead of HTML, so maybe I'll make the switch one day.
I decided to pay a bit more attention to the performance of my website this time around. It's an odd to start caring when it's pretty minimal code, but I wanted to dive deeper into performance—both perceived and actual. Specifically, I wanted to look into everything to do with compositing.
I started with all my JS inside a single file. Then, I split out the code required to check if the user had a theme preference so that I could set a class on the body. With this approach, I avoid showing people a flash of the light theme before the dark theme is applied (if that's their preference). This JS is an intentionally blocking script to make sure that body class is there when the CSS is being interpreted by the browser.
defer attribute to my JS that I didn't want to block rendering. So, I did that.
I have two different grid images for the background: one for light theme and one for dark theme. These are set as the body's
background-image. Only the background image that's used in the initial render will get requested once the browser starts parsing CSS, which is a boon for performance.
background-image is set differently depending on the theme, only one image is requested at a time. If I toggle on the dark theme, the second image is requested right away. This seemed ideal and so I left it as-is.
Although they're SVGs, I originally used my blob images with an
img tag and pointed to their asset path, meaning I was making additional requests for images.
Since I want to improve my first contentful paint, I instead inlined the SVGs in my HTML to increase load speed and save ~1KB (50%) in network requests.
Related to this improvement, I encountered a strange bug with Pug not allowing attributes I set on
svg elements to get passed through to the generated HTML. Because of this, my blobs looked odd on some devices since the
viewBox wasn't getting set on the SVG.
Since this was a problem with the templating engine I was using, I decided to use
overflow: hidden on my SVGs instead of switching back to the
img tag approach.