트렌딩 딥다이브 · 2026-07-22 · TrendShift Daily #10 · HAYDENBLEASEL

haydenbleasel/blume 딥다이브
— 클론할 스타터가 없는 마크다운-우선 문서 프레임워크

blume은 마크다운/MDX 파일을 폴더에 넣고 blume dev 한 줄만 실행하면 검색·내비게이션·테마·OG 이미지·AI 기능까지 갖춘 프로덕션급 문서 사이트를 얻는 문서 프레임워크(documentation framework)다. 한 줄 요약: 클론할 스타터도, 유지보수할 앱도 없이 오직 콘텐츠만 건드린다.

기존 문서 도구(Docusaurus·Nextra·Mintlify·Fumadocs)와 결정적으로 다른 점 — 스타터를 클론해 내 소유의 앱을 떠안지 않는다. blume의 철학은 "프레임워크가 곧 템플릿(the framework is the template)". 뒤에서 숨겨진 Astro 프로젝트를 .blume/ 폴더에 생성·구동하고, 기본값을 벗어날 때만 설정을 한 파일씩 추가한다(opt-in). 완전한 제어가 필요하면 blume eject로 독립 Astro 앱으로 승격한다.

(저장소 haydenbleasel/blume · 모노레포(Bun 1.3.14 + Turborepo) · 핵심 패키지 blume v1.1.3 · Astro 7 + React 19 + Tailwind v4 + TypeScript 6 · 검색 Orama · AI llms.txt·MCP 내장 · 라이선스 MIT · Node.js ≥ 22.12 · 문서 useblume.dev · 저자 Hayden Bleasel · 클론 소스 직접 분석)
목차
  1. 프로젝트 한 줄 요약
  2. 왜 주목받는가 — "제로 설정 + AI-네이티브"의 무게
  3. 기술 스택 전체 지도 — Astro 7·Bun 모노레포·최신 툴체인
  4. 아키텍처 심화 — 숨은 Astro 프로젝트를 생성해 구동한다
  5. 디렉토리 구조 해부
  6. 학습 포인트 — 여기서 훔쳐올 설계
  7. 시스템 / 실행 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한 줄 요약

"문서 사이트 하나 만들려고 또 프레임워크를 배우고 앱을 유지보수해야 해?" — 그 부담을 없앤 도구
한 문장으로

blume = 클론할 템플릿 없이 마크다운만 넣으면 도는, 제로 설정 문서 프레임워크 — Astro를 숨겨서 생성·구동하고, 원하면 eject로 넘겨준다

대부분의 문서 도구는 스타터 저장소를 클론하고, 그 프레임워크(라우팅·빌드·설정)를 배우고, 결과물 앱을 내가 계속 유지보수해야 한다. 콘텐츠 한 줄 고치려다 의존성 업그레이드·빌드 깨짐과 씨름하는 게 흔한 풍경이다.

blume은 그 층을 통째로 감춘다. npx blume initblume dev면 끝이고, 내 폴더엔 마크다운과 (선택적) 설정 파일 하나만 남는다. Astro·Tailwind·검색·라우팅은 blume이 .blume/에 몰래 만들어 돌리는 프로젝트 안에 있어, 나는 그 존재조차 몰라도 된다.

가장 작은 시작 예시가 이 도구의 성격을 압축한다. 클론할 저장소도, 배울 폴더 구조도, 설정 보일러플레이트도 없다:

# 1) 스캐폴드 — docs/index.mdx + blume.config.ts 하나
npx blume init

# 2) 핫 리로드 개발 서버 (Astro는 뒤에서 자동 생성)
blume dev

# 3) 정적 HTML + 로컬 검색 인덱스 빌드 → dist/
blume build

설정 파일조차 거의 비어 있어도 완전히 동작한다. 아래가 blume 설정의 전부일 수 있다 — 나머지는 전부 합리적 기본값이다:

// blume.config.ts — defineConfig는 타입 추론용 순수 헬퍼
import { defineConfig } from "blume";

export default defineConfig({
  title: "My Docs",
  theme: { accent: "teal" },
});
// defineConfig({}) 처럼 완전히 비워도 사이트가 뜬다 (제로 설정)
용어
문서 프레임워크 · SSG · MDX
문서 프레임워크는 마크다운 원고를 검색·내비게이션·테마가 붙은 웹사이트로 바꿔 주는 도구다(Docusaurus·Nextra 등). SSG(정적 사이트 생성기)는 빌드 시점에 미리 HTML을 다 만들어 두는 방식이라 서버 없이 빠르게 배포된다. MDX는 마크다운 안에 JSX 컴포넌트를 섞어 쓸 수 있는 확장 포맷으로, 문서 안에 인터랙티브 카드·탭·다이어그램을 넣게 해 준다. blume은 이 셋을 Astro 위에서 묶되, 그 복잡함을 사용자에게 숨긴다.

정리하면 blume의 정체는 "라이브러리"가 아니라 "코드 생성 CLI + Astro 런타임"의 하이브리드다. ① CLI(blume)가 설정과 콘텐츠를 읽어 페이지 그래프를 만들고, ② 그걸로 .blume/진짜 Astro 프로젝트를 생성astro dev/astro build를 구동하며, ③ 내가 만든 마크다운·오버라이드·테마를 그 안으로 주입한다. 문서의 "예쁨·빠름"은 Astro·Tailwind에서 오고, 이 레포의 진짜 가치는 그 모든 걸 감춰 "콘텐츠만 만지게" 만든 오케스트레이션 엔지니어링에 있다.

