토스 에디터 원칙 10가지에서 제가 고른 셋, 그리고 반만 동의하는 하나
![]()
화면에 보이는 문구 하나를 고치려는데 텍스트를 선택할 수 없는 에디터를 상상해 보세요. 상위 컴포넌트를 먼저 잡고 오른쪽 속성 패널에서 해당 텍스트 프로퍼티를 찾아야 바꿀 수 있는 에디터. 토스에서 디자인 에디터와 문서 에디터를 만든 검정바지가 열 가지 원칙으로 정리한 글에서 제가 제일 먼저 멈춘 대목이 이거예요. 열 가지를 다 옮길 생각은 없어요. 대신 자기 실패를 붙여 둔 항목만 골랐습니다. 실패담이 있는 원칙은 교과서가 아니라 청구서거든요.
편집 단위를 정한 건 사용자가 아니라 저장소였어요
텍스트를 못 고르는 이유는 단순했습니다. 그 디자인 에디터의 주요 아티팩트가 코드 컴포넌트라서, 코드 컴포넌트가 최소 편집 단위가 되는 경우가 많았다는 것. 데이터가 컴포넌트의 프로퍼티로 저장되니 시스템 관점에서는 자연스러운 설계였고요. 그런데 사용자는 '컴포넌트의 특정 문자열 프로퍼티'를 바꾸고 싶은 게 아니라 눈앞의 제목을 바꾸고 싶었던 거예요. 캔버스라는 직접 조작의 약속을 한 순간, 보고 가리킬 수 있는 대상과 실제로 편집할 수 있는 대상이 일치해야 한다는 게 이 항목의 결론입니다.

저는 이 실패가 에디터에만 있는 게 아니라고 봐요. 저장 단위를 편집 단위로 그대로 노출하는 건 백엔드 스키마를 화면에 그대로 올리는 관리자 페이지에서도, 설정 화면에서도 매일 일어나거든요. 다만 에디터에서는 그 어긋남이 즉시 드러난다는 차이가 있을 뿐이죠. 해법으로 제시된 것도 내부 모델을 해체하라는 게 아니라 접근의 출발점을 바꾸라는 거예요. 텍스트를 직접 선택하면 시스템이 적절한 프로퍼티를 연결해 주고, 직접 편집이 불가능하면 왜 그런지와 어디서 바꿀 수 있는지를 그 자리에서 알려주는 것. 저장 모델은 두고 진입 경로만 뒤집는 셈이라 구현 비용도 생각보다 크지 않습니다. 더블 클릭, Enter, 드릴다운처럼 상위 객체에서 하위 객체로 자연스럽게 내려가는 경로를 제공하라는 적용 포인트도 같은 맥락이고요. 캔버스의 선택 단위와 속성 패널의 데이터 단위가 어긋나는 지점을 먼저 찾아 적어 보라는 제안은, 이미 만들어진 에디터를 점검하는 팀이라면 당장 할 수 있는 일이라고 봐요.
같은 병이 다른 항목에도 있어요. 컴포넌트 원본을 수정하려면 별도 페이지로 가야 해서 원본 페이지와 인스턴스 페이지를 두 개 띄워 놓고 오가며 작업했다는 대목. 원본과 인스턴스를 엄격히 구분한다는 시스템 관점에서는 합리적이었지만, 사용자는 하나를 바꿨을 때 다른 것이 어떻게 변하는지를 보면서 모델을 배우는데 그 관찰이 막혀 있었던 거죠.

Figma 가 원본과 인스턴스를 같은 캔버스에 둘 수 있게 한 것을 단순한 화면 배치 이상으로 읽은 대목이 저는 이 글에서 제일 좋았어요. 모델의 구조를 문서로 설명하는 대신 편집 결과가 전파되는 모습으로 관계를 이해하게 만든다는 것. 저장소의 분리 기준이 화면의 분리 기준이 된 두 번째 사례이고, 해법은 역시 모델을 없애는 게 아니라 변경이 어디까지 영향을 미치는지를 보이게 하는 쪽이었습니다.
Undo 는 무엇을 되돌리는 기능일까
두 번째로 고른 건 Undo 와 History 항목입니다. 되돌릴 수 없는 도구에서 사용자는 확실한 행동만 반복하고, 언제든 복구할 수 있다는 믿음이 있어야 레이아웃을 크게 바꾸고 낯선 기능을 시험하고 AI 가 만든 결과도 부담 없이 적용해 본다는 것. 여기까지는 다들 아는 내용인데, 실패담은 그 다음에 있어요. 디자인 컴포넌트 기능을 처음 만들 때 실행 후 피드백과 Cmd+Z 경험을 충분히 고려하지 못해서, 기능은 동작하는데 사용자는 실행이 끝났는지 무엇이 달라졌는지 확신하지 못했고, QA 과정에서 특정 행동을 되돌릴 수 없다는 사실을 뒤늦게 발견한 게 그 실패담이에요.

