The project's README from github.com/edwardkim/rhwp. As one markdown file: README.md.
알(R), 모두의 한글 — 알에서 시작하다
All HWP, Open for Everyone
한국어 | English
HWP/HWPX 파일과 지원되는 HML 문서를 어디서든 열어보세요. 무료, 설치 없이.
rhwp는 Rust + WebAssembly 기반의 오픈소스 HWP/HWPX 뷰어/에디터입니다. 닫힌 포맷의 벽을 깨고, 모든 사람, 모든 AI, 모든 플랫폼에서 한글 문서를 자유롭게 읽고 쓸 수 있게 합니다.
온라인 데모 | VS Code 확장 | Open VSX
혼자 뼈대를 세우고, 함께 살을 붙이고, 모두의 것으로 완성한다.
현재는 v0.8.6 — v1.0 조판 엔진 체계화를 중심으로 작업하면서, 40명이 넘는 외부 기여자와 두 명의 공동 유지보수자(콜레보레이터)가 참여하는 v2.0 협업 기반도 함께 발전시키고 있습니다. 버전별 목표와 완료 기준, 함께 진행되는 작업, AI 활용 세부 로드맵의 위치는 프로젝트 로드맵에서 설명합니다. rhwp 업스트림에 기여할 기능과 별도 다운스트림 프로젝트에서 구현할 제품의 경계도 같은 문서에서 확인할 수 있습니다.
역공학 완성, 읽기/쓰기 기반 구축
HML은 실제 corpus로 확인된 HWPML 2.9/2.91 구조만 제한 지원합니다. 지원 범위의 수식은 가져와 편집할 수 있고, 보존 불가 요소가 없는 HML 원본은 preflight 검사 후 HML로 다시 저장할 수 있습니다. 그림·내장/외부 리소스 등 미지원 요소는 경고하고 손실 저장을 차단합니다.
사이클별 상세 변경 사항(기여자 목록 포함)은 CHANGELOG.md에 기록합니다.
--features native-skia)--text-as-paths 지원, 바이트 재현성), native Skia direct opt-in(--features native-skia, --backend direct)PageRenderTree → PageLayerTree (Rust DocumentCore::build_page_layer_tree, WASM getPageLayerTree) — schemaVersion: 1, 호환 변경은 additive 원칙--features native-skia)?renderer=auto를 명시하면 bounded document preflight가 완전하고 적격이며 필요한 문서 폰트를 준비할 수 있는 경우만 CanvasKit으로 고정합니다. 표준 선·도형 점선과 수평 글자 겹침, 탭 리더, 밑줄·취소선·강조점, 위치가 확정된 공백·탭·문단 끝·줄바꿈 부호, nominal glyph replay가 안전한 일반 TextRun의 세로쓰기·장평·음영·그림자·외곽선·양각·음각은 CanvasKit이 직접 재생합니다. 방향과 cluster advance 권한이 아직 없는 복합 shaping 문자, 옛한글·boxed-PUA와 장평 또는 paint effect의 조합, 세로·회전된 특수 시각 op, [표], [그림] 같은 구조 조판 부호를 포함하는 showControlCodes, 판정·초기화·리소스 준비·런타임 실패는 해당 문서 revision 전체를 Canvas2D로 고정합니다. ?renderer=canvas2d와 ?renderer=canvaskit은 명시적 강제 선택입니다.TextRun 폴백 (호환 계약)72/96 변환을 사용합니다. 손실되는 gradient/pattern/shadow/connector/image adjustment는 SVG backend 사용을 안내하며 실패하고, Raw SVG만 --raster-dpi 기반 bounded raster fallback을 사용합니다.웹 페이지에 HWP 에디터를 통째로 임베드합니다. 메뉴, 툴바, 서식, 표 편집 — 모든 기능을 그대로 사용할 수 있습니다.
npm install @rhwp/editor
<div id="editor" style="width:100%; height:100vh;"></div>
<script type="module">
import { createEditor } from '@rhwp/editor';
const editor = await createEditor('#editor');
</script>
WASM 기반 파서/렌더러를 직접 사용하여 HWP 파일을 SVG로 렌더링합니다.
npm install @rhwp/core
import init, { HwpDocument } from '@rhwp/core';
globalThis.measureTextWidth = (font, text) => {
const ctx = document.createElement('canvas').getContext('2d');
ctx.font = font;
return ctx.measureText(text).width;
};
await init({ module_or_path: '/rhwp_bg.wasm' });
const resp = await fetch('document.hwp');
const doc = new HwpDocument(new Uint8Array(await resp.arrayBuffer()));
document.getElementById('viewer').innerHTML = doc.renderPageSvg(0);
| 패키지 | 용도 | 설치 |
|---|---|---|
| @rhwp/editor | 완전한 에디터 UI (iframe) | npm i @rhwp/editor |
| @rhwp/core | WASM 파서/렌더러 (API) | npm i @rhwp/core |
빌드 도구 없이 CLI(그리고 아래 MCP 서버)를 바로 쓰려면
Releases에서 플랫폼 바이너리를
받으세요 — 매 릴리스에 linux x86_64 · macOS(x86_64/aarch64) · windows x86_64
4종과 무결성 검증용 SHA256SUMS.txt 가 첨부됩니다.
tar xzf rhwp-v*-linux-x86_64.tar.gz # windows 는 zip 해제
sha256sum -c SHA256SUMS.txt --ignore-missing # 무결성 확인 (선택)
./rhwp/rhwp capabilities # 첫 확인 — 전 명령 기계 계약 자기서술
PATH 에 두면 아래 MCP 절의 "command": "rhwp" 가 그대로 동작합니다.
처음 프로젝트에 참여하는 개발자는 온보딩 가이드를 먼저 읽어보세요. 프로젝트 아키텍처, 디버깅 도구, 개발 워크플로우를 한눈에 파악할 수 있습니다.
rust-toolchain.toml 기준)cargo build # Development build
cargo build --release # Release build
cargo test # Run tests (3,400+ tests)
WASM 빌드는 Docker를 사용합니다. 플랫폼에 관계없이 동일한 wasm-pack + Rust 툴체인 환경을 보장하기 위함입니다.
cp .env.docker.example .env.docker # 최초 1회: 환경변수 템플릿 복사
docker compose --env-file .env.docker run --rm wasm
빌드 결과물은 pkg/ 디렉토리에 생성됩니다.
cd rhwp-studio
npm install
npx vite --host 0.0.0.0 --port 7700
Open http://localhost:7700 in your browser.
rhwp 는 MCP(Model Context Protocol) 서버를 내장한다 — 설정 한 줄이면 Claude Code 등 MCP 호스트가 HWP/HWPX 를 읽고·검색하고·채우고·변환한다:
// .mcp.json
{ "mcpServers": { "rhwp": { "command": "rhwp", "args": ["mcp-serve"] } } }
rhwp 실행 파일은 위 "설치" 절의 릴리스 바이너리면 충분하다 — 소스 빌드 없이
바로 동작한다.
첫 호출 3종 (조사 → 위치 → 채움):
hwp_info { "path": "문서.hwp" } // 규모·형식 파악
hwp_search { "path": "문서.hwp", "query": "위임전결" } // 몇 쪽 어느 셀인지
hwp_fill_fields { "path": "서식.hwp", "data": {"성명":"홍길동"} } // 누름틀 채움
대형 문서는 hwp_open → hwp_doc_* 세션 도구로 재파싱 없이 반복 조회·편집한다.
전체 도구 지도·오류 의미론은 MCP 통합 가이드,
막히면 에이전트 실패 사전.
CLI 만 쓸 때의 입구는 rhwp capabilities 한 번이면 된다(전 명령 기계 계약 자기서술).
rhwp export-svg sample.hwp # Export to output/
rhwp export-svg sample.hwp -o my_dir/ # Export to custom directory
rhwp export-svg sample.hwp -p 0 # Export specific page (0-indexed)
rhwp export-svg sample.hwp --debug-overlay # Debug overlay (paragraph/table boundaries)
rhwp export-png sample.hwp -o out/ # PNG (requires --features native-skia build)
rhwp export-pdf sample.hwp -o out.pdf # PDF (byte-reproducible)
rhwp export-pdf sample.hwp --text-as-paths # Text as vector paths (font-free)
rhwp dump sample.hwp # Full IR dump
rhwp dump sample.hwp -s 2 -p 45 # Section 2, paragraph 45 only
rhwp dump-pages sample.hwp -p 15 # Page 16 layout items
rhwp info sample.hwp # File info (size, version, sections, fonts)
export-svg --debug-overlay → Identify paragraphs/tables by s{section}:pi={index} y={coord}dump-pages -p N → Check paragraph layout list and heightsdump -s N -p M → Inspect ParaShape, LINE_SEG, table propertiesNo code modification needed for the entire debugging process.
src/
├── main.rs # CLI entry point
├── parser/ # HWP/HWPX file parser
├── model/ # HWP document model
├── document_core/ # Document core (CQRS: commands + queries)
│ ├── commands/ # Edit commands (text, formatting, tables)
│ ├── queries/ # Queries (rendering data, pagination)
│ └── table_calc/ # Table formula engine (SUM, AVG, PRODUCT, etc.)
├── renderer/ # Rendering engine
│ ├── layout/ # Layout (paragraph, table, shapes, cells)
│ ├── pagination/ # Pagination engine
│ ├── equation/ # Equation parser/layout/renderer
│ ├── typeset.rs # Typeset engine (main pagination)
│ ├── svg.rs # SVG output
│ ├── web_canvas.rs # Canvas output
│ └── skia/ # Native Skia PNG/PDF (--features native-skia)
├── paint/ # PageLayerTree paint IR + replay planes
├── emf/ # EMF parser + SVG converter
├── ooxml_chart/ # OOXML chart parser + SVG renderer
├── serializer/ # HWP/HWPX/HML serializer (save)
└── wasm_api.rs # WASM bindings
rhwp-studio/ # Web editor (TypeScript + Vite)
├── src/
│ ├── core/ # Core (WASM bridge, types)
│ ├── engine/ # Input handlers
│ ├── hwpctl/ # hwpctl compatibility layer
│ ├── ui/ # UI (menus, toolbars, dialogs)
│ └── view/ # Views (ruler, status bar, canvas)
├── e2e/ # E2E tests (Puppeteer + Chrome CDP)
│ └── helpers.mjs # Test helpers (headless/host modes)
npm/editor/ # @rhwp/editor (iframe embed package)
rhwp-chrome/ rhwp-firefox/ # Browser extensions (+ rhwp-safari, rhwp-vscode)
rhwp-shared/ # Shared frontend modules
assets/fonts/ # Canonical open-source font root
mydocs/ # Project documentation (Korean)
├── orders/ # Daily task tracking (archives/: past months)
├── plans/ # Task plans (archives/: completed)
├── working/ report/ # Stage reports / final reports
├── pr/ # External PR review records (archives/)
├── feedback/ # Code review feedback
├── tech/ manual/ # Technical docs / guides
└── troubleshootings/ # Troubleshooting records
scripts/ # Build & quality tools
├── metrics.sh # Code quality metrics collection
└── dashboard.html # Quality dashboard with trend tracking
이것은 바이브 코딩이 아닙니다. AI가 주는 코드를 읽지도 않고 수락하는 것이 아닙니다. 모든 계획은 검토되고, 모든 결과물은 검증되며, 모든 결정의 뒤에는 사람이 있습니다.
바이브 코딩 — AI 출력을 읽지 않고 수락하고, AI에게 아키텍처 결정을 맡기고, 이해하지 못하는 코드를 배포하는 것 — 은 함정입니다. 겉보기에는 동작하지만, 이해하지 못했기 때문에 문제가 생겨도 진단할 수 없는 코드가 만들어집니다.
이 프로젝트는 정반대의 접근을 취합니다. 사람 작업지시자가 방향, 품질, 아키텍처 결정의 완전한 소유권을 유지하고, AI는 혼자서는 불가능한 속도와 규모로 구현을 수행합니다. 핵심 차이: 사람은 절대 생각을 멈추지 않습니다.
| 바이브 코딩 | 이 프로젝트 | |
|---|---|---|
| 사람의 역할 | AI 출력 수락 | 지시, 검토, 결정 |
| 계획 | 없음 — "그냥 만들어" | 계획서 작성 → 승인 → 실행 |
| 품질 관문 | 동작하길 바람 | 3,400+ 테스트 + Clippy + CI + 코드 리뷰 |
| 디버깅 | AI에게 AI 버그 수정 요청 | 사람이 진단, AI가 구현 |
| 아키텍처 | 우연히 형성 | 의도적 설계 (CQRS, 의존성 방향) |
| 문서 | 없음 | 10,000+개 파일의 프로세스 기록 |
| 결과물 | 취약, 유지보수 어려움 | 프로덕션 수준, 450K+ 라인 |
AI는 배율기입니다. 하지만 배율기는 기존 프로세스를 증폭시킵니다. 프로세스 없음 × AI = 빠른 혼돈. 좋은 프로세스 × AI = 비범한 결과물.
이 프로젝트는 Claude Code (Anthropic AI 코딩 에이전트)를 페어 프로그래밍 파트너로 사용하여 개발합니다. 전체 개발 과정이 투명하게 문서화되어 있습니다.
작업지시자 (사람) AI 페어 프로그래머 (Claude Code)
────────────────