안녕하세요. 첫 번째 블로그 글입니다.
저는 프로그래밍하면서 고민하고 해결한 과정을 기록하고 공유하기 위해 블로그를 만들었습니다. 글을 잘 쓰는 편은 아니지만, 수정·보완하면서 효율적으로 지식을 나눌 수 있도록 하겠습니다.
이번 글에서는 제가 직접 만든 블로그 에디터를 소개하려 합니다.
1달 가까이 다양한 에디터를 테스트했고, 결국 ProseMirror 기반 Tiptap을 선택했습니다.
팁탭은
확장성이 뛰어나고
Viewer를 JSON/Text 형식 모두 SSR 가능
Next.js & 백엔드와 궁합이 좋음
에디터 | SSR | 확장성 | 엔진 | WYSIWYG | Markdown | RIch Text | 기타 |
|---|---|---|---|---|---|---|---|
editor.js | 🟡 | ↗️ | 자체 | ✅ | 🟡 | ✅ | 문서 좋음. Json 구조. |
react-md-editor | ❌ | ➡️ | 자체 | ❌ | ✅ | ❌ | 이지윅 사용성 안좋음. |
toast UI | ❌ | ⬇️ | ProseMirror | ✅ | ✅ | ✅ | 문서화 나쁨. 플러그인 적음. |
quill | 🟡 | ↗️ | Delta | ✅ | 🟡 | ✅ | 문서 좋음. JSON 구조. |
TipTap | ✅ | ↗️ | ProseMirror | ✅ | 🟡 | ✅ | 문서 보통. 기능 잘 나뉨. |
ProseMirror | ✅ | ⬆️ | 자체 | ✅ | ❌ | 🟡 | 문서 최고. 높은 러닝 커브. |
👉 결론: 간단 기능 위주라면 Quill/Editor.js 추천. 하지만 커스텀 기능 많이 필요하다면 Tiptap/ProseMirror가 최적일 것입니다.
저의 에디터에 필요한 기능들의 기능들을 정리해 봤습니다.
기본 텍스트 편집 기능
글씨체 변경 (굵게, 밑줄, 기울임, 색깔, 배경색)
글머리 기호, 번호 기호, 체크 리스트
문단 좌, 우, 가운데 정렬
마크다운 문법 지원 (#적고 띄우면 h1 태그.. ```js 작성시 js 코드 블록 자동 생성)
들여쓰기, 내어쓰기
하이퍼 텍스트 생성
Viewer의 서버 사이드 렌더링
Viewer는 서버사이드 렌더링(SSR)이 가능하여 NextJs의 ISR, SSG로 캐싱가능
코드 블록 및 코드 하이라이팅
코드 블록에 설정한 코딩 언어에 맞는 문법 강조
Code Syntax Highlighter는 SSR이 가능하여, NextJs의 ISR, SSG로 캐싱가능.
기본 Syntax Highlighted된 코드에 서식 추가.(형광팬, 밑줄 등)
VS Code에서 복사한 코드는 자동으로 해당 파일의 언어를 감지하여 코드 블록 생성
이미지 업로드 및 관리
이미지 정렬 및 크기 조정 기능 지원
복사-붙여넣기 시 편하게 S3에 업로드하여 URL을 받아 사용
업로드 시, WebP 압축 후 비교하여 효율적인 포멧 사용.
기존의 이미지 URL을 재활용하여 불필요한 업로드 방지.
목차(TOC) 자동 생성
헤더를 통해 자동으로 목차(TOC) 생성
첫 슬래쉬, 드래그 자동완성
"/"를 입력하면 주요 기능들을 사용할 수 있다.
내용을 드래그하면 드래그한 영역에 필요한 기능을 사용할 수 있다.
6가지 기능을 구현하면서 어려웠던 점 및 구현 방법을 간단히 소개하겠습니다.
개발 이유: 개발 블로그라 다양한 언어 코드 강조가 필수
구현: Shiki 기반, 100+ 언어 지원, Line 단위 파싱 → Line number 처리 가능
특징: 코드 블록에 형광펜·밑줄·취소선 같은 마크도 적용 가능. VS Code 복붙 언어 자동 감지.
어려움: ProseMirror Schema/Mark 충돌 해결 → 2주 이상 소요
성과: 에디터와 한 몸처럼 작동(에디터 컨텍스트 연동), 데이터 이중 저장 불필요

개발 이유: Next.js ISR/SSG 캐싱을 통한 빠른 렌더링
고안한 방식들 :
클라이언트에서 HTML 전달 → 보안 취약할 수 있음.
서버에서 SSR로 데이터 파싱과 Sanitizing 수행 → 최신 반영, 안전
구현 : 서버에서 데이터 저장 + 파싱한 HTML 캐싱 병행 → 빠르게 출력 및 안전
장점: 보안 강화, 데이터 중복 저장 불필요

개발 이유 : S3 저장소에 실시간 이미지 업로드가 필요.
구현 : 클립보드 붙여넣기 → WebP 압축 → S3 업로드 후 URL 반환
어려움 : 외부 URL 처리 방안과 CSP 설정에 대한 고민
장점 : 기존 URL 재활용 → 중복 업로드 방지
![]() | ![]() |
구현 : Tiptap에 플러그인을 형식에 맞게 개발
어려움 : 기능을 추가하려면 ProseMirror 문서까지 참고해야 함.
장점 : 언제든 꾸미는 자유도를 기능 추가로 확장할 수 있다.

개발 이유 : 나무 위키 목차 찾아가는 기능이 부러워서.
구현 :
Heading 플러그인에 TOC를 위한 data-attribute를 추가 및 활용하여 파싱.
ResizeObserver를 통한 Layout 변경 감지, Debouncing 적용으로 최적화.
어려움 : 파싱하는 방식으로 구현되어 에디터 Heading 플러그인 구현 사항을 모르면 유지 보수 힘듦.
장점 : 한눈에 목차를 볼 수 있고 찾을 수 있다.
![]() | ![]() |
개발 이유 : 노션 에디터를 레퍼런스로 봤을 때 충분히 좋아 보임.
구현 :
다행히 기본적인 플러그인이 있어 해당 플러그인 활용
커스텀하게 추가하고 싶은 기능을 플러그인에 추가함.
어려움 : Command를 다 파악하고 추가해야하는데, 코드블럭은 바닥부터 만든 기능이라 커맨드를 직접 추가해줘야 했음.
장점 : 마우스를 컨트롤 박스까지 올리지 않아서 좋음.
개발 이유 : 언젠가 코드 작동까지 보여주도록 해야하는데, 코드 펜을 활용하면 좋을 것 같아서.
구현 :
iframe 적용시 보안 문제가 생길 수 있어서 CSP를 적절하게 사용.
어려움 : 완전히 Third Party이기 때문에 CSP 영향을 많이 받는데 실제 환경에서 테스트가 힘듦.