기능가격문서블로그
mote 받기
← 블로그
개발·2026년 6월 28일·읽는 시간 6분

Rust 코어 하나에 플랫폼별 셸을 얹은 이유

세 OS에 같은 에디터를 내려면 UI를 한 번만 짜는 길이 있어요. 우리는 그 길을 한 번 갔다가 되돌아 나와서, 코어 하나에 플랫폼별 얇은 셸 셋을 얹었어요.

m
mote
셸 셋이 위, 코어가 가운데, 텍스트 렌더링과 게이트가 아래. 마크다운 해석·편집 연산·파일 쓰기는 전부 가운데 상자 안에 있어요.
셸 셋이 위, 코어가 가운데, 텍스트 렌더링과 게이트가 아래. 마크다운 해석·편집 연산·파일 쓰기는 전부 가운데 상자 안에 있어요.

같은 에디터를 리눅스와 macOS, 윈도우에 내놓으려면 UI를 세 번 만들어야 해요.

처음에는 그 비용을 피하고 싶었어요. 하나의 크로스 플랫폼 툴킷으로 세 운영체제에 같은 화면을 그렸죠. 그 결정으로 첫 성능 게이트를 통과했고, 한글 입력 첫 마일스톤도 통과했어요.

그러다 우선순위가 바뀌었어요.

성능이 디자인보다 중요하고, 디자인이 비용보다 중요하다. 시간과 비용은 제약에서 제외한다.

이 기준으로 다시 보니 답도 달라졌어요.

하나의 UI를 포기했어요

크로스 플랫폼 툴킷에는 분명한 장점이 있어요. 한 번 만든 기능을 여러 운영체제에서 쓸 수 있죠.

대신 치러야 하는 비용도 있었어요. 메모리를 40~60MB 더 사용했고, 실행은 150~200ms 느렸어요. 글자 표현은 운영체제의 기본 텍스트 엔진보다 아쉬웠고, 시스템 고유의 시각 효과도 온전히 쓸 수 없었어요.

개발 비용이 중요할 때는 합리적인 선택이었어요. 하지만 비용을 제약에서 빼자 더는 감수할 이유가 없었어요.

그래서 문서를 처리하는 코어는 Rust로 만들고, 화면을 담당하는 셸은 운영체제마다 따로 만들기로 했어요.

기존 기술이 나빠서가 아니에요. 우선순위가 달라지면 같은 선택지에서도 다른 답이 나와요. 우리는 기능을 세 번 만드는 비용을 내고, 성능과 글자 품질, 시스템다운 경험을 되찾기로 했어요.

다만 모든 것을 버리지는 않았어요.

측정 규율 셋은 그대로 가져왔어요. 포인터를 창 밖에 두기, 창을 이름으로 정확히 찾기, 프레임을 동기로 세기. 한글 입력 설계 원칙도 함께 옮겼어요. 운영체제에는 커서가 있는 줄만 보여주고, 조합 중인 글자는 꾸미지 않아요. 상태가 어긋나면 추측하지 않고 다시 맞춰요.

코드는 버려도 검증된 원칙은 남아요.

셸의 역할을 작게 정했어요

플랫폼별 셸이 많은 일을 맡기 시작하면 세 제품은 금세 달라져요. 그래서 셸이 할 일과 하지 않을 일을 분명하게 정했어요.

셸은 창을 만들고 글자를 그려요. 키보드와 포인터 입력을 코어에 전달하고, 한글 입력을 편집 명령으로 바꿔요. 운영체제의 시각 효과도 적용해요.

반면 마크다운을 해석하지 않아요. 줄바꿈 말고는 레이아웃도 정하지 않고, 파일을 저장하거나 라이선스를 판단하지도 않아요.

이 원칙은 문서에만 적어 두지 않았어요. 셸에 마크다운 해석 코드가 들어오면 자동 검사에서 빌드가 멈춰요.

한 셸에서만 문법을 처리하기 시작하면 운영체제마다 결과가 조금씩 달라질 수 있어요. 이런 문제는 찾기도 어려워요. 한 셸에서만 표가 다르게 보이는데, 정작 원인은 표를 그리는 코드가 아닐 수도 있으니까요.

코어만 오래 남게 만들었어요

코어는 어떤 UI 기술에도 기대지 않아요. 창이 없어도 터미널에서 단독으로 테스트할 수 있어요.

문서 편집과 마크다운 해석, 되돌리기, 검색, 아웃라인, 파일 저장, 내보내기, 라이선스 검증을 모두 코어가 맡아요.

UI 없이 터미널에서 실행한 코어 테스트. 단위 테스트 194개와 별도의 증분 블록 테스트가 통과했어요.
UI 없이 터미널에서 실행한 코어 테스트. 단위 테스트 194개와 별도의 증분 블록 테스트가 통과했어요.

