Articlestack.convex.dev·2026년 7월 8일·0

Building Convex OS, a Browser-Based React App with Real-Time Sync

Quick Summary

Convex OS는 Windows XP 스타일의 브라우저 기반 React 데스크톱 UI를 Convex의 반응형 데이터베이스 상태 모델 위에 올려, 창 위치·프로세스·파일 상태를 여러 탭에서 실시간으로 공유하게 만든 실험이다.

Building Convex OS, a Browser-Based React App with Real-Time Sync 관련 대표 이미지

🖼️ 인포그래픽

Building Convex OS, a Browser-Based React App with Real-Time Sync 내용을 설명하는 본문 이미지

🖼️ 4컷 인포그래픽

Building Convex OS, a Browser-Based React App with Real-Time Sync 내용을 설명하는 본문 이미지

💡 한 줄 요약

Convex OS는 Windows XP 스타일의 브라우저 기반 React 데스크톱 UI를 Convex의 반응형 데이터베이스 상태 모델 위에 올려, 창 위치·프로세스·파일 상태를 여러 탭에서 실시간으로 공유하게 만든 실험이다.

📌 핵심 요약

  • 글쓴이는 Windows XP 감성의 웹 데스크톱 인터페이스인 Convex OS를 만들며, 거의 모든 UI 상태를 Convex 데이터베이스에 저장하는 방식을 실험했다.
  • 이 프로젝트는 실제 운영체제나 커널을 에뮬레이션하는 것이 아니라, 웹 기술로 데스크톱 메타포를 구현하고 그 상태를 실시간 백엔드와 동기화하는 데 초점을 둔다.
  • 핵심 아이디어는 창 위치, 실행 중인 앱, 파일 업로드 상태처럼 새 탭에서도 동일해야 하는 상태는 Convex에 두고, 렌더링 순간에만 필요한 DOM 위치 같은 값은 React ref나 로컬 상태에 두는 것이다.
  • Convex의 반응형 쿼리 덕분에 별도 웹소켓 동기화, 재연결 처리, 이벤트 중복 제거, 충돌 조정 로직 없이도 한 탭의 변경이 다른 탭에 자동 반영된다.
  • 스키마는 files, processes, windows, messageMetadata 네 개 테이블을 중심으로 설계되며, 파일 업로드 상태와 앱별 프로세스 상태에는 판별 유니언을 사용해 상태별로 신뢰할 수 있는 필드를 명확히 했다.

🧩 주요 포인트

  1. 글쓴이는 Windows XP 감성의 웹 데스크톱 인터페이스인 Convex OS를 만들며, 거의 모든 UI 상태를 Convex 데이터베이스에 저장하는 방식을 실험했다.
  2. 이 프로젝트는 실제 운영체제나 커널을 에뮬레이션하는 것이 아니라, 웹 기술로 데스크톱 메타포를 구현하고 그 상태를 실시간 백엔드와 동기화하는 데 초점을 둔다.
  3. 핵심 아이디어는 창 위치, 실행 중인 앱, 파일 업로드 상태처럼 새 탭에서도 동일해야 하는 상태는 Convex에 두고, 렌더링 순간에만 필요한 DOM 위치 같은 값은 React ref나 로컬 상태에 두는 것이다.
  4. Convex의 반응형 쿼리 덕분에 별도 웹소켓 동기화, 재연결 처리, 이벤트 중복 제거, 충돌 조정 로직 없이도 한 탭의 변경이 다른 탭에 자동 반영된다.
  5. 스키마는 files, processes, windows, messageMetadata 네 개 테이블을 중심으로 설계되며, 파일 업로드 상태와 앱별 프로세스 상태에는 판별 유니언을 사용해 상태별로 신뢰할 수 있는 필드를 명확히 했다.

🧠 상세 정리

1. Convex OS의 출발점과 핵심 실험

글쓴이는 몇 주 전 Convex OS라는 브라우저 기반 React 앱을 만들었다고 소개한다. 이 앱은 Windows XP 데스크톱처럼 보이지만 실제 운영체제가 아니라 웹 브라우저 안에서 실행되는 데스크톱 스타일 인터페이스다. 중요한 점은 창 위치, 실행 중인 프로세스, 사용자가 데스크톱에 끌어다 놓은 파일 같은 대부분의 상태가 Convex 데이터베이스에 저장된다는 것이다. 그래서 두 번째 탭을 열어도 같은 데스크톱이 나타나고, 한 탭에서 창을 움직이면 다른 탭에서도 그 움직임이 반영된다.

