앞에서 contenteditable을 맨손으로 길들이는 게 얼마나 험한 일인지 봤죠. 그래서 현실의 개발자 대부분은 검증된 라이브러리를 골라 써요. 문제는 이 바닥에 선택지가 너무 많다는 거예요. Quill, TipTap, ProseMirror, Slate, Lexical... 이름은 들어봤는데 뭐가 다른지 감이 안 오죠. 저도 프로젝트마다 다른 걸 써보며 비싸게 배웠어요. 오늘은 대표 라이브러리들의 성격과 용도를 정리하고, 여러분 상황에 맞는 걸 어떻게 고를지 기준을 잡아드릴게요.
17.1 라이브러리마다 대체 뭐가 다른가요?
겉으로는 다 글쓰기 창이라 비슷해 보여요. 하지만 속을 보면 두 축에서 갈려요. 첫째는 완제품이냐 재료냐예요. 버튼과 툴바까지 다 갖춰 바로 쓰는 것도 있고, 화면(UI)은 직접 만들라며 알맹이만 주는 것도 있어요.
둘째는 얼마나 뜯어고칠 수 있냐예요. 정해진 틀 안에서 편하게 쓰는 대신 자유가 적은 것과, 배우기는 힘들어도 무엇이든 만들 수 있는 것으로 나뉘어요. 이 두 축을 머리에 넣고 하나씩 보면 성격이 또렷하게 보여요.
왜 이 구분이 중요하냐면, 지금의 편함과 나중의 자유가 맞바꿈 관계이기 때문이에요. 완제품은 오늘 편하지만 특이한 요구가 생기면 벽에 부딪혀요. 재료형은 오늘 고생스럽지만 원하는 건 뭐든 만들 수 있죠. 그러니 내 프로젝트가 어느 쪽에 가까운지부터 정직하게 따져봐야 해요.
17.2 Quill은 언제 쓰기 좋아요?
Quill(퀼)은 바로 쓰는 완제품에 가까워요. 설치하고 몇 줄이면 툴바 달린 편집기가 뚝딱 뜨거든요. 굵게, 목록, 링크 같은 기본 서식이 처음부터 들어 있어요.
const editor = new Quill("#editor", { theme: "snow" });
이 한 줄로 편집기가 떠요. Quill은 내용을 델타(Delta)라는 자기만의 JSON 형식으로 다뤄서 다루기 깔끔하고, 문서도 친절해요. 대신 정해진 틀이 강해서 아주 특이한 요구, 예를 들어 블록을 자유자재로 새로 짜는 일에는 벽을 만나요. 게시판, 댓글, 간단한 블로그처럼 보통 수준의 서식이면 Quill이 가성비 최고예요. 실제로 우리가 흔히 보는 글쓰기 창 상당수가 이 부류예요.
한 가지 미리 알아둘 점은, 완제품은 기본 디자인이 이미 정해져 있다는 거예요. 우리 서비스 색이나 분위기와 안 맞으면 CSS로 덮어써야 하는데, 이게 생각보다 손이 가요. 그래도 바닥부터 만드는 것에 비하면 새 발의 피죠. 서식 요구가 평범한 선에서 끝난다면 굳이 어려운 길로 갈 이유가 없어요.
17.3 ProseMirror는 왜 강력하다고 해요?
ProseMirror(프로즈미러)는 결이 완전히 달라요. 이건 완제품이 아니라 엔진이에요. 문서의 구조를 스키마(schema, 어떤 요소가 어디에 올 수 있는지 정한 규칙)로 내가 직접 정의하고, 그 규칙에 맞게만 편집되도록 단단하게 통제해요.
덕분에 말도 안 되는 구조가 절대 안 만들어져요. 예를 들어 표 안에만 들어갈 요소가 엉뚱한 데 끼는 일을 규칙으로 막죠. 노션처럼 복잡하고 규칙이 엄격한 편집기를 만들 때 최고예요. 대신 배우는 곡선이 가파르고, 간단한 편집기 하나 만드는 데도 코드가 꽤 들어요. 뒤에 나올 여러 라이브러리가 이 ProseMirror를 바닥에 깔고 있을 만큼, 이 바닥의 튼튼한 기둥이에요.
ProseMirror의 또 다른 강점은 되돌리기와 협업이 탄탄하다는 거예요. 문서를 변경 조각 단위로 다루도록 설계돼서, 여러 명이 동시에 편집하는 기능도 이 위에서 잘 굴러가요. 대신 이 힘을 다 쓰려면 개념부터 제대로 익혀야 해서, 마감이 급한 프로젝트에 바로 꺼내 쓰긴 부담스러워요.
17.4 TipTap은 ProseMirror랑 무슨 관계예요?
ProseMirror가 강력하지만 날것이라 어렵다고 했죠. TipTap(팁탭)은 바로 그 ProseMirror를 쓰기 편하게 감싼 라이브러리예요. 밑바닥의 힘은 그대로 두고, 기능을 확장(extension) 조각으로 쉽게 붙였다 뗐다 하게 만들었어요. 굵게, 목록, 표 같은 걸 필요한 것만 골라 끼우는 식이라, 편집기가 딱 필요한 만큼만 가벼워져요.
TipTap은 화면을 직접 만드는 방식(헤드리스, headless)이에요. 툴바 디자인이나 버튼 모양을 내 마음대로 짜고, 리액트나 뷰(Vue) 같은 도구와도 잘 붙어요. 정리하면 ProseMirror의 튼튼함은 갖고 싶은데 날것은 부담스러울 때, TipTap이 좋은 중간 지점이에요. 요즘 새로 시작하는 팀들이 많이 고르는 이유죠.
17.5 Slate랑 Lexical은 어떤 경우에 봐요?
Slate(슬레이트)는 리액트 전용 편집기 뼈대예요. 문서를 JSON으로 다루고, 거의 모든 동작을 내가 정의하도록 열어놨어요. 자유도가 아주 높은 대신, 완제품이 아니라 상당 부분을 직접 조립해야 해요. 리액트로 아주 독특한 편집 경험을 만들 때 후보에 올라요.
Lexical(렉시컬)은 메타(Meta, 페이스북 회사)가 만든 비교적 최신 라이브러리예요. 속도와 확장성에 힘을 줬고, 역시 화면을 직접 구성하는 방식이에요. 둘 다 리액트 생태계에서 강점이 있고, 규모가 큰 서비스가 성능까지 챙기며 특색 있는 편집기를 만들 때 검토해요. 다만 둘 다 바로 뜨는 완제품은 아니라, 손이 많이 간다는 점은 각오해야 해요.
참고로 예전엔 Draft.js(드래프트)라는 리액트 편집기도 많이 썼는데, 지금은 관리가 뜸해져 새로 시작할 때는 잘 안 골라요. Lexical이 사실상 그 자리를 이어받은 셈이에요. 이래서 지금 활발한지를 보라는 거예요. 한때 인기였어도 멈춰버린 도구를 새 프로젝트에 얹으면 두고두고 고생해요.
17.6 그래서 저는 뭘 골라야 하나요?
고민을 세 질문으로 줄여볼게요. 첫째, 서식이 얼마나 복잡한가요. 굵게, 목록, 링크, 사진 정도의 보통 수준이면 Quill로 충분해요. 빨리 붙이고 끝낼 수 있어요.
둘째, 노션처럼 규칙이 엄격하고 특이한 편집기가 필요한가요. 그러면 ProseMirror 계열이고, 날것이 부담되면 TipTap으로 시작하세요. 셋째, 리액트로 아주 독특한 경험을 만들고 성능도 중요한가요. 그럼 Slate나 Lexical을 보세요. 마지막으로 하나 당부하면, 유행보다 유지보수예요. 별이 많아도 문서가 부실하거나 업데이트가 끊긴 라이브러리는 나중에 발목을 잡아요. 활발히 관리되고 내가 쓰는 프레임워크와 잘 맞는지를 꼭 확인하세요. 커뮤니티가 살아 있으면 막혔을 때 물어볼 곳도 있고, 예제도 풍부하거든요.
17.7 오늘 정리
오늘은 에디터 라이브러리 고르는 법을 정리했어요. 라이브러리는 완제품이냐 재료냐, 그리고 얼마나 뜯어고칠 수 있냐로 갈렸죠. Quill은 바로 뜨는 완제품이라 보통 수준 서식에 가성비가 좋았고, ProseMirror는 스키마로 구조를 단단히 통제하는 강력한 엔진이지만 어려웠어요. TipTap은 그 ProseMirror를 쓰기 편하게 감싼 좋은 중간 지점이었고, Slate와 Lexical은 리액트에서 자유도와 성능을 노릴 때의 후보였죠. 고를 땐 서식 복잡도, 특이한 요구, 프레임워크 세 질문으로 좁히고, 유지보수가 살아 있는지를 꼭 챙기라고 했어요. 라이브러리를 정했다면 이제 남는 큰 결정 하나, 그 내용을 어떤 형태로 저장할지를 다음에 다뤄요.