사용자가 키 하나를 누르면 셸은 그 입력을 코어에 전달해요. 코어는 문서를 고치고, 바뀐 부분 주변만 다시 해석해요. 화면에 보이는 내용만 계산한 뒤 달라진 결과를 셸에 돌려줘요. 셸은 영향을 받은 줄만 다시 그리고 한 프레임을 완성해요.

이 과정에서 문서 전체를 다시 읽는다면 단순한 성능 문제가 아니에요. 처음 정한 예산을 어긴 거예요.

정확성도 코어에서 한 번만 검증해요. CommonMark 공식 예제 652개를 모두 통과해야 하고, 통과 개수가 줄어들면 빌드가 실패해요. 예상하지 못한 입력을 계속 넣는 퍼징 테스트도 해요.

저장한 파일이 원본과 바이트로 같은지도 확인해요. 왕복 비율이 1.0에 못 미치면 느린 게 아니라 파일을 잃은 거예요.

셸이 바뀌어도 코어는 그대로 남아요. 리눅스와 윈도우에서는 코어를 직접 연결하고, macOS에서는 Swift 연결 코드를 사용해요. macOS 셸은 AppKit과 TextKit 2로, 윈도우 셸은 DirectWrite로 만들고 있어요.

문서는 같게, 손맛은 각 운영체제답게 만드는 게 목표예요.

문서는 같고, 사용감은 달라요

경계를 정하니 무엇을 통일해야 하는지도 선명해졌어요.

통일해야 하는 것은 문서예요. 어느 운영체제에서 저장하든 파일 내용은 바이트 단위로 같아야 해요. 표 정렬과 줄 끝, 마지막 줄바꿈도 달라지지 않아야 하죠.

마크다운 정확성은 코어에서 이미 검증해요. 새로운 셸을 만들 때마다 다시 증명할 필요가 없어요. 새 플랫폼에서 확인할 것은 사용감과 성능이에요.

반대로 손에 닿는 경험은 통일하지 않아요.

글자는 각 운영체제의 텍스트 엔진으로 그려요. 한글 입력기도 운영체제의 방식을 직접 사용해요. 반투명 효과 역시 macOS와 윈도우에서는 시스템 기능을 쓰고, 같은 기능이 없는 리눅스에서는 필요한 부분만 직접 그려요.

창 버튼의 위치, 메뉴의 형태, 단축키의 보조키도 억지로 맞추지 않아요. 서로 다른 운영체제에서 같은 픽셀을 보여주는 건 목표가 아니에요. 각 운영체제에서 자연스럽게 느껴지는 게 더 중요해요.

출시 조건도 운영체제별로 정했어요. 성능 기준을 통과하고, 기본 한국어 입력기로 실제 테스트를 마쳐야 출시할 수 있어요.

벤치마크 표에 그 플랫폼 행이 생기는 것도 빌드가 실제로 나온 뒤예요. 재지 않은 줄을 미리 적으면 그 표의 나머지 줄까지 믿기 어려워지니까요.

이 선택에는 분명한 대가가 있어요

같은 기능을 세 번 만들어야 해요. 한글 입력도 세 번 구현하고, 빌드 환경도 세 벌 관리해야 해요.

윈도우와 macOS는 지금 사용하는 머신에서 빌드하거나 디버깅할 수 없어요. 별도의 하드웨어와 자동화 환경이 필요해요. 그래서 두 플랫폼에는 날짜를 적지 않아요.

이 결정을 다시 검토할 조건도 남겼어요. 비용을 제약에서 제외한 것이 결정의 전제예요. 필요한 하드웨어를 확보하지 못하면 해당 플랫폼의 일정만 늦춰요. 리눅스 출시는 그대로 진행해요.

결정에는 이유뿐 아니라 다시 생각할 조건도 필요해요. 그래야 상황이 달라졌을 때 논쟁을 처음부터 반복하지 않아요.

오래 남아야 하는 것은 코어예요. 셸은 언제든 버릴 수 있어야 해요.

버릴 수 있는 것만 플랫폼에 맡겼어요.

← 이전 글모드를 바꿔도 문서는 하나다다음 글 →글자를 직접 그리지 않고 플랫폼에 맡긴 이유
RSS로 새 글 받기
글을 위한 기본
한국어
© 2026 mote
멘토그래드 (MentorGrad) · 대표 윤상빈 · 사업자등록번호 475-15-02958 · 통신판매업신고 2026-서울도봉-0075 · 서울특별시 도봉구 마들로13길 61, 씨드큐브 창동, 4층 C동 411H호 · 010-2012-3741 · support@motemd.com