제가 밑줄 친 문장은 이거예요. 사용자가 "방금 한 일"이라고 인식하는 범위가 곧 되돌리기의 기본 단위라는 것. 타이핑 한 글자, 드래그 한 번, 여러 객체의 속성 변경, 수백 개 컴포넌트의 마이그레이션은 서로 다른 의도 단위인데, 시스템 이벤트 단위로 기록하면 원하는 지점까지 돌아가기 위해 수십 번 Cmd+Z 를 눌러야 하죠. 이것도 같은 병이에요. 이벤트라는 시스템의 단위가 의도라는 사용자의 단위를 이긴 것. 그래서 저는 Undo 설계를 데이터 구조 문제로 시작하는 팀은 거의 예외 없이 이 실패를 반복한다고 봐요. 트랜잭션 경계를 먼저 정하고 그 위에 히스토리 스택을 얹으면, 경계가 코드의 편의대로 잡히거든요. 되돌린 뒤 다시 앞으로 갈 수 있도록 Redo 와 분기 정책을 함께 설계하고, Undo 가 불가능한 행동은 실행 전에 명확히 알리고 대체 복구 방법을 제공하라는 항목까지 포함해서, 이 원칙은 기능이 아니라 정책 문서에 가깝습니다.
마이그레이션 같은 대규모 명령에서 단일 Undo 만으로 부족해 실행 전 스냅샷, 변경 내역, 실패한 항목, 복구 지점을 함께 제공했다는 대목은 반대 방향의 교훈이에요. 큰 명령일수록 되돌리기가 한 번의 키가 아니라 절차가 된다는 것. TDS 업데이트와 마이그레이션 기능에서는 명령을 실행 전·중·후·실패·되돌리기의 생애주기로 다뤘고, 그 생애주기 정의가 먼저 있어야 툴바와 단축키와 커맨드 팔레트가 서로 충돌하지 않는다는 원칙 5의 결론과도 이어집니다.
제약이 개입할 타이밍
세 번째는 자유도와 제약 항목이에요. 여기엔 방향이 반대인 실패담이 두 개 붙어 있어서 골랐습니다. 하나는 디자인 컴포넌트의 속성을 만들 때 생성과 할당을 여러 순서로 할 수 있게 열어 뒀더니, 많은 사용자가 먼저 빈 속성을 만들고 나중에 객체를 할당했는데 속성 타입은 객체가 할당돼야 결정할 수 있어서 시스템도 사용자도 알 수 없는 상태가 먼저 만들어졌다는 것. 객체 할당부터 시작하도록 경로를 제한하자 오히려 더 쉽게 이해했다는 게 결과였고요. 다른 하나는 디자인 결과물을 테이블과 규칙으로 강하게 구조화한 프로젝트 방식이 스펙 정리에는 좋았지만, 탐색 단계부터 그 제약을 적용하니 사용자가 답을 찾기도 전에 정해진 칸을 채워야 했고 작업 공간과 정리 공간이 분리되는 비효율이 생겼다는 것.

