Rebuilding My Personal Website: 2025 Edition

I help product teams build quality software and lead engineering efforts. Currently working at OpenSpace as a Senior Software Engineer.
Introduction
My old website was made in 2019 and hasn't been updated much since, except for career updates. I'm actually proud of that—I don't want to be someone who rebuilds their personal site every year.
But now, the site is over five years old in terms of both technology and content. It has become outdated—and it was obvious. It was built with Gatsby that relied on an old version of Node. I could still deploy it on Netlify, but getting it to work locally was a hassle. It also had a CMS, which was fun to add back then, but I hardly used it. Simply put, it was a mess.
I finally decided to redesign, rebuild from scratch, and make it much simpler. Here's what I did.
Go and see it for yourself: https://tomaszgil.me/.
Collecting inspiration
I've spent a lot of time searching for great examples of personal websites from both developers and designers, and also looking at product designs I really liked.
Using design inspiration galleries was really helpful at first. Here are the ones that were most useful to me.
I found plenty of stunning sites. I’ve picked a handful that were the most interesting to me, each with something I wanted to include in my design.
Mark Horn’s Portfolio. This site focuses on simplicity and balance, with a well-organized content structure. Most of this is achieved through typography. I really like the combination of sans-serif and serif fonts.

Pedro Duarte’s Personal Website. It's simple, personal, and focused on storytelling. I really like how the story is divided on the homepage and the overall layout of the site's content.

Max Yinger’s Website. This site combines ultimate simplicity—the homepage serves as the entire portfolio—with interactive design, featuring neat extras like a time clock.

Alistair Shepherd’s Website. This website has one of the most creative theme switchers I've ever seen. Combined with a fantastic hero illustration that moves as you scroll, it looks truly impressive.

Jacky Zhao’s Website. Sticking with the theme of theme switchers, Jacky's digital garden offers another great example—a pure CSS implementation that mimics sunlight streaming through a window, which looks absolutely great. The effect is open source, and you can find it here.

Alongside the individual portfolios, there were also products or services where the design resonated with me—I wanted my site to have similar characteristics or aesthetics.
Raycast. My favorite productivity app for macOS. Executed perfectly, with a strong focus on full keyboard navigation. I also really like the homepage design, especially the combination of sans-serif and monospace fonts.

Stripe. I'm not talking about the product or the main homepage here, but a part of the developer-facing documentation. I don't quite remember how I found it, but once I did, I fell in love right away. It's both modern and technical—thanks mainly to the use of a grayscale and sans-serif-monospace font combination (you might notice a theme here). I also like how the website can be fully navigated using a keyboard, with clear indicators showing how to access other pages.

The design
I started by defining the main high-level characteristics I wanted my design to follow.
Minimal and elegant. I wanted the website to be as clean as possible, so users can focus on the content. In practice, this meant using monochrome color palette, simple fonts, and minimal line icons. I reduced extra elements, mainly using white space for creating visual hierarchy. Once that was in place, I could add small details like animations and a theme-switching feature around the edges.
Modern and technical. Doubling down further on simplicity, I wanted the website to have a modern and technical look and feel. This influenced my choice of font families and the design of small components like buttons and links.
Theme-able and keyboard-accessible. The areas I wanted to explore were theming and full keyboard navigation. Normally, these are not the main focus of design, but I wanted to highlight them on my website. I believe they add value, not only for accessibility but also for user convenience and the overall look and feel.
These characteristics directly influenced the content structure I went with.
Homepage. I wanted the homepage to have a one-sentence description of what I do—nothing more, nothing less. The rest of the content can be accessed through navigation.
About. Separately, I wanted to share a bit more about my personal and professional background for those interested. This part highlights my main interests in engineering and beyond, along with a glimpse of my human side outside of tech.
Work. I decided to create a separate page to list the teams I've worked with recently, along with a brief description of what I did at each place. This serves as a concise version of my résumé.
Writing. Writing has become a core part of who I am as an engineer, both within the teams I've worked with and externally. I wanted to create a separate space to highlight a few of my most recent public articles, providing easy access to my blog.
Contact. I wanted people to have an easy way to reach out, so I included the contact information and links to social platforms in the navigation menu, making them just one click away.
With the content structure in place, I was ready to start designing. I chose two fonts—Geist as the primary sans-serif font and Geist Mono as the secondary monospace font. Both fonts look clean and modern, with the monospace font adding a more technical feel.
I made a few iterations in Figma and settled on the following design. I had a few other pages roughly sketched out, which was enough for me to start the implementation.

