Skip to main content

Command Palette

Search for a command to run...

I Fired My Database: Why I Moved From "Custom Everything" to a Headless CMS + Next.js

I spent weeks building a custom admin panel only to realize I hated using it. Let me tell why you should never complicate your simple portfolio.

Updated
4 min read

There is a toxic trait that all full-stack developers share: The urge to build everything from scratch.

When I started BabaCreates I didn’t want a "basic" website. I wanted to flex. I built the whole thing using: Next.js frontend, PostgreSQL, Prisma ORM, and a custom-coded Admin Dashboard.

It worked. It was fast. And it was a complete pain in the neck to use.

If I wanted to fix a typo in a blog post, I had to log into a dashboard that looked like it was designed by a prompt engineer (because it was 🥲, I used AI in hurry). If I wanted to add a new "Project" category, I had to run database migrations. I was spending more time pushing code than actually creating content.

I realized I needed something like simple already made CMS which can handle my posts and project and content mangement. But which one?

The "Bachelor" Phase: Dating Different CMS Options

Well I didn't just pick the first tool I saw. I looked around, and honestly, most options had deal-breakers.

1. Strapi (The Heavyweight)

Strapi is cool. It’s open-source and customizable. But hosting it? That’s a whole different job. I’d have to manage a separate server, deal with deployments, and worry about uptime. I want to write blogs, not babysit Docker containers.

2. Notion (The "Almost" Perfect)

I love Notion. I organize my whole life in it. Naturally, I thought about using the Notion API as my backend. The catch: Rendering Notion content on a custom Next.js site is... messy. You have to parse their specific block structure, and if you want it to look like your design (and not just a Notion clone), it takes a lot of effort. Plus, querying it for a high-performance site felt clunky.

3. Wordpress

Lol. No 🤣

Enter Sanity: The "Lazy" Developer's Choice

I landed on Sanity.io.

I’m not saying it’s the holy grail of software, but for my use case, a developer who wants a custom frontend but hates managing a CMS for this small thing, it was the sweet spot.

It’s a Headless CMS. This means they handle the database and the dashboard, and they just give me an API to fetch my data.

Why it won me over:

  1. I didn't lose my frontend. I kept my Next.js app exactly as it was. I didn't have to use some generic template. My site still looks cool and modern because I coded the frontend.

  2. Schema-as-Code. This is the killer feature. I don't click around a UI to create fields. I write a Javascript object, and Sanity generates the dashboard form for me.

The Migration: How Hard Was It?

Surprisingly easy. I basically deleted my prisma folder and replaced it with a sanity folder.

Step 1: Defining the Model

Instead of writing SQL migrations, I just told Sanity what a "Project" looks like in code:

JavaScript

// project.js
export default {
  name: 'project',
  title: 'Project',
  type: 'document',
  fields: [
    { name: 'title', type: 'string', title: 'Project Name' },
    { name: 'slug', type: 'slug', options: { source: 'title' } },
    { name: 'techStack', type: 'array', of: [{ type: 'string' }] },
    { name: 'content', type: 'array', of: [{ type: 'block' }] } // Rich text editor!
  ]
}

Boom💥. Sanity instantly generated a UI where I could type in my project details, upload images, and format text. No manual form validation required.

Step 2: Fetching the Data

Since I know JavaScript, learning their query language (GROQ) took about 15 minutes. It’s actually cleaner than my old Prisma queries.

Old Way (Prisma):

JavaScript

const projects = await prisma.project.findMany({
  where: { featured: true },
  select: { title: true, slug: true, image: true }
});
// Then I had to manually serialize dates because Next.js hates Date objects

New Way (Sanity):

JavaScript

const projects = await client.fetch(
  `*[_type == "project" && featured == true]{
    title,
    "slug": slug.current,
    "imageUrl": image.asset->url
  }`
);

The Verdict

My portfolio is now a "mullet" setup: Business in the back, Party in the front.

  • The Back: A boring, reliable, managed CMS (Sanity) that I don't have to maintain.

  • The Front: A high-performance, completely custom Next.js application that looks exactly how I want it to.

I get proper SEO (because Next.js renders everything server-side), I get a nice dashboard to write my blogs, and I deleted about 2,000 lines of boilerplate code from my repo.

I feel, If you’re sitting there maintaining a custom SQL database for a personal blog with 10 posts... stop it. Go get a headless CMS and get back to actually building cool stuff.

Fin.✌🏼