Building aimen.dev Part 1: Design & Database

Before we go any further, a quick confession: I didn’t build this blog by myself.

I had help from Claude, Anthropic’s AI. Not “help” as in copy-paste-some-snippet-and-hope. Real back-and-forth. I asked questions I was a little embarrassed to ask, got explanations that actually clicked, and walked away understanding things I didn’t before.

This is my first real full‑stack project. Being upfront about the tools I’m using (and how I’m using them) feels more useful than pretending I knew it all from the start.

Where I started

I wanted a personal dev blog I actually built, no template, no hosted platform. Something I understood end to end, with a backend I controlled.

The gap was knowing how to get there. I figured I’d need a database and a way to write posts. I sort of knew what an API was. But I didn’t know how the pieces fit together, which tech to pick, or what order to build in. And for this project, it didn’t matter what stack I was working in as long as it was JavaScript-related with some SQL involved.

So I opened Claude and described what I wanted. That was it. Instead of a generic checklist, it asked me a few clarifying questions and came back with a concrete architecture, plus reasoning for each choice. Then it generated an HTML preview of what the frontend could look like, which seemed fine to me as a starter. I wanted to do this project mainly to get some experience in backend and architecture.

The stack, in plain English

  • Next.js: Frontend and API in the same codebase. No separate Express server. One repo, one deploy. My first time with Next.js which felt like a good challenge.
  • PostgreSQL on Railway: Managed Postgres. The DATABASE_URL is one connection string with everything in it with protocol, username, password, host, port (usually 5432), and database name all packed into a single URI.
  • Prisma: An Object-Relational Mapping (ORM) between my code and the database. Instead of writing raw SQL, I use type-safe methods like prisma.post.findMany(). Prisma turns that into SQL and gives me autocomplete and type checking.
  • NextAuth.js: GitHub sign-in, locked to my account via an env var so only I can log in.
  • Resend: Email delivery for the newsletter. Still digging into the docs. (This was something I didn’t even think I would want but seems like a good addition).
  • Vercel: Great free tier for personal projects. Handles deploys, CDN, and serverless functions for me.

The frontend

For the first pass, I asked Claude to sketch the UI. I ended up liking the direction: dark, editorial, and developer-y. Three fonts, each with a job:

  • Instrument Serif for headlines. Unusual for a dev blog, which is why it stands out.
  • JetBrains Mono for UI labels and navigation. Signals the developer context and looks great.
  • DM Sans for body text. Simple and doesn’t compete.

Background color: #0c0c0f—not pure black; there’s a faint purple undertone. Pure black + green screams “Matrix.” The undertone warms up the acid green (#c8ff57).

The database schema

I set up the core tables early so I wouldn’t be doing painful migrations later. A few design choices:

  • Comments need approval before they show up — Every comment goes into a queue first so I can review it before anyone else sees it.
  • Reactions work without logging in — Visitors can react using a cookie; the database prevents reacting to the same post twice.
  • Email subscriptions are safe and legal — Double opt-in: a confirmation email with a special link before anyone lands on the list.

Step 1: getting the database live


bash

npx create-next-app@latest aimen-dev
cd aimen-dev
npm install prisma @prisma/client
npx prisma init
npx prisma db push
npx prisma studio

All the tables showed up in Prisma Studio. Milestone unlocked.

The Prisma singleton (lib/db.ts) exists because Next.js hot‑reloads on every save. Without a singleton, each reload opens a new DB connection and you can burn through Railway’s connection limit fast. Something I wouldn’t have thought about on my own.

What using Claude actually feels like

There’s a big difference between Claude handing me code and Claude teaching me (all on the free version). The most valuable moments weren’t the snippets; they were the explanations that rewired how I understood things.

It felt like sitting next to a senior dev with infinite patience for “obvious” questions. Every time I asked why, I got a real answer.

What it doesn’t replace is thinking. I still had to make decisions and understand what we were building. The code doesn’t work if I don’t get it and getting it is my job.

Comments

No comments yet. Be the first.

Leave a comment