2. 웹 데스크톱과 실제 OS 에뮬레이션의 구분

글쓴이는 브라우저 기반 운영체제를 데스크톱 UI가 브라우저 안에 렌더링되고, 창·파일·앱 상태가 네이티브 커널이 아니라 웹 기술로 관리되는 형태라고 설명한다. Convex OS는 x86 칩을 흉내 내거나 WASM에서 리눅스 커널을 부팅하는 프로젝트가 아니다. 대신 웹 데스크톱 UI 레이어를 만들고, 그 상태 관리를 실시간 백엔드에 맡기는 실험에 가깝다. 따라서 어려운 지점도 그래픽이나 커널 호환성이 아니라, 창과 프로세스를 데이터베이스 행으로 모델링하고 여러 탭이 같은 화면 상태에 합의하도록 만드는 데 있다.

3. Windows XP 미학과 프로젝트 동기

프로젝트의 직접적인 동기는 온라인에서 웹 데스크톱 형태의 홈페이지와 인터페이스가 자주 보였고, 글쓴이도 그 패턴을 직접 시도해 보고 싶었다는 데 있다. Windows XP 스타일을 택한 이유는 해당 분위기를 잘 재현할 수 있는 CSS 라이브러리가 이미 있고, 개발자들에게 보여줄 때 향수를 자극하는 효과도 있기 때문이다. Convex 관점에서는 OS 메타포가 상태 관리 실험으로 특히 흥미로웠다. 창, 파일, 프로세스처럼 원래 클라이언트 상태 저장소에 놓이기 쉬운 요소들을 데이터베이스 행으로 밀어 넣었을 때 어디까지 버틸 수 있는지 확인하는 스트레스 테스트였기 때문이다.

4. 프론트엔드 구성과 개발 루프

프론트엔드는 React와 Vite로 구성되며, SSR은 사용하지 않는다. 글쓴이는 이 앱이 본질적으로 상태가 많은 싱글 페이지 앱이기 때문에, 서버에서 데스크톱을 렌더링한 뒤 다시 완전한 반응형 상태 머신으로 하이드레이션하는 과정이 큰 이득 없이 복잡도만 더한다고 본다. 인증은 Convex Auth의 사용자명과 비밀번호 방식을 사용했고, 빠르게 만져보는 데모 성격이라 소셜 로그인은 제외했다. 스타일은 xp.css와 공개 Windows XP 아이콘 세트를 활용하며, 레이아웃 원시 요소는 Basarat의 General Layout System에서 느슨하게 아이디어를 가져왔다.

5. 무엇을 Convex에 넣고 무엇을 로컬에 둘 것인가

Convex OS에서는 창, 프로세스, 파일, 에이전트 스레드처럼 새로고침 뒤에도 유지되고 모든 탭에서 보여야 하는 상태를 Convex에 저장한다. 반대로 작업 표시줄 버튼의 DOM 위치처럼 최소화 애니메이션에만 필요하고 실제 세션 지속성과 관련 없는 값은 React ref에 둔다. 글쓴이가 사용한 기준은 명확하다. 새 탭에서 값이 다르면 잘못된 상태라면 Convex에 있어야 하고, 새 프레임에서만 틀릴 수 있는 값이라면 ref나 컴포넌트 상태에 두면 된다. 이 구분은 프로젝트의 여러 기능을 추가하는 동안 계속 유효하게 작동했다고 설명한다.

6. Convex 반응형 쿼리와 멀티 탭 동기화

멀티 탭 동기화는 Convex 쿼리가 기본적으로 반응형이라는 점에서 나온다. 데이터베이스에 저장된 창 위치, 뷰 상태, 파일 업로드 진행률 같은 값은 구독 중인 모든 클라이언트로 자동 전파된다. 전통적인 스택이었다면 웹소켓을 직접 붙이고, 재연결과 이벤트 중복 제거, 탭 간 충돌 조정까지 처리해야 했을 것이다. 여기서는 mutation이 한 번 실행되고 데이터베이스가 갱신되면, 모든 클라이언트가 같은 형태의 새 상태를 받는다. 다만 창 드래그처럼 업데이트가 매우 잦은 동작에서는 드래그 중에는 로컬 상태를 쓰고, 드래그 종료 시점에만 Convex에 쓰는 절충을 택했다.

