March 10th, 2024

Rebuilding my website using Remix, Prisma, and Markdown

Post hero for Rebuilding my website using Remix, Prisma, and Markdown

Introduction

Approaching the end of 2023 I decided I needed to refresh my website a bit. Throughout 2023 I used new tools and technologies that I really grew to appreciate. Looking at how my personal website was built at the time, I took a step back and asked myself, "How can I make this better to maintain, leaner, and more of my own?"

After posting that question to myself, I came up with the following requirements:

  • Content must be written in Markdown.
  • It has to be built with Remix.
  • No more out-of-the-box content management systems such as WordPress.
  • Flexible enough to support different types of content (writeups, blog posts, external links).
  • Version control for content.
  • Be as lightweight as possible.
  • Easy to deploy.

With that, I came up with the following tech stack:

Tech stack explanation

Remix

I started using Remix around May of 2023, about half a year after Remix joined Shopify. At first, my use of Remix was just explorative and I wanted to see how it differed from Next, which I was previously using for my website.

From a very high level view, they were not all that different as Next had introduced Layouts which are similar to Remix layouts.

But, when you start looking at the way that your routes (pages) load their data and submit forms you'll begin to realize how different the two are. Next uses api routes (/pages/api/your_api_name.ts) and Remix makes use of actions and loaders which are defined either within your route or within a resource route.

One of the biggest benefits I've found in using Remix is that their implementation of actions and loaders heavily relies on the Web API standards for Request and Response which I find much easier to follow along than any additional complexities or "features" that are baked into the API.

Prisma

I was looking for a lightweight ORM and I had used Prisma before, so naturally it was just the one I reached for first. There had been some issues that I had experienced while using Prisma previously (Support for a Union type). But, given the way that my content was going to be structured, I knew that the issues would not be a limiting factor for my personal website.

Knowing that Prisma had extensive documentation on their website and having some familiarity with it previously, I felt confident that this was a good decision to make for the ORM layer of the new build. However, if I were to approach the situation again in the future I might consider an alternative such as Drizzle ORM. Though, I'll add that I do really like the way the schema is constructed for Prisma compared to the schema for Drizzle.

Tailwind CSS

This will be one of the more fun topics as I had previously shared a large dislike for Tailwind "because it looks ugly in the code." However, I was mostly just being ignorant because I had not yet given it a full chance nor had I looked into the methods for keeping the codebase streamlined and clean when using Tailwind.

Prettier Plugin ESLint

Other technical decisions

Object Schema Validation

Why not Zod? Discuss the conditional type validation here.

Icon Sprites

Link to examples / add reasoning

Badge.tsx
interface BadgeProps {
label: string;
}
export function Badge({label}: BadgeProps) {
return (
<span className="rounded-full border border-neutral-300/50 bg-white px-3 py-1 text-xs text-neutral-500 transition-colors dark:border-neutral-600/30 dark:bg-zinc-850">
{label}
</span>
);
}
© Quinton Chester. All rights reserved.