---
title: "mdcore Engine Architecture Decision"
url: https://memory.wiki/g-jo1g9s
updated: 2026-05-03T12:29:54.638Z
hub: https://memory.wiki/hub/raymindai
concept_count: 12
source: "vscode"
---
# mdcore Engine Architecture Decision

> “유니버설 엔진”이 되려면 뭘로 만들어야 하는가?
>
> Last updated: 2026-03-23
>
> ⚠️ **전략 업데이트 (2026-03-23)**: 기술 결정(Rust/WASM/comrak)은 전부 유효. 변경된 것은 우선순위: 엔진 표면 확장(npm, CLI, VS Code 등)보다 [**mdfy.cc**](http://mdfy.cc) **바이럴 루프**(뱃지 + Chrome 익스텐션)를 먼저 완성. 컴파일 타겟에 **macOS QuickLook** (aarch64-apple-darwin)도 추가됨. 상세: `updatedDirection.md` v5.0 참조.

---

## 핵심 결론: Rust

**Rust core → 다중 타겟 컴파일**이 유일한 정답이다.

*TypeScript로는 “**제품**”을 만들 수 있다. Rust로는 “인프라”를 만든다. mdcore의 비전이 “AI와 사람 사이의 콘텐츠 인프라”라면, 인프라의 언어로 만들어야 한다.*

---

## 왜 Rust인가: Surface Map × Compilation Target 매핑

| \# | Surface | 실행환경 | 필요한 컴파일 타겟 | TypeScript | Rust |
| --- | --- | --- | --- | --- | --- |
| 1 | [mdfy.cc](http://mdfy.cc) (웹 제품) | Browser | WASM / JS | ✅ | ✅ WASM |
| 2 | @mdcore/engine (npm) | Node.js | Native addon / WASM | ✅ | ✅ napi-rs |
| 3 | @mdcore/terminal (CLI) | OS native | 독립 바이너리 | ❌ Node 필요 | ✅ 단일 바이너리 |
| 4 | VS Code 확장 | Node + Web | JS / WASM | ✅ | ✅ 둘 다 |
| 5 | WASM 모듈 | 어디서나 | wasm32 | ❌ 직접 불가 | ✅ 네이티브 |
| 6 | Obsidian 플러그인 | Electron | JS | ✅ | ✅ WASM |
| 7 | Email 렌더러 | Server | Node / Native | ✅ | ✅ |
| 8 | GitHub Action | Docker/Node | 바이너리 / JS | ✅ | ✅ |
| 9 | Slack App | Server | API 서버 | ✅ | ✅ |
| 10 | Raycast 확장 | Node.js | JS | ✅ | ✅ napi-rs |
| 11 | Mobile SDK | iOS/Android | Swift FFI / Kotlin JNI | ❌ 브릿지 필요 | ✅ UniFFI |
| 12 | Cloudflare Workers | Edge | WASM | ❌ 제한적 | ✅ WASM |
| 13 | Deno | Runtime | WASM / ESM | ⚠️ 호환이슈 | ✅ WASM 1st class |
| 14 | macOS Quick Look | Swift + WebKit | WASM (WebKit 내) | ❌ 불가 | ✅ WASM via WebKit |

**결론**: TypeScript는 11/14 표면에서 “돌아가긴” 하지만, 4개 핵심 표면(CLI, Mobile, Edge, macOS Quick Look)에서 구조적 한계가 있다. Rust는 14/14 모두 네이티브로 커버한다.

---

## 실제 선례: “한 언어 → 모든 곳” 패턴

| 프로젝트 | 코어 언어 | 배포 채널 | 교훈 |
| --- | --- | --- | --- |
| SWC | Rust | npm (napi-rs) + WASM + CLI | 20x faster than Babel. Next.js 기본 컴파일러 |
| Biome | Rust | CLI + VS Code (LSP) + WASM (Playground) | 하나의 Service Layer → 3개 인터페이스 |
| Typst | Rust | WASM (웹 에디터) + CLI (네이티브) | 과학 문서 조판. Leptos로 웹 렌더링 |
| tree-sitter | C/Rust | WASM + 네이티브 바인딩 | VS Code, Zed, Neovim 전부 사용 |
| Turbopack | Rust | Next.js 내장 (v16 기본값) | 700x faster than Webpack |

**공통점**: 전부 Rust(또는 C) 코어 → WASM + napi-rs + 네이티브 바이너리 패턴.

---

## Rust MD 생태계 현황

### 파서 후보

| 라이브러리 | CommonMark | GFM | MDX | 확장성 | 사용처 |
| --- | --- | --- | --- | --- | --- |
| comrak | ✅ 0.31.2 | ✅ 전체 | ❌ | 커스텀 포매터, 하이라이터 | GitLab, [crates.io](http://crates.io), Reddit |
| pulldown-cmark | ✅ 0.31 | ⚠️ 부분 | ❌ | 이벤트 기반 | Rust 생태계 표준 |
| markdown-rs | ✅ | ✅ | ✅ | micromark 아키텍처 | Vercel 후원, unified.js 연계 |
| markdown-it-rust | ✅ | ⚠️ | ❌ | 플러그인 시스템 | markdown-it 포트 |

### 추천 조합

```text
Core Parser:   comrak (GFM 완전 지원, 프로덕션 검증)
MDX 지원:      markdown-rs (Vercel 후원, MDX 네이티브)
하이라이팅:    tree-sitter 또는 syntect (Rust 네이티브)
수학:          KaTeX WASM 또는 자체 TeX 파서
다이어그램:    mermaid-js (WASM 아님, JS로 유지)
```

---

## 아키텍처 설계

### 레이어 구조

```text
┌─────────────────────────────────────────────────────────────────────┐
│                        Consumer Layer (JS/TS)                       │
│   mdfy.cc (React)  │  @mdcore/sdk (npm)  │  VS Code  │  Obsidian  │
└──────────┬──────────┴──────────┬──────────┴─────┬─────┴─────┬──────┘
           │                     │                │           │
     ┌─────┴─────────────────────┴────────────────┴───────────┴──────┐
     │                     Binding Layer                              │
     │   WASM (browser/edge)  │  napi-rs (Node)  │  UniFFI (mobile)  │
     └──────────┬─────────────┴──────────┬────────┴──────────┬───────┘
                │                        │                   │
     ┌──────────┴────────────────────────┴───────────────────┴───────┐
     │                     mdcore-engine (Rust)                       │
     │                                                                │
     │   ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────────┐ │
     │   │  Parser   │  │ Renderer │  │Converter │  │Flavor Detect │ │
     │   │ (comrak)  │  │ (custom) │  │ (X↔MD)   │  │  (auto)      │ │
     │   └──────────┘  └──────────┘  └──────────┘  └──────────────┘ │
     │                                                                │
     │   ┌──────────┐  ┌──────────┐  ┌──────────┐                   │
     │   │Highlight │  │  Math    │  │  AST     │                   │
     │   │(syntect) │  │ (TeX)    │  │ (mdast)  │                   │
     │   └──────────┘  └──────────┘  └──────────┘                   │
     └────────────────────────────────────────────────────────────────┘
```

### 핵심 설계 원칙

1. **Zero-copy AST**: Rust 소유권 시스템으로 메모리 복사 최소화
2. **Plugin via Trait**: `trait MdPlugin { fn transform(&self, ast: &mut MdAst); }` — 코어 건드리지 않고 확장
3. **WASM-first 렌더링**: 브라우저에서는 항상 WASM, Node에서는 napi-rs (WASM fallback)
4. **Streaming parser**: 대용량 문서도 첫 토큰부터 렌더 시작 (pulldown-cmark 이벤트 모델)

---

## 컴파일 & 배포 매트릭스

```text
                        mdcore-engine (Rust 소스코드)
                                    │
            ┌───────────────────────┼───────────────────────┐
            │                       │                       │
      wasm-bindgen              napi-rs                cargo build
            │                       │                       │
     ┌──────┴──────┐        ┌──────┴──────┐         ┌──────┴──────┐
     │    WASM     │        │   Native    │         │   Binary    │
     │   (.wasm)   │        │   (.node)   │         │  (ELF/Mach) │
     └──────┬──────┘        └──────┬──────┘         └──────┬──────┘
            │                       │                       │
     ┌──────┼──────┐        ┌──────┴──────┐         ┌──────┴──────┐
     │      │      │        │             │         │             │
  Browser  Edge   Deno    Node.js      Raycast    CLI        GitHub
  mdfy.cc  CF     import  @mdcore/     Extension  @mdcore/   Action
           Worker         engine                  terminal
                                                  brew install
```

### npm 패키지 구조 (SWC 패턴)

```text
@mdcore/engine                    ← 메인 패키지 (JS wrapper + 타입)
@mdcore/engine-linux-x64-gnu      ← Linux x64 네이티브
@mdcore/engine-linux-arm64-gnu    ← Linux ARM64
@mdcore/engine-darwin-x64         ← macOS Intel
@mdcore/engine-darwin-arm64       ← macOS Apple Silicon
@mdcore/engine-win32-x64-msvc     ← Windows
@mdcore/engine-wasm               ← WASM fallback (모든 플랫폼)
```

설치 시 OS/Arch 감지 → 맞는 네이티브 패키지 자동 선택. 없으면 WASM fallback.

---

## TypeScript가 아닌 이유

“TypeScript로 먼저 빠르게 만들고 나중에 Rust로 갈아타자”는 위험하다:

| 항목 | TS 먼저 → Rust 나중에 | Rust 처음부터 |
| --- | --- | --- |
| Phase 1 속도 | ⚡ 빠름 (2-3주) | 🐢 느림 (4-6주) |
| Phase 2 전환 비용 | 💀 전면 재작성 | ✅ 없음 |
| API 호환성 | ⚠️ 갈아탈 때 breaking change | ✅ 처음부터 안정 |
| CLI 배포 | Node 런타임 필요 | 단일 바이너리 |
| 외부 기여자 인식 | “또 하나의 JS 래퍼” | “진짜 인프라” |
| npm 다운로드 성능 | JS 속도 | 25x 빠름 (Unifast 기준) |
| 경쟁사 모방 난이도 | 쉬움 | 어려움 (Rust 모트) |

**가장 위험한 시나리오**: TS로 MVP 만듦 → 유저 모임 → Rust 재작성 필요 → API 호환성 깨짐 → 유저 이탈. SWC가 Babel을 이긴 이유는 “점진적 교체”가 아니라 “처음부터 Rust”였기 때문.

---

## 하지만 현실적으로: 솔로 파운더 + Rust

**걱정**: “Rust 러닝커브가 높지 않나?”

**답변**: mdcore 엔진의 80%는 이미 존재한다.

```text
직접 만들어야 하는 것:
├── Flavor detection logic (~500줄)
├── Renderer customization layer (~1000줄)
├── X→MD converter wrappers (~800줄)
├── WASM binding glue (~200줄)
└── napi-rs binding glue (~200줄)

이미 존재하는 것 (가져다 쓰는 것):
├── comrak → 파싱 + GFM 전체
├── syntect → 코드 하이라이팅
├── pulldown-cmark → 스트리밍 파서 (대용량용)
├── wasm-bindgen → WASM 컴파일
├── napi-rs → Node 바인딩
└── serde → JSON 직렬화
```

실질적으로 작성해야 하는 Rust 코드는 **\~2,700줄** 정도. 나머지는 설정과 glue code.

---

## Phase별 실행 계획

### Phase 1 (Week 1-4): Core Engine + WASM

```text
Week 1: Rust 프로젝트 셋업
  - cargo new mdcore-engine --lib
  - comrak 통합, 기본 파싱/렌더링
  - Flavor detection (GFM, Obsidian, MDX, Pandoc)
  - 테스트 스위트 (CommonMark spec tests)

Week 2: WASM 컴파일 + 웹 통합
  - wasm-bindgen 셋업
  - parse(md) → HTML 함수 WASM으로 노출
  - mdfy.cc (Next.js)에서 WASM import
  - 렌더링 커스터마이징 (테마, 스타일)

Week 3: napi-rs + npm 패키지
  - napi-rs 바인딩
  - @mdcore/engine npm 패키지 첫 배포
  - 플랫폼별 prebuild (linux-x64, darwin-arm64, wasm)
  - TypeScript 타입 정의 자동 생성

Week 4: mdfy.cc MVP
  - Next.js + WASM 엔진 통합
  - 입력 → 렌더링 → 공유 기본 플로우
  - Shiki (하이라이팅), KaTeX (수학), Mermaid (다이어그램)은 JS로 유지
  - Vercel 배포
```

### Phase 2 (Week 5-8): 확장 표면

```text
- @mdcore/terminal (CLI) — cargo build로 네이티브 바이너리
- VS Code 확장 — WASM 번들
- X→MD 변환기 — HTML/PDF/DOCX → MD
- Interactive editing layer — JS/React (WASM 엔진 위)
```

### Phase 3 (Week 9-12): 생태계

```text
- Obsidian 플러그인
- GitHub Action
- Mobile SDK (UniFFI → Swift/Kotlin)
- Canvas mode (tldraw + WASM 엔진)
```

---

## Mermaid: WASM이 아닌 JS로 유지하는 것들

모든 것을 Rust로 만들 필요는 없다. 렌더링의 **일부 레이어**는 JS가 더 적합:

| 컴포넌트 | 언어 | 이유 |
| --- | --- | --- |
| MD 파싱 + AST | Rust | 성능, 유니버설 |
| HTML 렌더링 | Rust | 코어 기능 |
| Flavor 감지 | Rust | 코어 기능 |
| X↔MD 변환 | Rust | 코어 기능 |
| Syntax highlighting | JS (highlight.js) | syntect는 WASM 불가, Shiki보다 경량 |
| Math (KaTeX) | JS | 브라우저 DOM 필요 |
| Diagrams (Mermaid) | JS | SVG 렌더링, DOM 의존 |
| Interactive editing | JS/React | UI 레이어 |
| Mermaid visual editor | JS/React (자체 구현) | tldraw 대신 경량 캔버스. 외부 의존성 0 |
| HTML → MD 변환 | JS (Turndown) | 붙여넣기 자동 감지 |
| 테마/스타일 | CSS/TailwindCSS | 스타일은 코드 아님 |

**원칙**: “데이터를 다루는 것은 Rust, 화면을 다루는 것은 JS”

---

## 최종 기술 스택

```text
┌─────────────── mdcore tech stack ───────────────────────┐
│                                                          │
│  CORE (Rust)                                             │
│  ├── comrak          — MD 파싱 (GFM)                     │
│  ├── pulldown-cmark  — 스트리밍 파싱 (대용량)              │
│  ├── syntect         — 코드 하이라이팅 (서버/CLI용)        │
│  ├── serde           — JSON 직렬화                       │
│  ├── wasm-bindgen    — WASM 바인딩                       │
│  └── napi-rs         — Node.js 네이티브 바인딩             │
│                                                          │
│  BINDING                                                 │
│  ├── @mdcore/engine  — npm 메인 패키지 (TS 타입)          │
│  ├── @mdcore/wasm    — WASM 번들 (브라우저/Edge)          │
│  └── uniffi          — iOS/Android 바인딩 (Phase 3)      │
│                                                          │
│  PRODUCT (TypeScript/React)                              │
│  ├── Next.js 15      — mdfy.cc 웹앱                     │
│  ├── TailwindCSS     — 스타일링                          │
│  ├── shadcn/ui       — UI 컴포넌트                       │
│  ├── Shiki           — 코드 하이라이팅 (브라우저)          │
│  ├── KaTeX           — 수학 렌더링                       │
│  ├── Mermaid         — 다이어그램                        │
│  ├── tldraw          — Canvas mode (Phase 2)             │
│  └── Supabase        — Auth, DB, Storage                 │
│                                                          │
│  INFRA                                                   │
│  ├── Vercel          — 프론트엔드 배포                    │
│  ├── Cloudflare Workers — Edge WASM 실행                 │
│  ├── GitHub Actions  — CI/CD + 멀티플랫폼 빌드           │
│  └── crates.io       — Rust 크레이트 배포                 │
│                                                          │
└──────────────────────────────────────────────────────────┘
```

---

## 이것이 만드는 모트(Moat)

1. **기술 모트**: Rust로 작성된 MD 엔진을 JS로 복제하는 것은 수개월\~수년. JS 엔진을 Rust로 대체하는 것도 마찬가지. 먼저 Rust로 가는 쪽이 이김.
2. **배포 모트**: 하나의 코어가 13개 표면에 동시 배포. 경쟁자는 각 표면마다 별도 구현 필요.
3. **성능 모트**: WASM 엔진이 JS 대비 3-25x 빠름. 대용량 문서에서 체감 차이 극명.
4. **인식 모트**: “Rust로 만든 인프라”는 개발자 커뮤니티에서 “진짜”로 인식됨. SWC, Biome, Turbopack이 증명.

---

*“Infrastructure should be written in infrastructure languages.”— mdcore의 기술 철학*

---

## Summary
The mdcore engine should be built in Rust with multi-target compilation (WASM, napi-rs, native binaries) rather than TypeScript, enabling deployment across 14 different surfaces (web, CLI, mobile, edge computing, etc.) while TypeScript structurally limits coverage to 11 surfaces and requires Node.js runtime for CLI/mobile/edge use cases. This approach, proven by projects like SWC and Biome, creates technical and deployment moats that make the system difficult for competitors to replicate.

## Themes
- Rust as universal infrastructure
- Multi-platform compilation strategy
- WASM-first architecture

## Key takeaways
- Rust core with multi-target compilation is the only viable answer for universal content infrastructure that must work in browser, Node.js, native CLI, mobile, Edge, and OS-specific contexts.
- TypeScript can theoretically run on 11 out of 14 deployment surfaces, but faces structural limitations on CLI (requires Node runtime), mobile (needs language bridge), Edge (Cloudflare Workers WASM limitations), and macOS QuickLook integrati
- The recommended parser combination is comrak for GFM support plus markdown-rs for MDX native support, with code highlighting via syntect, math via KaTeX WASM, and diagrams via Mermaid JS to avoid unnecessary Rust reimplementation.
- The Phase 1 execution plan targets WASM compilation and npm packaging within 4 weeks using wasm-bindgen and napi-rs, establishing foundation for CLI, VS Code, and Obsidian extensions in Phase 2.
- Rendering layers for syntax highlighting, math, and diagrams should remain in JavaScript because they require browser DOM manipulation and visual output, while parsing and flavor detection must be in Rust as core infrastructure.
- The npm package structure follows SWC pattern with platform-specific native builds (@mdcore/engine-darwin-arm64, @mdcore/engine-linux-x64-gnu, etc.) auto-selected at install time with WASM fallback.

## Insights
- TypeScript-first followed by Rust rewrite is architecturally dangerous because it breaks API compatibility and risks user churn, making the Rust-first approach more prudent despite higher initial engineering cost.
- The document argues that 80% of mdcore engine functionality already exists in mature libraries (comrak, syntect, serde), reducing novel Rust code to approximately 2,700 lines, making the Rust learning curve manageable for a solo founder.
- The technical moat is not speed alone but the structural ability to compile a single codebase into 14 different deployment surfaces simultaneously, a capability TypeScript cannot natively provide for CLI, mobile FFI, and Edge platforms.

## Open questions / gaps
- How will the Flavor detection logic specifically handle MDX support when comrak lacks native MDX but markdown-rs is positioned as the MDX solution, and which library becomes the primary parser?
- What is the concrete performance target and benchmark methodology for the 3-25x speed improvement claim over JavaScript alternatives?
- How does the UniFFI mobile binding strategy address the iOS App Store and Google Play Store distribution and code signing requirements for native Rust libraries?

## Concepts in this document
- **comrak** _(entity)_
  Selected Rust markdown parser library providing CommonMark and GFM support with proven production use in GitLab and crates.io.
- **Rust core architecture** _(concept)_
  Central architectural decision to build mdcore engine in Rust rather than TypeScript for universal multi-target compilation and infrastructure-grade performance.
- **Multi-target compilation** _(concept)_
  Core design principle enabling single Rust codebase to compile to 14 deployment surfaces (WASM, native binary, napi-rs, UniFFI) simultaneously.
- **WASM binding layer** _(concept)_
  Intermediate compilation target that enables Rust core to run in browsers, edge computing, and serverless environments without rewrite.
- **mdfy.cc viral loop** _(entity)_
  Primary product launch surface prioritizing badge + Chrome extension over immediate npm/CLI expansion per 2026-03-23 strategy update.
- **comrak parser** _(entity)_
  Selected Rust markdown parser providing complete CommonMark and GFM support with proven production validation in GitLab and crates.io.
- **Syntax highlighting** _(concept)_
  Rendering feature that colors code blocks for improved readability.
- **Infrastructure language philosophy** _(concept)_
  Core principle that content infrastructure must be built in systems languages like Rust, not application languages like TypeScript.
- **TypeScript consumer layer** _(concept)_
  Product-facing React/Next.js interfaces (mdfy.cc, VS Code, Obsidian) that consume Rust engine via bindings while handling UI and styling.
- **UniFFI mobile binding** _(concept)_
  Cross-platform FFI interface enabling Rust core to generate Swift and Kotlin bindings for iOS/Android SDKs in Phase 3.
- **Zero-copy AST design** _(concept)_
  Memory optimization strategy leveraging Rust ownership system to minimize AST copying across compilation boundaries.
- **napi-rs** _(entity)_
  Rust-to-Node.js native binding mechanism providing npm package integration and performance vs pure-JS alternatives.

## Concept relations (within this doc's concepts)
- **Rust core architecture** enables universal **Multi-target compilation**
- **Rust core architecture** delegates parsing to **comrak parser**
- **Zero-copy AST design** optimization principle for **Rust core architecture**
- **Infrastructure language philosophy** justifies choice of **Rust core architecture**
- **WASM binding layer** powers browser execution for **mdfy.cc viral loop**
- **UniFFI mobile binding** extends coverage to **Multi-target compilation**
- **Rust core architecture** enables **Multi-target compilation**
- **Rust core architecture** selects for parsing **comrak**
- **WASM binding layer** powers browser execution **mdfy.cc viral loop**
- **napi-rs** bridges to npm **TypeScript consumer layer**
- **Rust core architecture** uses **comrak parser**
- **Multi-target compilation** produces **UniFFI mobile binding**
- **Infrastructure language philosophy** justifies **Rust core architecture**
- **WASM binding layer** powers **mdfy.cc viral loop**
- **Multi-target compilation** produces **WASM binding layer**
- **Rust core architecture** feeds **TypeScript consumer layer**
- **Zero-copy AST design** optimizes **Rust core architecture**
- **Syntax highlighting** serves **TypeScript consumer layer**

_Hub canonical:_ https://memory.wiki/hub/raymindai
_Concept digest:_ https://memory.wiki/raw/hub/raymindai?digest=1&compact=1
