DEV Community

Cover image for Updating my website's tech stack in 2025
David  Morais
David Morais

Posted on

Updating my website's tech stack in 2025

Intro 🤓

The world of front end development is always changing and in order to keep up-to-date with the latest technologies I like to take on personal projects on my free time. My website/blog is one of these projects that I have built, and despite the semi-neglect it has seen over the past few years, I have always been proud of having it and showcasing it to people.

As one can infer from my post history, stuff happened in my personal life that has left me with little to no time for writing tech articles or even work on my side projects. I gave up on finishing Epoch Rift about 1 year and a half ago after realizing I was way too optimistic with the initial scope of the project and my pixel art making skills, and since then I have only started local repositories that eventually were lost when my old computer was bricked.

So in an effort to keep up to date and also to give my website a much needed tech update, along with a visual overhaul. In this post, I will detail as much as possible what hardships I faced, decisions I took and the final result.

How it was 🦕

My website's previous iteration was built in 2021. It was bootstrapped using (the now deprecated) Create React App and it took approximately 2 months to build. The home page included a bunch of photos that I had taken myself of my desk and keyboard as background for several sections and it included most of the information on the website. In the middle of the page I put the SkillsTerminal (which also features in the current version), which provided visitors with a familiar and mobile-ready UI which included my tech skills, aswell as a bit of information on my work and project history.

A comparison betwen package.json

The other page was a list of my blog posts that were posted in Hashnode, fetched using Graph QL using Hashnode's API. The posts would then be shown when the user navigated to /post/<slug> , after triggering another request to Hashnode's API. I also built my own solution for i18n and theming and relied on styled-components to do most of the CSS heavy lifting and customization.

Javascript to Typescript ✨️

Very early on when planning this update I was decided on making the whole thing in Typescript as the previous itteration of the website was one of the last projects I built entirely using only Javascript.

I could have spent some weeks migrating some components I previously used, but along with the decision to migrate to Typescript, I also came to the conclusion that I was better off building the UI from scratch.

The only code I felt I could migrate to Typescript was my data/configuration files. For example, for my resume, I wrote a .ts file with a single exported variable that contained my work history information. My resume, contacts and the data in the SkillsTerminal (I will get to it 🙏) was all that I felt I had to actually write some interfaces for.

Styled Components to TailwindCSS 🌬️

So, along with the decision to use Typescript and start a codebase from scratch, I also decided that for once I was going to save some time and use one of those shiny new primitive libraries. I did not really want a complete set of UI components, but rather some primitives that worked out of the box but were also easily customizeable. In my last React Native project, I had worked with Tamagui and I loved it, I also really like the components provided in Hero UI (formerly known as Next UI), so I was going for something with the same visual style, but lighter.

shadcn/ui 🧩

shadcn/ui is definetly the new cool kid on the block as far as UI libraries are concerned, despite the fact that they clearly state in their documentation "This is not a component library. It is how you build your component library". This was exactly what I needed.

This library does not provide developers with the usual npm i shadcn/ui + import Component from "shadcn/ui" workflow. Instead, they give the code to the actual component so that you use and import it in your codebase. Whereas the usual paradigm means importing a file from deep inside node_modules and having a wrapper around it, be it for style or functional purposes, I am now finding myself not only using only what I need from a component library, but also being able to customize my own components much easier as I am either dealing with plain HTML elements or Radix primitives.

Setting it up was not hard at all, I just followed the documentation for a manual installation and went with it. The only minor caveat I did find is that I had to add @plugin "tailwindcss-animate"; to the top of my global.css file since tailwindcss-animate doesn't support the latest version of Tailwind.

Goodbye styled-components 👋

One of the fads that I have never indulged in for the past few years was the Tailwind CSS fever. To me, this was just another Bootstrap waiting to be replaced by a more modern, more complete and lighter version of itself. And over the years, I've noticed that some component libraries would often indicate in their documentation that they recently migrated away from styled-components. Looking into it, I soon discovered that I would be facing the same decision.

You see, styled-components and other CSS-in-JS has a huge impact on performance and size for the website as it includes more styles that it needs to (and this can be optimized to a point, but I wanted a simpler approach) and the styles are applied at runtime, adding overhead for the browser to parse and apply the styles.

I did try to make it work with Tailwind and styled-components, but ultimately I was seeing some performance issues and weird flickers that were clearly coming from these two conflicting engines and I decided to ditch styled-components all together, after some 5 years of being my go-to CSS solution, it's time to say goodbye and welcome more modern, complete and lighter version of it 🤡

Ditching API based articles 🖊️

Another decision I had taken previously to starting working on this, was to stop fetching the posts on the client side. This is terrible for SEO and makes me have to rely on a thirdparty API to keep the posts available. And in my experience, there were breaking changes to the Hashnode API a few years ago that made it so that my posts were unreachable for quite some time until I finally noticed they were not working when I happened to visit the website.

Besides adding error monitoring to the website, I also decided that the way to go was to render the markdown articles on the server. In doing so I gave Astro a spin, but after being unable to get the Tailwind CSS working, I decided to settle on Next.JS. It is a familiar framework, but I still had to learn how to use the relatively new App Router, which was new to me.

Next.js' App Router 🛣️

Next is shifting towards what they're calling App Router. The previous itteration, known as Pages Router is not compatible with those shiny new React Server Components I mentioned earlier. The main difference to me was using simple fetch and async/await syntax to fetch the server side props. In this case, I had a node script that relied on fs to retrieve the markdown files and a library called gray-matter to retrieve their YAML metadata properties. Then all I had to do was transform my [slug] page into an async function and call the function that fetched the posts from the filesystem.

The other main difference is that instead of relying on a file per page, this allows me to make hierarchical routes, creating nested layouts of components that may need to wait for server data much easier.

Conclusion 🚀

Revamping my website proved to be a rewarding journey filled with both challenges and learning experiences. Transitioning from JavaScript to TypeScript not only improved the robustness of my code but also enhanced the maintainability and scalability of the project. The move from styled-components to Tailwind CSS streamlined the styling process, resulting in cleaner code and better performance, while embracing the component-first approach with shadcn/ui brought more customization flexibility.

Furthermore, switching from an API-based article system to server-rendered markdown posts was a win for SEO and reliability, allowing me to present my content more efficiently and without external dependencies. With Next.js' App Router and the integration of React server components, I was able to reinforce structure and enhance performance, thoroughly modernizing the tech stack of my site.

Reflecting on these updates, it's clear that the landscape of web development is ever-evolving, pushing us to adapt and iterate continuously. This project not only rejuvenated my personal website but also rekindled my passion for front-end development, reminding me that keeping pace with new technologies is both imperative and invigorating. As I move forward, I am excited to explore more innovative tools and techniques that can further elevate my web development projects.

Top comments (0)