Skip to main content
LadeStack LogoLadeStack
Architecture 약 12분 소요 2026년 3월 15일

GB Coder 내부 구조: 브라우저 기반 개발을 위한 듀얼 엔진 아키텍처

Monaco Editor의 고성능 구문 분석과 무지연 격리 샌드박스 실행을 결합한 GB Coder의 클라이언트 중심 아키텍처 기술 심층 분석.

GB Coder 듀얼 엔진 아키텍처 다이어그램

최신 브라우저 기반 코드 편집기는 근본적인 기술적 과제에 직면해 있습니다. 개발자는 Visual Studio Code와 같은 정교한 언어 지능, 자동 완성 및 진단 피드백을 요구하면서도 메인 UI 스레드가 멈추지 않는 즉각적인 실시간 미리보기 실행을 기대합니다.

LadeStack의 대표 웹 기반 개발 환경인 GB Coder를 구축하면서, 우리는 무거운 클라우드 컨테이너 방식을 배제하고 클라이언트 중심의 **듀얼 엔진 아키텍처(Dual-Engine Architecture)**를 설계했습니다. 본 문서에서는 GB Coder가 Monaco Editor, 격리된 iframe 샌드박스, 구조화된 메시지 채널을 어떻게 조율하여 클라이언트 브라우저 내에서 1밀리초 미만의 실행 루프를 달성하는지 설명합니다.


브라우저 내 IDE의 기술적 과제

기존의 웹 기반 IDE는 일반적으로 다음 두 가지 극단 중 하나에 의존했습니다.

  1. 원격 클라우드 가상 머신: 파일 수정 사항이 WebSocket을 통해 클라우드의 컨테이너(Docker 또는 Firecracker microVM)로 전송됩니다. 완전한 POSIX 호환성을 제공하지만 네트워크 지연, 막대한 서버 인프라 비용, 오프라인 사용 불가의 한계가 있습니다.
  2. 단순 메인 스레드 평가: eval()이나 제한 없는 DOM 삽입을 사용하여 최상위 브라우징 컨텍스트에서 코드를 직접 실행합니다. 단 한 번의 while(true) 무한 루프로 브라우저 탭 전체가 멈추고 저장되지 않은 상태가 유실되며 심각한 XSS 위험에 노출됩니다.

GB Coder는 **언어 지능(정적 엔진)**과 **런타임 실행(동적 샌드박스)**을 분리하여 이 두 가지 한계를 모두 극복합니다.

┌────────────────────────────────────────────────────────┐
│                   메인 브라우저 컨텍스트                 │
│                                                        │
│  ┌─────────────────────────┐  postMessage (RPC)        │
│  │   Monaco Editor Core    │ ──────────────────────┐   │
│  │ (AST / 구문 분석 / 린터)│                       │   │
│  └─────────────────────────┘                       │   │
└────────────────────────────────────────────────────┼───┘
                                                     │
                                                     ▼
┌────────────────────────────────────────────────────────┐
│               샌드박스 처리된 iframe 컨텍스트            │
│               sandbox="allow-scripts"                  │
│                                                        │
│  ┌─────────────────────────┐  Blob Object URL          │
│  │   가상 DOM & 콘솔 출력  │ ◄──────────────────────   │
│  │ (완전히 독립된 Window)  │                           │
│  └─────────────────────────┘                           │
└────────────────────────────────────────────────────────┘

엔진 1: Monaco Editor 통합 및 백그라운드 워커

에디터 서피스는 Microsoft의 Monaco Editor 엔진을 기반으로 구축되었으며, 전용 Web Workers 위에서 실행됩니다. 이를 통해 복잡한 구문 분석, 괄호 매칭, TypeScript AST 검증이 메인 렌더링 스레드를 방해하지 않습니다.

// Monaco 언어 워커 풀 초기화
import * as monaco from 'monaco-editor';

self.MonacoEnvironment = {
  getWorkerUrl: function (_moduleId: string, label: string): string {
    if (label === 'typescript' || label === 'javascript') {
      return '/workers/ts.worker.bundle.js';
    }
    if (label === 'html' || label === 'handlebars') {
      return '/workers/html.worker.bundle.js';
    }
    if (label === 'css' || label === 'scss' || label === 'less') {
      return '/workers/css.worker.bundle.js';
    }
    return '/workers/editor.worker.bundle.js';
  }
};

언어 컴파일 작업을 백그라운드 스레드로 분리함으로써, GB Coder는 수천 줄 규모의 단일 페이지 파일에서도 부드러운 60 FPS 타이핑 경험을 유지합니다.


엔진 2: 격리된 샌드박스 실행 컨텍스트

메인 애플리케이션의 보안과 안정성을 보호하면서 실시간 실행 결과를 렌더링하기 위해, GB Coder는 <iframe> 컨테이너 내부에서 동적으로 격리된 HTML 문서를 생성합니다.