두 사례를 나란히 놓으면 결론이 나와요. 제약은 오류 비용이 커지는 시점에 강해져야 한다는 것. 탐색 중에는 가이드와 프리뷰로 부드럽게, 저장·배포·공유처럼 결과가 확정되는 순간에는 엄격하게. 저는 이 원칙이 에디터 설계보다 팀의 프로세스 설계에 더 자주 어긋난다고 생각해요. 기획 초반부터 스펙 템플릿을 채우게 하는 조직이 딱 두 번째 실패담과 같은 구조거든요. 정리를 위한 제약을 탐색에 갖다 대면 사람은 탐색을 멈추고 칸을 채웁니다. 그래서 제약마다 시스템의 필수 조건인지 익숙한 관행인지 구분하라는 적용 포인트가 제일 실용적이에요. 속성 타입이 할당 뒤에 정해진다는 건 필수 조건이고, 스펙을 테이블로 정리한다는 건 관행이거든요. 잘못된 상태를 금지하기 전에 자동 보정이나 스냅, 안전한 기본값으로 풀 수 있는지 먼저 보라는 말도 같은 줄에 있는데, 금지는 마지막 수단이라는 뜻으로 읽었습니다.
반만 동의하는 하나: 에디터는 없앨 수 없다는 결론
첫 번째 원칙은 에디터는 폼이 아니라 작업 환경이라는 거예요. AI 와 규칙으로 화면을 결정론적으로 그려 주고 프리셋과 테이블에 조건만 넣으면 완성된 결과를 만들어 주는 빌더를 시도했다가 사용성 테스트에서 가설이 깨졌고, 사용자는 색을 바꾸고 간격을 줄이고 1px 씩 움직여 보면서 비로소 원하는 방향을 알아갔다는 실패담이 붙어 있죠. 테스트용 프로토타입을 만들던 본인조차 로컬 웹을 띄워 놓고 수치를 바꾸며 디자인하고 있었다는 장면까지요.

실패담 자체에는 동의해요. 반만 동의하는 건 거기서 뽑은 일반화입니다. 이 글은 사용자가 작업을 시작할 때 이미 답을 아는지, 작업하면서 답을 발견하는지 먼저 구분하라고 스스로 적어 놨는데, 그 구분을 끝까지 밀면 결론이 달라지거든요. 답을 발견하는 작업에는 에디터가 필요하지만, 답을 이미 아는 작업, 그러니까 패턴이 굳은 기능 화면을 반복해서 찍어내는 일에는 빌더가 맞아요. 빌더는 선택지를 빠르게 조합하는 데 강하지만 결과를 보며 다음 선택을 발견해야 하는 문제에서는 쉽게 경직된다고 글 스스로 적어 두기도 했고요. 토스의 빌더가 실패한 건 빌더라서가 아니라 답을 발견해야 하는 작업에 빌더를 댔기 때문이라고 저는 봅니다. 어느 쪽인지 가르는 잣대도 글 안에 있어요. 사용성 테스트에서 과업 성공 여부만 보지 말고 사용자가 중간에 몇 번 시도하고 비교했는지 관찰하라는 것. 시도 횟수가 거의 없는 작업이라면 빌더로 충분하고, 시도가 반복되는 작업이라면 에디터가 필요한 거죠. 생성 버튼 뒤에 부분 수정·버전 비교·이전 상태 복귀를 붙여야 AI 결과가 실제 작업의 일부가 된다는 처방에는 동의하고요. 그 처방이 에디터를 살리는 방향이 아니라 빌더에 작은 에디터를 붙이는 방향으로도 읽힌다는 게 제 입장이에요.
그 외에 선택 상태가 약해서 속성 패널이 선택 피드백을 대신하고 있었다는 관찰, 드래그 앤드 드롭에서 알고리즘보다 인디케이터와 프리뷰가 핵심이었다는 관찰, 기능 노출을 빈도·문맥·리스크로 층위를 나누라는 원칙, 숙련될수록 빨라지는 경로를 설계하라는 원칙도 있는데, 이쪽은 실패담보다 교과서에 가까워서 뺐습니다.
넷을 겹쳐 놓으면 하나가 남아요. 저장소의 단위가 편집 단위를 정했고, 데이터 분리가 화면 분리를 정했고, 이벤트가 되돌리기 단위를 정했고, 정리용 제약이 탐색을 막았다는 것. 전부 시스템의 단위가 사용자의 단위를 이긴 사례예요. 검정바지는 마지막에 에디터 UX 는 변화를 설계하는 일이라고 적었지만, 저는 조금 다르게 적어 두려고 해요. 에디터 UX 는 단위를 누가 정하느냐의 싸움이고, 기능 명세를 화면이 아니라 현재 상태에서 명령을 거쳐 다음 상태로 쓰라는 이 글의 제안에 한 줄만 보태면 됩니다. 그 명세의 첫 줄에 사용자가 "방금 한 일"이라고 부를 단위를 먼저 쓰는 것. 그게 정해지면 선택도, 되돌리기도, 제약의 타이밍도 그 단위를 따라갑니다.