저자는 Hayden Bleasel(Kibo UI·Ultracite 등으로 알려진 OSS 저자)이며 MIT로 공개했다. "Free and open source, forever"를 내걸었고, 문서 사이트(useblume.dev)는 blume으로 만든 blume 문서 — 즉 스스로를 도그푸딩하는 구조다.

2왜 주목받는가 — "제로 설정 + AI-네이티브"의 무게

경쟁: Docusaurus · Nextra · Mintlify · Fumadocs · Starlight — 이들과 무엇이 다른가

문서 사이트를 세우려는 개발자에게 지금까지 선택지는 저마다 어딘가 무거웠다. 스타터를 클론해 앱을 떠안거나(Docusaurus·Nextra), 호스팅에 묶이거나(Mintlify), 특정 프레임워크에 종속됐다(Fumadocs=Next.js). blume은 그 무게들을 정확히 겨냥한다.

도구기반장점불편한 점
DocusaurusReact성숙·플러그인 풍부스타터 클론 → 앱을 내가 유지보수, 무거운 설정
NextraNext.jsNext 친화, 심플Next 앱 구조를 소유·이해해야 함
MintlifySaaS예쁨, AI 기능호스팅·요금 종속, 셀프호스팅 제약
FumadocsNext.js유연·현대적Next.js 프로젝트를 직접 구성
제로 설정 생성형
(blume)
Astro(숨김)클론 없음, AI 내장, 정적·빠름, eject 자유신생(v1.x), Astro 관례 일부 학습, 생태계 초기

차별점 ① — 클론할 스타터가 없다: "프레임워크가 곧 템플릿"

다른 도구는 git clone starter로 시작해 그 앱을 영원히 소유한다 — 의존성 업그레이드도, 빌드 설정도 내 책임이다. blume은 정반대다. 내 폴더엔 마크다운과 (선택) blume.config.ts만 있고, Astro 프로젝트는 blume이 매 실행마다 .blume/에 새로 만든다. 프레임워크가 곧 스타터라, "업데이트=blume 버전만 올리기"가 된다.

비유

집을 짓는 두 방법. 기존 문서 도구는 모델하우스 설계도를 복사해 내 땅에 직접 짓고, 그때부터 배관·전기·보수를 평생 책임지는 것과 같다(스타터 클론 → 앱 소유). blume은 호텔에 체크인하는 것에 가깝다 — 방(콘텐츠)만 꾸미면 되고, 건물 유지보수(Astro·빌드·라우팅)는 호텔이 한다. 그러다 정말 내 집이 필요하면 blume eject로 그 건물을 통째로 넘겨받아 소유주가 된다.

차별점 ② — AI-네이티브를 1급 기능으로 내장

blume은 "AI-ready"를 표방하는데, 이는 마케팅 문구가 아니라 코드로 들어 있다. 빌드 시 llms.txt·llms-full.txt를 생성하고, 모든 페이지에 원본 마크다운을 .md URL로 제공하며, "Copy as Markdown"·"Open in chat" 액션을 붙인다. 나아가 호스팅 MCP 서버까지 내장해, 코딩 에이전트가 문서를 직접 검색·조회하게 만든다.

용어
llms.txt · MCP · 에이전트 스킬
llms.txt는 "이 사이트를 LLM이 읽기 쉽게 정리한 색인" 표준으로, AI가 문서 전체를 빠르게 파악하게 돕는다. MCP(Model Context Protocol)는 AI 도구가 외부 데이터·기능에 붙는 표준 규약으로, blume은 search_docs·get_page 같은 읽기 전용 도구를 MCP 서버로 노출한다. 에이전트 스킬(skills/)은 코딩 에이전트에게 "blume 문서를 스캐폴딩·작성·유지보수하는 법"을 가르치는 지침 묶음이다. 즉 사람과 AI 둘 다를 독자로 상정한 최초 세대 문서 도구다.

차별점 ③ — 정적 우선(빠름), 서버 기능은 opt-in

기본 테마는 클라이언트 프레임워크 JS를 배포하지 않는다 — Astro의 "제로 JS 기본"을 따라 Core Web Vitals가 좋다. Ask AI·MCP 같은 요청 시간 기능이 필요할 때만 서버 출력으로 전환한다. 심지어 prepare.ts에 하드 게이트가 있어, 서버 전용 기능을 정적 빌드에 넣으면 BLUME_SERVER_FEATURE_REQUIRED 에러로 멈춰 "느려지는 실수"를 코드로 막는다.

그래서 트렌딩
"문서 도구의 피로"를 제로 설정 + AI로 정면 돌파

개발자들은 문서 스타터를 클론·설정·유지보수하는 반복 노동에 지쳐 있었다. blume은 그 층을 감춰서 없애고, 여기에 2026년의 화두인 "AI가 읽는 문서"(llms.txt·MCP·스킬)를 기본 탑재했다. Astro 7·React 19·Tailwind v4 같은 최신 스택 위에서 도그푸딩(스스로의 문서를 blume으로)까지 보여 주니, "장난감이 아니라 실전용"이라는 인상을 준다. 저자의 기존 명성(Kibo UI·Ultracite)도 초기 확산을 도왔다.

주의 · 오해 방지
"blume이 Astro를 대체한다"가 아니다 — 감싸고, 필요하면 돌려준다

blume은 Astro를 숨겨서 오케스트레이션할 뿐, 새 렌더링 엔진을 만든 게 아니다. 렌더링·빌드는 Astro가 한다. 또한 신생 프로젝트(v1.x)라 생태계·플러그인은 성숙한 Docusaurus에 못 미치고, 깊은 커스터마이징은 결국 Astro 지식을 요구한다. "제로 설정"은 시작이 제로라는 뜻이지, 고급 요구까지 마법으로 해결한다는 뜻은 아니다. 다행히 blume eject가 그 탈출구를 보장한다.