The implementation
I had a few goals in mind when starting the project.
Server-side generation. I knew the website would be simple, with some interactivity, but mostly focused on the content. Server-side generation was probably going to be the right rendering approach, so I wanted my setup to support it.
React and TypeScript. This is my bread and butter, the tools I use every day, and they have a great ecosystem built around them. Even though it would have been just as viable to implement this using plain HTML, CSS, and some JavaScript, I wanted to stick with my regular stack purely for ease of development.
Maintainability and support. I wanted to choose tools that are well-established, have good support and resources, and—as a result—are likely to remain in good condition five years from now.
The framework
After some research, I decided on Astro. My friend, Ray Gesualdo, recommended it to me and even wrote a short blog series about moving his own website and blog to Astro (you can read it here).
Even though Astro is a relatively new framework, it has excellent documentation and many integration options, including React. It allowed me to have a statically-built site with almost perfect Lighthouse scores—all by default, without any extra effort on my part.
Design system
Even though I didn’t need many components, I knew it was useful to choose a component library. I have implemented enough buttons and basic typography components in the past, so now I know better. I used to work with Stitches and Radix, and I really enjoyed both.
I noticed that the team behind Radix recently introduced Themes, a component library built on top of Radix's primitive components, offering theming options as the name suggests. This was a no-brainer.
It turned out to be a fantastic choice. Implementing the pages was easy, ensuring all basic design elements were consistent—from colors, typography, and spacing to the smallest components like buttons or links. It also supports a dark theme right out of the box, which I knew would be useful.
Theme switcher
This was an area I wanted to explore much deeper. I was impressed with Jacky’s website's animated background, and since it was open source, I decided to build on it. The effect transitions smoothly from day to night but is actually more granular under the hood, moving through 6 distinct phases altogether. I wanted to expose this to users, so I introduced six themes based on the six phases of the day: dawn, sunrise, day, sunset, dusk, and night, instead of just two (light and dark).
I needed to make some small adjustments to the colors so each state has enough contrast and connect it to my setup with theme-switching controls. The value of the currently selected theme is stored in local storage. I've experimented with it a lot, trying to refine how it’s done with Astro—it's still not perfect with the statically generated pages (even though the value loads before the page renders).
Update: I just found a version that works—read more about it here.
I decided to leave it as it is. The final touch was to add a subtle swoosh animation for the icon when the day changes to night.

Keyboard navigation
Inspired by Stripe’s developer site, I wanted to add hotkeys for interactive or navigation elements. I used the Kbd component from Radix to display the hotkey next to each interactive element.
I didn't want the hotkey hints to always be visible, so I added a separate layer where the keyboard shortcut hints appear when the user presses C. This is managed through a global context provider and is passed to all hotkey components.

Other tools
Finally, here are some additional tools, packages, or services I used during the process.
Icons: Radix Icons
Animations: Motion
Hosting: Netlify
Analytics: Umami
The final result
That's it! The process took about three months of light evening coding, which was much longer than I expected, but I'm really happy with the result. A big thanks to my friends who helped me make decisions along the way and provided feedback!
Again, you can see the result here: https://tomaszgil.me/.
If you enjoyed the article or have a question, feel free to reach out to me on Bluesky or leave a comment below!
Further reading and references
- Photo by Matt Hardy on Unsplash.






