The tech stack

The choice of technology for any software system should be justified against the quality attributes and the functional requirements that the system and/or customer demands. This enforces a constraint on developers, perhaps rightfully so. There is however, no rule or guideline that forbids a system to include fancy tech, as long as that choice serves a purpose.

Needs

Without going too much into detail, here are some bullet points of some of the needs I have for this site and its infrastructure:

  • It should support rich content
  • It should be easy to create new content
  • It should be easy to build and deploy new versions of the site
  • It should be (close to) free to host

Rationale

The tech-stack chosen for many of my projects, including this, is an example of such a system where the main premise is to learn and have fun with cool technology (at least within reason). From working with React Native professionally for 2 years, I had to ensure that I didn't fall behind on the newest in web-development, specifically when it comes to server side rendering (SSR).

Framework

For reasons mentioned above, I chose to develop my app using Remix, mainly since I already had tried my hand at Next.js, plus that developers seem to like it a lot. Remix comes with a server framework, a client framework, a compiler and a server-side HTML handler. The BFF pattern that comes out the box with remix is also a plus from a security perspective as, if done right, secrets can live in the much more protected server environment rather than exposing them to the client.

The content

I knew I wanted to support rich content in the form of images, videos, code-snippets and posssibly React components. For these reasons, I chose to base all the site content on MDX-files. I use the lightweight mdx bundler named mdx-bundler to do this. The bundling is set up to happen on the server.

Content management

For content management, I initially did this manually by storing my mdx-files in the site repository. I initially thought keeping the files as close to the repository as possible was the best as it added no extra dependencies to my system, it was free and that version control would be nice to have. Not long after first publishing my site did I realize that managing all the files and images made the site hard to scale. I would have to implement my own API for managing the content, or risk that the content and the rest of the codebase became too coupled. For this reason, I decided to switch to using Contentful CMS. I personally don't like editing my posts externally, and wasn't too fond of storing them outside of my control, but the models-builder seemed intriguing, and assets are very easy to manage.

Going with a CMS also gave me a good excuse for brushing dust of my experience with client-side GraphQL libraries. I have tried my hand at relay, but wanted something much more lightweight, so I chose urql. The networking code is minimal, but being the preacher of type-safety I am, I also made sure to set up schema and request compilation with graphql-codegen so that I can work with types. Not too fan of urql not having the same first-class support of data-masking, but I can live with that for this project.

Styling

I have tried Tailwind CSS for some of my projects and I absolutely love it. Inspired by Shadcn, I also made sure to include clsx and tailwind-merge for an even better styling-experience. Using tailwind means dark-mode support is very easy to set up as well.