3기술 스택 전체 지도 — Astro 7·Bun 모노레포·최신 툴체인

렌더링 코어(Astro) · 콘텐츠/AI/검색 엔진 · 언어·빌드 툴링(Bun·Turbo·Oxlint·tsgo)

blume은 "프론트/백엔드"로 나뉘는 웹 앱이 아니라, 배포되는 npm 패키지 하나(blume)가 사용자 기기에서 Astro 프로젝트를 생성·구동하는 도구다. 스택을 이해하려면 세 묶음으로 보면 빠르다: 렌더링을 담당하는 Astro 코어, 콘텐츠·검색·AI를 처리하는 기능 엔진, 그리고 이 패키지를 개발·빌드하는 툴체인.

용어
모노레포 · Bun workspaces · Turborepo
모노레포는 여러 패키지를 한 저장소에 모아 두는 방식이다. blume 저장소는 blume-monorepo로, 배포용 packages/blume, 자체 문서 apps/docs, 프로모 영상 packages/video를 함께 둔다. Bun은 초고속 JS 런타임 겸 패키지 매니저로, workspaces로 이들을 묶고 bun@1.3.14로 버전을 고정했다. Turborepo빌드·테스트를 캐시·병렬화하는 태스크 러너다(turbo.json).

① 렌더링 코어 — Astro 7 + React 19 + Tailwind v4

blume이 생성하는 숨은 프로젝트의 심장은 Astro다. 정적·서버 렌더링을 모두 지원하고, 인터랙티브 조각만 골라 하이드레이션하는 "아일랜드" 모델을 쓴다.

구성요소버전역할
astro^7.0.2렌더링 엔진 — 정적/서버 출력, 라우팅, 빌드
@astrojs/mdx · reactMDX 처리 + React 아일랜드 통합
@astrojs/node · vercel서버 어댑터(요청 시간 기능용). Netlify·Cloudflare는 옵션
react / react-dom^19.0.0인터랙티브 컴포넌트. React Compiler 최적화 적용
tailwindcss (+ @tailwindcss/vite)^4스타일링 — Tailwind v4, Vite 플러그인 방식
@tailwindcss/typography산문(prose) 타이포그래피 프리셋

② 기능 엔진 — 콘텐츠·검색·AI·구문 하이라이팅

여기가 blume의 "부가가치"가 몰린 층이다. 마크다운을 읽고, 검색 인덱스를 만들고, AI가 읽을 형태로 변환하고, 코드를 예쁘게 칠한다.

영역패키지역할
설정 검증zod ^3.24 + jiti ^2.4blume.config.ts를 런타임 로드(jiti) 후 스키마 검증(Zod)
콘텐츠 파싱gray-matter · marked프론트매터 분리 · 에이전트용 마크다운 다운레벨
검색(기본)@orama/orama ^3.1로컬 검색 엔진 — 호스팅 서비스 불필요
검색(옵션)pagefind · algolia · typesense …설정 한 줄로 백엔드 교체(peerDeps, 전부 optional)
AIai ^5.0 (Vercel AI SDK) · @modelcontextprotocol/sdkAsk AI 어시스턴트 · MCP 서버
구문 하이라이팅shiki ^4.2 + twoslashShiki 하이라이팅 + Twoslash(TS 타입 인라인 표시)
수식·다이어그램katex · mermaid ^11KaTeX 수식 · Mermaid 다이어그램
OG 이미지takumi-js · satteri빌드타임 OG 이미지 렌더링
API 레퍼런스@scalar/astro · openapi-parserOpenAPI/AsyncAPI를 인터랙티브 레퍼런스로
내보내기epub-gen-memory · dompurify클라이언트 사이드 EPUB/PDF 내보내기 · HTML 새니타이즈
용어
peerDependencies(optional) · Orama
Orama는 순수 JS로 짠 전문 검색 엔진으로, 빌드 시 인덱스를 만들어 브라우저에서 검색한다 — Algolia 같은 외부 서비스 없이 로컬에서 도는 게 강점이다. blume은 Algolia·Typesense·Notion·Sanity 같은 무거운 백엔드를 optional peerDependencies로 둔다. peerDependency는 "쓸 사람만 직접 설치"하는 의존성이라, 기본 사용자는 필요 없는 SDK를 받지 않는다. 알고리아를 켠 사람만 algoliasearch를 깐다.

③ 툴체인 — TS 6(tsgo)·Oxlint/Oxfmt·Bun test·Changesets

blume 저장소 자체를 개발하는 도구들인데, "2026년 최신 프론트엔드 툴체인의 축소판"이라 그 자체로 볼거리다.

도구버전역할
TypeScript^6.0.3타입 언어. 타입체크는 네이티브 포트 tsgo(@typescript/native-preview)
Ultracite → Oxlint/Oxfmtoxlint ^1.73 · oxfmt ^0.58Rust 기반 초고속 린터/포매터. ESLint·Prettier 대체
Turborepo^2.3태스크 러너(build/dev/test/typecheck 캐시·병렬)
Bun test내장Jest 호환 테스트 러너. 테스트 파일 97개
Changesets버전·릴리스 관리(.changeset/, main 머지 시 릴리스 PR)
husky^9.1git 훅(.husky/) — 커밋 전 린트
스택이 말하는 것
"빠른 도구는 전부 채택" — 속도에 집착한 현대 스택