7. files 테이블과 업로드 상태 머신

파일 테이블은 이름, 크기, 타입, 데스크톱 위치와 함께 uploadState를 저장한다. uploadState는 created, uploading, uploaded, errored 네 가지 상태를 가진 판별 유니언으로 설계되어 있다. 글쓴이는 storageId 같은 필드를 nullable로 두는 대신, 상태별로 존재할 수 있는 필드를 명시하는 방식을 택했다. 예를 들어 created 상태에는 아직 storage ID가 없지만 uploaded 상태에는 storage ID가 반드시 있어야 하므로, 소비자는 상태 태그를 읽고 어떤 필드에 의존할 수 있는지 알 수 있다. 드래그 앤 드롭 업로드 UI도 이 상태를 읽어 진행률, 미리보기, 오류 표시를 각각 렌더링한다.

8. processes, windows, messageMetadata의 역할

processes 테이블은 실행 중인 앱마다 하나의 행을 두며, 이미지 미리보기, 텍스트 미리보기, OS 안의 Internet Explorer 같은 앱별 상태를 함께 저장한다. 브라우저 프로세스는 URL 히스토리와 현재 URL을 갖고, 이미지 미리보기 프로세스는 파일 참조를 갖는 식으로 앱별 상태의 형태가 달라지기 때문에 여기서도 판별 유니언이 유용하다. windows 테이블은 위치, 크기, 제목, 아이콘, open·minimized·maximized 같은 viewState를 저장하고 프로세스에 속한다. 현재는 프로세스 하나에 창 하나가 대응되지만, 스키마는 한 프로세스가 여러 창을 가질 수 있게 설계되어 있다. messageMetadata 테이블은 Convex agent 컴포넌트가 메시지에 임의 메타데이터를 붙이는 기능을 아직 지원하지 않아, AI 에이전트의 첨부 참조를 별도로 연결하기 위해 사용된다.

🧾 핵심 주장 / 시사점

  • 이 글의 핵심 교훈은 OS 메타포가 화려한 UI 실험이 아니라 상태 설계의 강한 검증 도구가 될 수 있다는 점이다.
  • Convex의 반응형 데이터 모델은 멀티 탭 동기화를 별도 기능으로 구현하는 대신, 데이터베이스를 단일 진실 공급원으로 두는 설계의 결과로 만들었다.
  • 모든 상태를 무조건 서버에 두는 것이 아니라, 새 탭에서도 맞아야 하는 상태와 렌더링 순간에만 필요한 상태를 구분한 점이 프로젝트의 실용적인 균형점이다.

✅ 액션 아이템

  • 창 위치·실행 앱·업로드 진행 등 탭 간 동일성이 필요한 상태는 Convex DB 동기화 대상으로 고정하고, 렌더 순간 값은 ref 또는 로컬 상태로 분리한다.
  • 별도 웹소켓·재연결·중복 제거·충돌 조정 로직 없이 동작한 반응형 쿼리 구조를 기준으로, 탭 분리 시 동시 변경 구간의 데이터 반영 신뢰성을 점검한다.
  • files, processes, windows, messageMetadata 네 테이블을 기준으로 스키마를 정비하고 파일 업로드·앱 프로세스 상태를 판별 유니언으로 타입별 필드 유효성을 명확히 정의한다.

❓ 열린 질문

  • 어떤 상태를 DB 동기화 대상으로 둘지, 어떤 값은 DOM 렌더 전용 로컬/Ref로 분리할지 판단할 기준은 무엇인가?
  • 연결 지연이나 동시 수정이 많은 환경에서 Convex 반응형 쿼리만으로 재연결 처리·중복 반영·충돌 정합성을 충분히 확보할 수 있는가?
  • files, processes, windows, messageMetadata 스키마에서 업로드 상태와 프로세스 상태 전이가 비정상 분기될 때 어떤 규칙으로 복구할 것인가?

관련 문서

공통 태그와 주제 흐름을 기준으로 같이 보면 좋은 문서를 이어서 제안합니다.