<iframe
  id="gb-preview-frame"
  sandbox="allow-scripts allow-modals"
  csp="default-src 'self' 'unsafe-inline' blob: data:; img-src * data: blob:;"
  src="about:blank"
  title="GB Coder Live Execution Preview"
  aria-label="Live Execution Sandbox"
></iframe>

여기서 가장 중요한 결정은 allow-same-origin의 의도적인 배제입니다. 이 속성이 없으면 실행 프레임의 출처가 불투명한 고유 출처(null)로 취급됩니다. 따라서 악성 스크립트가 실행되더라도 다음 데이터에 접근할 수 없습니다.

  • ladestack.in의 로컬 스토리지 및 토큰
  • 쿠키 및 인증 세션
  • IDE 탐색 셸을 구성하는 상위 DOM 요소

양방향 RPC 통신: 콘솔 인터셉트

GB Coder의 하단 디버그 터미널에 런타임 로그를 출력하기 위해, 샌드박스는 네이티브 console 메서드를 가로채 데이터를 직렬화한 후 부모 윈도우로 전송합니다.

// 샌드박스 내에 주입되는 부트스트랩 스크립트
(function installConsoleProxy() {
  const originalLog = console.log;
  const originalError = console.error;

  function serialize(data) {
    try {
      return JSON.parse(JSON.stringify(data));
    } catch (e) {
      return String(data);
    }
  }

  console.log = function (...args) {
    window.parent.postMessage({
      type: 'GB_CODER_CONSOLE_EVENT',
      level: 'log',
      payload: args.map(serialize),
      timestamp: Date.now()
    }, '*');
    originalLog.apply(console, args);
  };

  console.error = function (...args) {
    window.parent.postMessage({
      type: 'GB_CODER_CONSOLE_EVENT',
      level: 'error',
      payload: args.map(serialize),
      timestamp: Date.now()
    }, '*');
    originalError.apply(console, args);
  };
})();

호스트 애플리케이션은 메시지 출처 요소를 엄격히 검증한 후 터미널에 메시지를 출력합니다.

window.addEventListener('message', (event: MessageEvent) => {
  const previewFrame = document.getElementById('gb-preview-frame') as HTMLIFrameElement;
  if (!previewFrame || event.source !== previewFrame.contentWindow) {
    return;
  }

  const { type, level, payload } = event.data ?? {};
  if (type === 'GB_CODER_CONSOLE_EVENT') {
    appendTerminalMessage(level, payload);
  }
});

아키텍처 비교표

아키텍처 특성 기존 클라우드 IDE (Docker) 단순 메인 스레드 Eval GB Coder 듀얼 엔진
실행 지연 시간 300ms ~ 1200ms (네트워크) < 1ms (위험) < 2ms (로컬 메모리)
오프라인 지원 ❌ 인터넷 연결 필수 ⚠️ 불안정 ✅ 코어 에디터 및 샌드박스 오프라인 동작
충돌 격리 ✅ 호스트 보호 ❌ 브라우저 탭 전체 정지 ✅ iframe 격리로 호스트 보호
코드 프라이버시 ⚠️ 클라우드로 코드 전송 ✅ 로컬 한정 ✅ 로컬 클라이언트 연산 (서버로 코드 전송 없음)
사용자당 서버 비용 월 $5 ~ $25 $0 $0 (클라이언트 연산)

IndexedDB를 통한 상태 영구 보존

탭 닫기나 브라우저 재시작으로 인한 데이터 유실을 방지하기 위해, GB Coder는 300ms 디바운스 주기로 모든 변경 사항을 브라우저 내 IndexedDB에 자동으로 저장합니다.

import { openDB } from 'idb';

const DB_NAME = 'gb_coder_workspace';
const STORE_NAME = 'project_files';

export async function persistActiveBuffer(filename: string, content: string): Promise<void> {
  const db = await openDB(DB_NAME, 1, {
    upgrade(database) {
      if (!database.objectStoreNames.contains(STORE_NAME)) {
        database.createObjectStore(STORE_NAME, { keyPath: 'filename' });
      }
    }
  });

  await db.put(STORE_NAME, {
    filename,
    content,
    updatedAt: Date.now()
  });
}

결론 및 제품 안내

듀얼 엔진 아키텍처는 전문적인 개발자 도구를 제공하기 위해 거대한 클라우드 서버 인프라를 운영할 필요가 없음을 입증합니다. Monaco Web Workers와 샌드박스 iframe 격리를 결합함으로써, GB Coder는 최고 수준의 반응 속도, 철저한 프라이버시, 제로 인프라 비용을 동시에 달성했습니다.

GB Coder의 실제 작동을 확인하려면 LadeStack의 GB Coder 안내 페이지를 방문하거나 code.ladestack.in에서 직접 IDE를 실행해 보세요. 추가 기술 문서는 개발자 문서에서 확인하실 수 있습니다.

More Engineering Articles