AI와 함께 만들어보는 첫 번째 개인 프로젝트로 블로그를 선택했다. 예전에는 블로그를 직접 만드는 일이 꽤 귀찮게 느껴졌다. 화면을 만들고, 글을 불러오는 구조를 만들고, 배포까지 신경 써야 했기 때문이다.
하지만 요즘은 AI를 활용하면 개인도 작은 서비스를 훨씬 쉽게 만들 수 있다. 아이디어를 빠르게 구현해 보고, 막히는 부분을 함께 정리하고, 필요한 구조를 하나씩 개선해 갈 수 있다. 그래서 나도 첫 시작을 블로그라는 비교적 단순한 프로젝트로 해 보기로 했다.
이번 블로그는 대단한 서비스를 만들기 위해 시작한 프로젝트는 아니다. 내가 겪은 삽질을 기록하고, 새로운 기술을 실험하고, 꾸준히 유지보수할 수 있는 나만의 공간을 만들어 보는 것이 목적이었다.
직접 블로그를 만든 이유
블로그를 직접 만들게 된 가장 큰 이유는 오래 유지보수할 수 있는 나만의 프로젝트를 갖고 싶었기 때문이다. 이미 좋은 블로그 플랫폼은 많다. 하지만 그런 플랫폼을 사용하면 편한 만큼 내가 직접 통제할 수 있는 범위는 줄어든다.
나는 글의 공개 여부, 블로그 구조, 서버 에러 대응, 수정 방식, Git 이력, 커스터마이징, 그리고 나중에 붙이고 싶은 다양한 기능을 직접 다루고 싶었다. 직접 만든 블로그라면 성능이나 SEO, 기능, 디자인을 내 입맛에 맞게 조정할 수 있다.
물론 직접 만든다는 것은 그만큼 책임도 따른다는 뜻이다. 하지만 그 과정 자체가 나에게는 좋은 학습이 될 수 있다고 생각했다. 블로그는 단순히 글을 올리는 공간이 아니라, 내가 계속 만지고 개선해 볼 수 있는 작은 실험실이 될 수 있기 때문이다.
기술 스택 선택
기술 스택을 고를 때는 복잡한 기준을 세우기보다, 개인 블로그에 필요한 기능을 얼마나 단순하고 안정적으로 만들 수 있는지를 먼저 봤다. 글을 작성하고, 목록으로 보여주고, 상세 페이지에서 읽을 수 있게 만들고, 검색 엔진과 RSS 리더가 이해할 수 있는 형태로 제공하는 것이 핵심이었다.
Next.js
Next.js는 React 기반의 풀스택 프레임워크다. CSR(Client-Side Rendering), SSG(Static Site Generation), ISR(Incremental Static Regeneration) 같은 렌더링 방식을 상황에 맞게 선택할 수 있다는 점이 좋았다.
블로그 글처럼 자주 바뀌지 않는 콘텐츠는 SSG로 미리 HTML을 생성해 빠르게 제공할 수 있고, 운영 방식에 따라 ISR로 정적 페이지를 다시 생성하는 선택지도 있다. 반대로 검색이나 테마 전환처럼 사용자 상호작용이 필요한 부분은 CSR로 처리할 수 있어, 정적인 블로그의 장점과 동적인 UI의 장점을 함께 가져갈 수 있다.
SEO 측면에서도 유리했다. 블로그는 본문이 검색 엔진에 잘 노출되어야 하고, 링크를 공유했을 때 제목과 설명이 정확히 표시되어야 한다. Next.js의 metadata API를 사용하면 title, description, canonical URL, Open Graph 같은 정보를 페이지 단위로 관리할 수 있어 블로그에 잘 맞았다.
Tailwind CSS
Tailwind CSS는 유틸리티 클래스 기반의 CSS 프레임워크다. 별도의 CSS 파일을 크게 작성하지 않아도 클래스 이름만으로 간격, 색상, 타이포그래피, 레이아웃을 빠르게 조정할 수 있다.
내가 Tailwind CSS를 선택한 이유는 작은 개인 블로그에서 화면을 빠르게 다듬기 좋기 때문이다. 블로그는 복잡한 UI보다 읽기 좋은 여백, 적절한 본문 폭, 카드 간격, 코드 블록 스타일 같은 디테일이 중요하다. Tailwind는 이런 요소를 실제 화면을 보면서 조금씩 조정하기에 편했다.
Next.js와의 궁합도 좋았다. 페이지와 컴포넌트를 나눠 작성하는 구조에서 스타일을 컴포넌트 가까이에 둘 수 있고, 필요한 스타일만 사용하기 때문에 작은 블로그 프로젝트를 가볍게 유지하기 좋다. 처음부터 거대한 디자인 시스템을 만들기보다, 필요한 스타일을 바로 적용하고 반복되는 부분이 생기면 그때 컴포넌트로 정리하는 방식이 더 잘 맞았다.
TypeScript
TypeScript는 JavaScript에 타입을 더한 언어다. 변수, 함수, 데이터 구조가 어떤 값을 다루는지 코드 단계에서 명확히 표현할 수 있고, 컴파일 단계에서 타입 관련 실수를 미리 잡는 데 도움을 준다.
이 블로그에서 TypeScript가 필요했던 이유는 글 데이터의 형태를 안정적으로 다루기 위해서였다. 각 글에는 title, description, publishedAt, category, tags, draft 같은 frontmatter가 있고, 이 값들은 글 목록, 상세 페이지, SEO metadata, RSS 같은 여러 곳에서 반복해서 사용된다.
문자열 하나가 빠지거나 날짜 형식이 잘못되면 화면뿐만 아니라 sitemap이나 RSS에도 영향을 줄 수 있다. TypeScript를 사용하면 포스트 타입을 기준으로 데이터 구조를 맞출 수 있고, 나중에 기능을 추가하더라도 어떤 값이 어디에서 쓰이는지 추적하기 쉬워진다.
MDX
MDX는 Markdown 문서 안에서 JSX를 사용할 수 있게 해주는 형식이다. 기본적으로는 Markdown처럼 글을 작성하면서, 필요할 때 React 컴포넌트를 함께 사용할 수 있다.
CMS(Content Management System)는 관리자 화면을 통해 글을 작성하고 관리하는 시스템이다. 편리한 장점이 있지만, 이번 블로그에서는 글을 Git으로 관리하고 코드와 같은 흐름으로 다루고 싶었기 때문에 CMS보다 MDX가 더 잘 맞았다.
MDX를 선택한 이유는 글 작성 방식은 단순하게 유지하면서도 확장 가능성을 열어두고 싶었기 때문이다. 글은 Markdown처럼 편하게 쓰고, 기술 블로그에서 필요한 코드 예제나 강조 영역, 나중에 추가할 커스텀 컴포넌트는 React 방식으로 확장할 수 있다.
또한 글 하나를 하나의 .mdx 파일로 관리하고, 파일 상단에는 제목, 설명, 작성일, 태그 같은 메타데이터를 함께 둘 수 있다. 이 방식은 Git과도 잘 어울린다. 글을 수정하면 변경 이력이 남고, 어떤 내용을 언제 바꿨는지 확인할 수 있기 때문에 블로그 자체를 하나의 프로젝트처럼 운영하기 좋다.
예를 들어 일반 Markdown은 글과 코드 블록을 단순하게 작성하는 데 집중한다.
const message = "Hello blog";
console.log(message);반면 MDX에서는 Markdown 문서 안에서 React 컴포넌트를 함께 사용할 수 있다. 예를 들어 아래 콜아웃 박스처럼 직접 만든 컴포넌트를 글 안에 배치할 수 있다.
Markdown처럼 글을 작성하다가,
일반 Markdown만 사용하면 단순하지만 표현의 한계가 생길 수 있고, CMS 중심 구조로 가면 Git으로 글을 관리하려는 흐름과 멀어질 수 있다. MDX는 그 중간 지점에 있었다. 지금은 복잡한 컴포넌트를 많이 쓰지 않더라도, 블로그가 커졌을 때 글 안에서 더 다양한 표현을 시도할 수 있다는 점이 마음에 들었다.
사용한 라이브러리와 선택 이유
MDX를 선택했다고 해서 모든 것이 자동으로 해결되지는 않았다. 글 파일을 읽고, frontmatter를 분리하고, Markdown 문법을 확장하고, heading에 링크를 붙이고, 코드 블록을 보기 좋게 렌더링하는 과정이 필요했다.
그래서 블로그에 필요한 역할을 기준으로 라이브러리를 나눠서 선택했다. 각각의 라이브러리는 거창한 기능을 위해서라기보다, 글을 안정적으로 읽고 보기 좋게 보여주기 위한 작은 역할을 맡고 있다.
전체 흐름을 단순하게 그리면 아래와 같다.
.mdx 파일
|
| gray-matter
| - frontmatter와 본문 분리
v
메타데이터 + MDX 본문
|
| next-mdx-remote/rsc
| - MDX를 React에서 렌더링할 수 있는 형태로 변환
|
| remark-gfm
| - GitHub Flavored Markdown 문법 처리
|
| rehype-slug
| - heading에 id 생성
|
| rehype-autolink-headings
| - heading에 anchor link 연결
|
| rehype-pretty-code
| - 코드 블록 syntax highlighting
v
블로그 글 화면next-mdx-remote
next-mdx-remote는 .mdx로 작성한 글을 실제 블로그 화면에 보여줄 수 있게 도와주는 라이브러리다. 이 블로그는 파일 시스템에서 .mdx 글을 읽어와 Next.js App Router 환경에서 보여주는 구조이기 때문에, 서버 컴포넌트 흐름에 맞는 next-mdx-remote/rsc가 잘 맞았다. 복잡한 MDX 변환 과정을 직접 다루기보다, 글을 안정적으로 보여주고 필요한 도구들을 연결하는 데 집중할 수 있어서 선택했다.
예를 들어 .mdx 파일에 작성한 아래 내용을 실제 블로그 화면에서 React가 렌더링할 수 있는 콘텐츠로 바꿔준다.
## Next.js를 선택한 이유
블로그 글은 자주 바뀌지 않기 때문에 SSG와 잘 맞았다.gray-matter
gray-matter는 글 파일 위쪽에 적어둔 제목, 설명, 작성일 같은 정보를 본문과 따로 꺼내서 사용할 수 있게 해주는 라이브러리다. 이 블로그에서는 글마다 제목, 설명, 작성일, 카테고리, 태그, draft 여부가 필요했고, 이 값들은 목록 정렬, 상세 페이지 metadata, RSS 생성에 반복해서 사용된다. 글 파일 하나 안에서 콘텐츠와 메타데이터를 함께 관리하면서도 코드에서는 깔끔하게 나눠 사용할 수 있어 잘 맞았다.
블로그 글 파일 상단의 이런 정보가 frontmatter다.
---
title: 개인 블로그 만들기(1)
description: 블로그를 직접 만든 이유를 정리했습니다.
publishedAt: 2026-04-21
tags:
- nextjs
- mdx
draft: true
---
여기부터는 실제 글 본문이다.gray-matter를 사용하면 위 영역은 메타데이터로, 아래 본문은 콘텐츠로 분리해서 다룰 수 있다.
remark-gfm
remark-gfm은 GitHub에서 자주 쓰는 Markdown 문법을 블로그에서도 그대로 사용할 수 있게 해주는 도구다. 테이블, 체크박스, 취소선 같은 문법은 GitHub에서 글을 작성하거나 미리 볼 때 자연스럽게 쓰게 된다. 이 블로그는 Git 기반으로 글을 관리하기 때문에 GitHub에서 보이는 문법과 실제 블로그에서 렌더링되는 문법의 차이를 줄이기 위해 선택했다.
예를 들어 GitHub에서 자주 쓰는 테이블이나 체크박스 문법을 블로그에서도 그대로 사용할 수 있다.
| 기능 | 상태 |
| --- | --- |
| MDX 렌더링 | 완료 |
| RSS 추가 | 완료 |
- [x] 블로그 글 작성
- [ ] 배포 글 공개rehype-slug
rehype-slug는 글의 제목에 자동으로 주소를 붙일 수 있게 해주는 도구다. 기술 글은 길어질수록 특정 섹션으로 바로 이동하거나 링크를 공유하고 싶을 때가 많다. 제목마다 직접 id를 관리하면 번거롭고 실수하기 쉬운데, 이 도구를 사용하면 글 작성자는 본문에 집중하고 블로그는 문서 탐색에 필요한 구조를 자동으로 만들 수 있다.
예를 들어 글에 아래 제목이 있으면,
## 기술 스택 선택렌더링된 HTML에는 이런 식으로 이동 가능한 id가 붙는다.
<h2 id="기술-스택-선택">기술 스택 선택</h2>rehype-autolink-headings
rehype-autolink-headings는 제목을 클릭하거나 복사할 수 있는 링크처럼 만들어주는 도구다. rehype-slug가 제목에 이동 가능한 id를 만들어준다면, 이 도구는 그 제목을 사용자가 쉽게 접근할 수 있는 링크로 만들어준다. 특정 섹션을 공유할 일이 많은 기술 블로그에서 글 전체가 아니라 필요한 위치를 바로 전달할 수 있어 유용했다.
앞의 heading에 링크가 붙으면 사용자는 이런 주소로 특정 섹션에 바로 접근할 수 있다.
https://yunkoo.dev/posts/building-my-blog-with-nextjs-mdx#기술-스택-선택rehype-pretty-code
rehype-pretty-code는 코드 블록을 더 읽기 좋게 보여주는 도구다. 기술 블로그에서 코드 블록은 본문만큼 중요하고, 코드가 읽기 어려우면 글의 이해도도 떨어진다. 단순한 <pre> 스타일로도 코드를 보여줄 수는 있지만, 언어별로 색이 입혀지면 훨씬 읽기 편하다. 앞으로 코드 예제가 많은 글을 작성할 것을 생각해 처음부터 코드 가독성을 챙기기 위해 선택했다.
예를 들어 글에 이렇게 TypeScript 코드 블록을 작성하면,
type Post = {
title: string;
publishedAt: string;
};블로그 화면에서는 TypeScript 문법에 맞게 색이 입혀진 코드 블록으로 보여줄 수 있다.
마무리
예전부터 개인 블로그를 만들고 싶다는 생각은 계속 있었다. 하지만 막상 시작하려고 하면 화면 구성, 글 관리 방식, 배포, SEO처럼 신경 써야 할 것들이 많아 보여서 계속 미뤄왔다. 이번에는 AI를 함께 활용하면서 그 부담이 많이 줄었다. 막히는 부분을 정리하고, 필요한 구조를 하나씩 나누고, 구현 방향을 빠르게 검토하면서 작은 개인 프로젝트를 실제로 완성해볼 수 있었다.
지금 단계에서는 MDX 파일과 Git만으로도 충분했고, 필요한 기능은 나중에 확장하면 된다. 중요한 것은 도구를 많이 붙이는 것이 아니라, 내가 글을 어떻게 작성하고 공개하고 유지보수할 것인지에 맞는 흐름을 만드는 것이었다.
AI에 익숙해지면서 앞으로 어떤 개발을 해야 할지도 다시 생각하게 됐다. 단순히 코드를 대신 작성하게 하는 것이 아니라, 내가 만들고 싶은 것을 더 작게 나누고, 빠르게 실험하고, 결과를 보면서 개선하는 방식이 중요해졌다. 이번 블로그는 그 시작점에 가까운 프로젝트였다.
이번 프로젝트를 통해 완벽하게 준비된 상태에서 시작하는 것보다, 조금 엉망진창 이더라도 일단 시작하는 것이 훨씬 중요하다는 걸 알게 됐다. 만들면서 고치고, 부족한 부분을 채우고, 다시 정리하면 된다. 그래서 앞으로는 더 많은 것을 작게 만들어보고, 실패하더라도 계속 실험 해볼 생각이다.