Bun(런타임)·Turbo(빌드 캐시)·Oxlint/Oxfmt(Rust 린터)·tsgo(네이티브 타입체크)·Tailwind v4(Rust 엔진)까지, blume은 병목마다 최신 고속 도구를 골랐다. React 19 + React Compiler로 런타임 최적화도 자동화했다. "문서 도구"라는 겉모습과 달리 내부는 2026년 프론트엔드 성능 트렌드를 총집합한 학습 표본이다. 규모도 상당해 packages/blume/srcTS 244개 + Astro 69개 ≈ 4.5만 줄이다.

4아키텍처 심화 — 숨은 Astro 프로젝트를 생성해 구동한다

CLI가 콘텐츠를 그래프로 스캔 → .blume/에 Astro 프로젝트 생성 → dev/build 구동 → 원하면 eject

이 레포에서 가장 배울 게 많은 부분이다. "문서 도구를 어떻게 만드느냐"에는 흔히 두 길이 있다 — 라이브러리로 컴포넌트를 export하거나(Fumadocs), 스타터 앱을 배포하거나(Docusaurus). blume은 제3의 길을 간다: 코드를 생성하는 CLI가 되어, 실행 때마다 완전한 Astro 앱을 만들어 돌린다.

전체 데이터 흐름

blume.config.ts + docs/*.md(x) + meta.ts + theme.css │ ▼ ┌─────────── CLI (citty) ───────────┐ │ loadConfig → Zod 검증(schema.ts) │ src/cli/index.ts └───────────────┬───────────────────┘ ▼ scanProject() src/core/project-graph.ts ┌───────────────────────────────────────────┐ │ 1. resolveSources() filesystem / remote / │ │ github-releases / notion / sanity … │ │ 2. 각 source.load() 병렬 실행 │ │ 3. normalizeEntry() 라우트 매핑 통일 │ │ 4. buildContentGraph() 페이지 그래프 │ │ 5. buildManifest() 라우트 매니페스트 │ │ (+ git 최종수정일, i18n, 진단) │ └───────────────────┬───────────────────────┘ ▼ BlumeProject generateRuntime() src/astro/generate.ts (64KB) ┌───────────────────────────────────────────┐ │ .blume/ 에 Astro 프로젝트 물리 생성: │ │ · astro.config.mjs · package.json · tsconfig│ │ · blume:data 가상 모듈(config·nav·routes) │ │ · catch-all [...slug].astro │ │ · search 인덱스 · llms.txt · OG 엔드포인트 │ │ · RSS / sitemap / robots · MCP 엔드포인트 │ └───────────────────┬───────────────────────┘ ▼ astro dev / astro build → dist/(정적 HTML) 또는 서버 출력 │ ▼ (완전한 제어가 필요하면) blume eject → 내가 소유하는 독립 Astro 앱
용어
catch-all 라우트 · 가상 모듈(virtual module)
catch-all 라우트([...slug].astro)는 "어떤 경로가 들어와도 이 한 파일이 처리"하는 만능 페이지다. blume은 페이지마다 파일을 만들지 않고, 이 한 파일이 매니페스트를 보고 알맞은 콘텐츠를 렌더한다. 가상 모듈은 디스크에 실제 파일이 없어도 import ... from "blume:data"처럼 불러올 수 있는 빌드 타임 생성 모듈이다. blume은 설정·내비게이션·라우트 데이터를 이 가상 모듈로 주입해, 생성 코드와 사용자 코드를 깔끔히 잇는다.

CLI 진입점 — citty 서브커맨드

CLI는 UnJS의 citty로 짜였다. 11개 서브커맨드가 한 곳에 등록되고, 원격 소스용 토큰(예: GITHUB_TOKEN)을 .env에서 로드한다.

// src/cli/index.ts — 모든 서브커맨드의 등록소
const main = defineCommand({
  meta: { name: "blume", version: getBlumeVersion(),
          description: "Markdown-first documentation powered by Astro and Vite." },
  subCommands: { add, audit, build, check, dev, doctor,
                 eject, init, preview, sync, validate },
});
loadEnvFiles(process.cwd());   // 원격 소스 토큰 로드
runMain(main);

핵심 설계 패턴 4가지

패턴 ① — 숨은 런타임 생성(generated runtime)을 캐시처럼 취급

.blume/는 사용자가 소유하는 코드가 아니라 매 실행마다 재생성되는 산출물이다. 그래서 dev 커맨드가 흥미롭다 — 파일을 watch하다가, "페이지가 추가/삭제/리네임된 구조적 변경"과 "본문만 고친 편집"을 구분한다. 전자는 서버를 재시작하고, 후자는 Vite HMR 핫패스로 넘긴다. 구분의 열쇠가 route signature(정렬된 경로+엔트리ID 문자열)다.

// src/cli/commands/dev.ts — 구조 변경 감지용 서명
const routeSignature = (routes) =>
  routes.map((route) => `${route.path} ${route.entryId}`)
        .toSorted().join("\n");

// 서명이 바뀌면(=구조 변경) server.stop() → generateRuntime() → 새 서버,
// 아니면 그냥 재생성만 하고 Vite HMR에 맡김.

여기에 .blume/dev.lock 원자적 잠금(dev-lock.ts)을 두어 두 개의 dev 서버가 같은 디렉토리를 동시에 훼손하는 사고를 막는다. watch 이벤트가 폭주해도 single-flight로 재생성을 합쳐(coalesce) 처리한다.

패턴 ② — 소스 추상화(ContentSource 계약)

모든 콘텐츠 오리진이 같은 인터페이스(load()/validate()/watch())를 구현한다. 그래서 로컬 파일 + 원격 MDX + GitHub Releases + Notion + Sanity를 한 사이트에 섞어 쓸 수 있다. 레퍼런스 구현이 파일시스템 소스다.

// src/core/sources/filesystem.ts — 콘텐츠 소스 레퍼런스
const files = await glob(options.include, {        // tinyglobby
  absolute: true, cwd: contentRoot, onlyFiles: true,
  ignore: [...options.exclude, ...baselineScanIgnore()], // node_modules/.blume 제외
});
// 각 파일: gray-matter로 프론트매터/본문 분리
const parsed = matter(source);
return { body: { format, text: parsed.content },
         data: parsed.data, raw: source, ref, sourcePath };

패턴 ③ — 설정은 없어도 동작(제로 설정), 검증은 Zod로

jiti.ts 설정을 런타임 import하고 blumeConfigSchema.safeParse()로 검증한다. 설정 파일이 없어도 스키마 기본값으로 완전 동작한다. Zod 에러는 한 번에 전부 보여 줘 "고치고-재실행-또 실패" 루프를 막는다.

// src/core/config.ts — 없으면 빈 객체로도 파싱 성공
const parsed = blumeConfigSchema.safeParse(raw ?? {});
// OG 이미지는 절대 URL이 필요 → site URL을 알면 자동 on, 모르면 off
const ogEnabled = config.seo.og.enabled ?? Boolean(site);

패턴 ④ — eject: 일방향 승격

blume eject.blume/ 생성물을 사용자 소유의 독립 Astro 앱으로 변환한다(astro.config.mjs·src/·package.json 스크립트 재작성). 그 뒤로도 blume 패키지는 계속 import할 수 있다. "제로 설정으로 시작하되, 천장에 부딪히면 완전한 제어로 탈출"하는 비상구를 설계에 내장한 것이다.

설계 포인트
진단(Diagnostics) 우선 — 콘텐츠 문제에 함부로 throw하지 않는다

깨진 링크·누락 메타 같은 콘텐츠 문제에서 blume은 예외를 던지는 대신 진단을 수집해 호출자가 엄격도(strictness)를 정하게 한다. 빌드는 draft: true 페이지를 자동 제외하고, dev에서는 초안도 보여 준다. 덕분에 "한 곳이 틀렸다고 전체 빌드가 죽는" 좌절을 줄이고, blume audit·blume doctor로 문제를 모아서 리포트한다.

5디렉토리 구조 해부

모노레포(packages·apps·skills) + 핵심 패키지 packages/blume/src의 12개 하위 모듈

모노레포 최상위

blume/ # 모노레포 루트 (blume-monorepo, private) ├── package.json # workspaces: packages/*, apps/* ├── turbo.json # Turborepo 태스크(build/dev/test/typecheck) ├── bun.lock # Bun 잠금파일(357KB) ├── tsconfig.base.json # 공유 TS 설정(strict, moduleResolution: Bundler) ├── oxlint.config.ts / oxfmt.config.ts # Ultracite 린트/포맷 ├── .changeset/ .husky/ patches/ ├── packages/ │ ├── blume/ # ★ 배포되는 npm 패키지(핵심) │ └── video/ # Remotion 프로모 영상(빌드에서 --filter=!video 제외) ├── apps/ │ └── docs/ # blume으로 만든 blume 문서(도그푸딩) └── skills/ # 에이전트 스킬 3종(아래) ├── blume/ # 문서 사이트 스캐폴딩/작성 ├── blume-migrate/ # 타 도구에서 이관 └── blume-update-docs/ # 문서 유지보수

핵심 패키지 packages/blume/

packages/blume/ ├── package.json # "blume" v1.1.3, bin: blume → bin/blume.mjs ├── bin/blume.mjs # CLI 런처(dist 우선, 없으면 src TS 폴백) ├── test/ # 97개 테스트(bun test) └── src/ ├── index.ts # 공개 API: defineConfig · defineMeta · defineComponents ├── cli/ # index.ts + commands/(11개) + init/ + prepare.ts + dev-lock.ts ├── core/ # ★ 두뇌: config · schema(49KB!) · project-graph · navigation · sources/ ├── astro/ # ★ 숨은 Astro 생성기: generate.ts(64KB) · templates.ts(80KB) ├── components/ # content/(43개) + layout/(내비·검색·TOC) + openapi/ + islands/ ├── search/ # providers · orama-index · sync/(algolia·typesense·orama-cloud) ├── ai/ # llms.ts · ask.ts · markdown.ts · mcp/(server·tools·data) ├── og/ # Takumi OG 이미지 렌더 ├── openapi/ # OpenAPI/AsyncAPI 파싱·렌더(Scalar) ├── markdown/ # remark/rehype 플러그인(twoslash·mermaid·math·anchors) ├── deploy/ # sitemap · rss · robots · redirects · headers ├── audit/ # blume audit — 링크·SEO·이미지·i18n 검사(checks/ 13종) ├── registry/ # blume add(소스 컴포넌트 설치) + eject 로직 ├── theme/ # palette · fonts · icons · entry(Tailwind) └── runtime/ # 사용자 .astro 페이지용 헬퍼(getBlumeCollection)

구조가 말하는 핵심 세 가지. 첫째, 사용자가 만지는 건 저장소 밖의 docs/·blume.config.ts이고, 이 방대한 src/는 전부 감춰진 엔진이다. 둘째, core/(스캔·그래프)와 astro/(코드 생성)가 명확히 갈려 있어, "무엇을 렌더할지 정하는 층"과 "실제 Astro 코드를 찍어내는 층"이 분리된다. 셋째, ai/·audit/·openapi/가 독립 모듈로 존재한다는 건 AI·품질·API 문서를 곁다리가 아닌 1급 기능으로 본다는 신호다.

핵심 파일/디렉토리왜 중요한가
src/cli/index.ts + commands/11개 서브커맨드의 진입점. dev.ts는 route signature HMR의 백미
src/core/schema.ts (1321줄)전체 설정의 단일 진실원 — Zod로 모든 옵션·기본값 정의
src/core/project-graph.ts소스 병렬 로드 → 정규화 → 콘텐츠 그래프 → 매니페스트
src/astro/generate.ts (64KB).blume/ Astro 프로젝트를 물리적으로 생성하는 심장
src/core/sources/filesystem.tsContentSource 계약의 레퍼런스 구현(원격·CMS 확장의 본보기)
src/ai/mcp/tools.ts코딩 에이전트용 읽기 전용 도구 4종(AI-ready의 핵심)
apps/docs/blume.config.ts실제 설정 예시 — blume이 자신을 어떻게 설정하는지
함정 · 착시
"내 프로젝트에 이 폴더들이 생기나?" — 아니다

이 방대한 src/ 트리는 blume 패키지 내부다. 내가 npx blume init하면 내 폴더엔 docs/blume.config.ts만 생긴다. 렌더링을 위해 .blume/가 잠깐 생기지만 그건 git에 커밋하지 않는 산출물(.gitignore 대상)이다. "blume을 쓴다 ≠ 이 코드를 관리한다"를 분명히 해야 길을 잃지 않는다. 이 코드를 읽는 건 기여자·학습자의 관점이다.

6학습 포인트 — 여기서 훔쳐올 설계

코드 생성형 프레임워크 · 소스 추상화 · dev 서버 정합성 · AI-네이티브 문서화

배울 것 ① — "코드 생성형 프레임워크" 패턴

이 레포 최고의 학습 자산. 라이브러리로 API를 노출하는 대신 완전한 프로젝트를 생성해 구동하고, 원하면 eject로 넘겨주는 하이브리드 설계는, "추상화의 편함"과 "탈출의 자유"를 동시에 주는 드문 예다. create-next-app(1회 생성 후 방치)과 라이브러리(계속 감춤)의 중간 지점을, 매 실행 재생성 + 일방향 eject로 절묘하게 잡았다.

실습 아이디어
"설정 파일 → 프로젝트 폴더를 찍어내는" 최소 생성기

my.config.json을 읽어 .mytool/index.html·package.json을 생성하고 Vite dev 서버를 띄우는 최소 CLI를 만들어 보라. 설정을 바꾸면 폴더를 재생성하고, eject 커맨드로 그 폴더를 프로젝트 루트로 승격해 보면, blume의 generateRuntime()·eject가 왜 그렇게 설계됐는지 몸으로 이해된다.

배울 것 ② — 인터페이스로 데이터 소스를 갈아 끼우기

ContentSource라는 하나의 계약(load/validate/watch) 아래 filesystem·remote·github-releases·notion·sanity가 갈려 있다. 상위 스캐너는 소스가 로컬인지 CMS인지 전혀 모른다. "다양한 백엔드를 상위 코드 모르게 통일"하는 이 플러그형 구조는, 검색 provider(orama·algolia·typesense…)에도 똑같이 적용돼 있다 — 확장 가능한 아키텍처의 교과서다.

// src/search/providers.ts — provider를 kind로 분류해 통합 방식 결정
export const SEARCH_PROVIDERS = {
  orama:       { kind: "static", requiresServer: false, syncs: false }, // 기본값
  pagefind:    { kind: "pagefind", ... },   // 빌드 후 HTML에서 인덱스
  algolia:     { kind: "hosted", syncs: true },  // 빌드타임 업로드
  typesense:   { kind: "hosted", syncs: true },
  mixedbread:  { kind: "server", requiresServer: true }, // /api/search 프록시
  none:        { kind: "none" },
};

배울 것 ③ — dev 서버의 "정합성 엔지니어링"

route signature diff(구조 변경 vs 본문 편집 구분), 원자적 파일 락(중복 서버 방지), coalesced runner(watch 폭주를 single-flight로 합침) — 이 셋은 "파일을 watch해 재생성"하는 모든 도구가 부딪히는 실전 문제의 모범 해법이다. 빌드 도구·코드 생성기·핫 리로드를 만들 사람에게 그대로 참고서가 된다.

배울 것 ④ — AI-네이티브 문서화의 구체적 구현

"AI-ready"를 코드로 어떻게 만드는지 볼 수 있다: llms.txt 생성, 페이지별 .md 원본 노출, MCP 서버로 에이전트가 문서를 도구로 조회. MCP 도구는 4개뿐이지만 설계가 깔끔하다 — 전부 읽기 전용이라 안전하고, 검색·단일 페이지·목록·내비를 덮는다.

// src/ai/mcp/tools.ts — 코딩 에이전트에 노출하는 읽기 전용 도구 4종
export const MCP_TOOLS = [
  { name: "search_docs",    title: "Search documentation" }, // 전문 검색
  { name: "get_page",       title: "Get page Markdown" },   // 에이전트 최적 MD
  { name: "list_pages",     title: "List pages" },         // 전체 열거
  { name: "get_navigation", title: "Get navigation" },     // 내비 트리
];

배울 것 ⑤ — 2026년 프론트엔드 툴체인의 집약체

Astro 7 + React 19(+Compiler) + Tailwind v4 + TypeScript 6(tsgo) + Oxlint/Oxfmt(Rust) + Bun test + Zod 스키마 + Changesets 릴리스. 이 하나의 저장소를 읽는 것만으로 현대 스택의 조립법을 통째로 훑을 수 있다. 특히 "런타임 TS 설정 로드(jiti) + Zod 검증"은 설정 주도 도구를 만들 때 바로 쓰는 패턴이다.

용어
도그푸딩(dogfooding) · React Compiler
도그푸딩은 "자기 제품을 자기가 쓴다"는 뜻이다. blume 문서(useblume.dev)가 blume으로 만들어져 있어, 문서가 곧 가장 큰 사용 예제이자 회귀 테스트가 된다. React Compiler는 React 19대와 함께 온 빌드타임 최적화기로, 개발자가 useMemo·useCallback을 수동으로 붙이지 않아도 자동으로 메모이제이션해 준다. blume은 babel-plugin-react-compiler로 이를 켜 둔다.

7시스템 / 실행 요구사항

사용자는 Node 22.12+ 하나면 끝 · 패키지 매니저 자유 · 서버 기능만 어댑터 필요
용도요구사항
설치·실행(사용자)Node.js ≥ 22.12.0(engines.node). 콘텐츠 폴더에 .md/.mdx 1개만 있으면 됨 — Astro·Tailwind 직접 설정 불필요
패키지 매니저Bun · pnpm · npm · yarn 모두 지원. 저장소 자체는 bun@1.3.14 고정
정적 배포blume builddist/ 정적 HTML. 아무 정적 호스트(Vercel·Netlify·Cloudflare Pages·GitHub Pages·S3+CDN)에
서버 기능(옵션)Ask AI·MCP 등 요청 시간 기능은 어댑터 필요: Vercel·Netlify·Node·Cloudflare. Vercel·Netlify·CF Pages에선 어댑터·site URL 자동 감지
저장소 기여(개발)Bun(모노레포). bun installturbo로 build/dev/test. 타입체크 tsgo, 린트/포맷 Ultracite(oxlint/oxfmt)
검색기본 Orama는 추가 설치·서비스 불필요(로컬). Algolia·Typesense 등은 해당 SDK를 직접 설치(optional peerDep)

설정 옵션이 이 도구의 "손잡이"를 보여 준다. defineConfig({...}) 안에서 content.sources여러 콘텐츠 소스를 혼합하고, navigation.tabs로 상단 탭을, theme.accent로 색을, deployment.adapter로 배포 타깃을, search.provider로 검색 백엔드를, export: true로 PDF/EPUB 내보내기를 켠다. 폴더별 meta.ts(defineMeta)로 사이드바 그룹을, theme.css로 Tailwind v4 토큰을 세밀 제어한다.

// apps/docs/blume.config.ts — blume이 자신을 설정하는 실제 예시(축약)
export default defineConfig({
  title: "Blume",
  theme: { accent: "teal" },
  content: { root: "content", sources: [
    { type: "filesystem", root: "content" },
    { type: "github-releases", owner: "haydenbleasel", repo: "blume", prefix: "changelog" },
  ] },
  navigation: { tabs: [ { label: "Docs", path: "/docs" },
                        { label: "Changelog", path: "/changelog" } ] },
  deployment: { adapter: "vercel" },
  export: true, lastModified: true,
});
주의
"제로 설정"이라도 고급 기능엔 대가가 있다

정적 배포만 쓸 거면 요구사항은 Node 하나로 끝이다. 그러나 Ask AI·MCP 같은 서버 기능을 켜는 순간 어댑터·서버 호스팅·(AI의 경우) API 키가 필요해진다. 또 신생(v1.x)이라 API·기본값이 바뀔 수 있으니, 프로덕션 도입 전 blume 버전을 고정하고 useblume.dev의 최신 문서를 확인하는 게 안전하다. 깊은 커스터마이징은 결국 Astro 지식을 요구한다는 점도 계획에 반영하자.

8직접 해볼 수 있는 실습 과제

첫 문서 배포부터 소스 혼합·MCP 연동, 나만의 생성기까지
과제 1난이도 ★☆☆☆☆

5분 만에 문서 사이트 띄워 배포하기

npx blume init(Node 22.12+) 후 docs/에 마크다운 두어 개를 넣고 blume dev로 확인한다. blume builddist/를 만들어 GitHub Pages·Netlify drop에 올려 본다. 내 폴더에 실제로 뭐가 생겼는지(docs/·blume.config.ts·잠깐 생기는 .blume/) 눈으로 확인하는 게 핵심.

과제 2난이도 ★★☆☆☆

MDX 컴포넌트로 살아있는 문서 만들기

import 없이 쓰는 내장 컴포넌트(Callout·Card·Tabs·Steps·CodeGroup·FileTree)를 마크다운에 섞어 본다. Mermaid 다이어그램과 Math 수식, Twoslash로 TS 타입이 인라인 표시되는 코드 블록까지 넣어, "왜 그냥 마크다운이 아니라 MDX인가"를 체감한다.

과제 3난이도 ★★★☆☆

콘텐츠 소스 혼합 + GitHub Releases를 changelog로

content.sourcesfilesystemgithub-releases를 함께 넣어, 로컬 문서 + GitHub 릴리스 노트를 자동 changelog로 합친 사이트를 만든다. GITHUB_TOKEN.env에 넣고 blume sync로 원격을 재-페치해, ContentSource 추상화가 실전에서 어떻게 작동하는지 관찰한다.

과제 4난이도 ★★★★☆

AI-네이티브 기능 켜고 MCP로 에이전트에 물려 보기

빌드 후 생성된 /llms.txt·페이지별 .md URL을 확인하고, 서버 어댑터로 배포해 MCP 서버를 켠다. 코딩 에이전트(Claude 등)에 이 MCP를 연결해 search_docs·get_page문서를 도구처럼 조회시켜, "사람+AI 둘 다를 독자로" 삼는 설계를 직접 써 본다.

과제 5난이도 ★★★★★

eject 해부 → 나만의 "생성 후 eject" 미니 도구 만들기

blume eject를 실행해 .blume/독립 Astro 앱으로 바뀌는 과정을 diff로 뜯어본다. 그다음, 설정 파일을 읽어 임시 폴더에 프로젝트를 생성·구동하고 eject로 승격하는 최소 CLI를 citty로 직접 만든다. route signature 기반 재생성·원자적 락까지 흉내 내면 blume 핵심 엔지니어링을 스스로 재현하는 캡스톤이 된다.

9관련 기술 심화 학습 로드맵

4주 코스 — Astro/MDX → 설정 주도 CLI → 코드 생성·HMR → AI-네이티브 문서화
주차주제 · 목표핵심 자료
1주차 Astro + MDX + Tailwind v4 기초. 아일랜드 하이드레이션, content collections, 정적 vs 서버 출력, 어댑터 개념 Astro 공식 문서 · apps/docs/ · src/components/content/
2주차 설정 주도 CLI 만들기. citty 서브커맨드, jiti로 .ts 설정 로드, Zod 스키마 검증·기본값·에러 취합 src/cli/index.ts · src/core/config.ts · schema.ts · Zod 문서
3주차 코드 생성 & 핫 리로드. 가상 모듈, catch-all 라우트, route signature diff, 원자적 락, coalesced 재생성, eject src/astro/generate.ts · src/cli/commands/dev.ts · dev-lock.ts
4주차 AI-네이티브 & 소스 추상화. llms.txt 생성, MCP 서버·도구, ContentSource 계약, 검색 provider 플러그인화 src/ai/ · src/core/sources/ · src/search/providers.ts · MCP 문서
곁들이면 좋은 배경
"언제 생성형이고 언제 라이브러리·SaaS인가"까지 알아야 진짜 이해

blume식 생성형 프레임워크는 시작이 쉽지만 "숨은 마법"이라는 부담이 있다. 완전한 제어·기존 앱 통합이 목표면 라이브러리형(Fumadocs)이, 관리·협업·호스팅까지 위임하고 싶으면 SaaS(Mintlify)가 낫다. blume이 택한 "제로 설정 + 정적 우선 + eject 비상구" 자리를 세 대안과 비교해 보면, 도구 선택이 곧 제어권과 편의의 트레이드오프임이 선명해진다.

10핵심 키워드 사전

이 저장소를 읽을 때 반복해서 만나는 말들
키워드
생성형 프레임워크 · "framework is the template"
스타터를 클론하지 않고, CLI가 실행 때마다 완전한 프로젝트(.blume/ Astro 앱)를 생성해 구동하는 방식. 프레임워크 자체가 스타터라 업데이트가 "버전 올리기"로 끝난다. blume의 근본 철학.
키워드
eject
생성된 .blume/를 사용자 소유의 독립 Astro 앱으로 승격하는 일방향 커맨드. "제로 설정으로 시작하되 천장에 부딪히면 완전한 제어로 탈출"하는 비상구. create-react-app의 eject와 같은 개념.
키워드
Astro · 아일랜드 아키텍처
blume이 숨겨서 쓰는 렌더링 엔진. 기본은 JS 없는 정적 HTML을 내보내고, 인터랙티브가 필요한 조각(아일랜드)만 골라 하이드레이션한다. 그래서 문서 사이트가 빠르다.
키워드
MDX · 무-import 컴포넌트
마크다운 + JSX 컴포넌트. blume은 Callout·Card·Tabs·Steps43개를 import 없이 바로 쓰게 제공한다. AutoTypeTable은 TS 타입에서 표를 자동 생성하는 등 문서 특화 기능이 많다.
키워드
ContentSource · 소스 혼합
load()/validate()/watch()를 구현하는 콘텐츠 오리진 계약. filesystem·remote·github-releases·notion·sanity가 같은 인터페이스라 한 사이트에 섞어 쓴다. 확장 가능 아키텍처의 표본.
키워드
llms.txt · MCP
llms.txt는 사이트를 LLM이 읽기 쉽게 정리한 색인 표준. MCP는 AI 도구가 외부 기능에 붙는 규약으로, blume은 search_docs·get_page 등 읽기 전용 도구를 MCP 서버로 노출해 에이전트가 문서를 조회하게 한다.
키워드
Orama · 검색 provider
Orama는 blume 기본 검색 엔진으로, 외부 서비스 없이 로컬에서 도는 전문 검색이다. 필요하면 Pagefind·Algolia·Typesense·Orama Cloud·Mixedbread로 설정 한 줄에 교체(optional peerDep).
키워드
Zod 스키마 · jiti
Zod는 런타임 타입 검증 라이브러리로, schema.ts(1321줄)가 blume 설정의 단일 진실원이다. jiti.ts 설정 파일을 빌드 없이 즉시 import하게 해 주는 로더. 둘이 짝을 이뤄 "타입 안전한 설정 파일"을 만든다.
키워드
Ultracite · Oxlint/Oxfmt · tsgo
Ultracite는 린트/포맷 통합 래퍼로, 내부는 Rust 기반 초고속 Oxlint(린터)+Oxfmt(포매터)다. tsgo는 TypeScript의 네이티브 포트로 타입체크를 빠르게 한다. blume 툴체인의 "속도 집착"을 보여 주는 삼총사.
키워드
가상 모듈 · catch-all 라우트
가상 모듈은 디스크 파일 없이 import ... from "blume:data"로 불러오는 빌드타임 생성 모듈(설정·내비·라우트 주입). catch-all([...slug].astro)은 모든 경로를 처리하는 만능 페이지로, 페이지마다 파일을 만들지 않게 한다.

11참고 링크

원본과 배경 기술을 직접 확인하고 싶다면

저장소 · 문서

핵심 배경 기술

도구 · 생태계