REPO DEEP DIVE · 2026-07-29 · DYAD-SH/DYAD · 내 컴퓨터에서 도는 오픈소스 AI 앱 빌더

dyad-sh/dyad 딥다이브
"Lovable를 내 노트북 안에" 넣은 로컬 AI 코딩 에이전트

Dyad는 Lovable·v0·bolt.new 같은 "말로 앱 만들기" 서비스를, 클라우드가 아니라 내 컴퓨터에서 통째로 돌리는 Electron 데스크탑 앱이다. 사용자가 채팅으로 요구사항을 적으면 LLM이 <dyad-write> 같은 전용 태그로 코드를 통째로 뱉고, Dyad는 그 태그를 그 자리에서 파싱해 진짜 로컬 파일로 써넣고 git 커밋까지 자동으로 남긴다.

가장 중요한 정체성은 "코드와 프로젝트 폴더가 100% 내 디스크에 있다"는 것이다. AI 모델은 OpenAI·Anthropic·Google 등 원하는 걸 자기 API 키(BYOK)로 붙이거나 Ollama/LM Studio로 완전히 로컬 모델만 써도 되고, Supabase·Vercel·Neon·GitHub 연동은 있으면 편한 옵션일 뿐 필수가 아니다.

(저장소 dyad-sh/dyad · 제작 Will Chen 외 다수 · 버전 1.9.0(package.json 기준, 진실원) · 라이선스 Apache 2.0 + src/pro/FSL-1.1-ALv2(저작권자 Dyad Tech, Inc.) · Electron 40.0.0 + React 19.2.4 + TypeScript · 소스 파일 약 1,700개, 유닛테스트 475개 + Playwright E2E 스펙 127개 · 최신 커밋 2026-07-28)
목차
  1. 한 줄 정체
  2. 왜 지금 뜨는가
  3. 무엇을 해결하나
  4. 전체 구조
  5. 핵심 설계·동작 원리
  6. 기술 스택·의존성
  7. 설치·요구사항
  8. 실제 사용 흐름
  9. 함정·오해 방지
  10. 대안 비교
  11. 정리 · 누가 쓰면 좋은가

1한 줄 정체

"내 컴퓨터에서 도는 Electron 앱 + LLM이 파일을 직접 써넣는 코드 적용 파이프라인"

Dyad는 AI 모델이 아니라 "AI가 짠 코드를 실제 프로젝트 폴더에 적용해 주는 로컬 프로그램"이다. package.json의 한 줄 설명 그대로 "Free, local, open-source AI app builder"다. 겉모습은 Lovable·v0·bolt.new 같은 채팅형 앱 빌더와 똑같지만, 그 서비스들이 사용자 코드를 회사 클라우드 서버에 두는 것과 달리 Dyad는 Electron 데스크탑 앱을 다운로드해 실행하는 순간부터 모든 프로젝트 파일이 사용자 디스크(~/dyad-apps 류의 로컬 폴더)에 그대로 존재한다.

기술적으로 핵심은 두 가지다. 하나는 LLM 프로바이더 추상화(Vercel AI SDK 기반, OpenAI·Anthropic·Google·Azure·xAI·Bedrock·OpenRouter·Ollama·LM Studio 등을 갈아 끼울 수 있음)이고, 다른 하나는 <dyad-write> 같은 전용 의사(疑似) XML 태그로 LLM 응답을 구조화해 그 자리에서 실제 파일 쓰기·삭제·이름변경·의존성 설치·git 커밋으로 변환하는 "응답 처리기"다. Electron 자체가 새로 만든 것은 없지만, 이 둘을 엮어 "채팅 한 번 = 실행 가능한 앱 한 조각"을 보장하는 파이프라인이 Dyad의 실체다.

한 줄 비유

"클라우드 코딩 비서"를 통째로 내 데스크에 옮겨놓은 것

Lovable·v0 같은 서비스는 회사 서버의 비서에게 앱을 만들어 달라고 부탁하는 것과 같다. 비서는 일을 잘하지만, 결과물(코드)도 회사 창고(클라우드)에 보관되고 요금도 그 회사가 정한다.

Dyad는 같은 비서(LLM)를 부르되, 비서가 일하는 책상과 서류함을 내 집(내 컴퓨터)으로 옮겨온 것이다. 비서는 여전히 전화(API)로 부르지만 — OpenAI든 로컬 Ollama 모델이든 내가 고른다 — 만들어진 서류(코드)는 항상 내 서랍(로컬 git 저장소)에 쌓인다.

2왜 지금 뜨는가

클라우드 AI 빌더 피로감 · BYOK(내 키로 쓰기) 열망 · "코드 락인" 거부감

① 클라우드 AI 앱 빌더의 구독료·락인 피로감

Lovable·v0·bolt.new류는 대부분 사용량 기반 크레딧 과금이고, 프로젝트가 그 회사 인프라 안에 갇힌다. Dyad의 제품 문서(PRODUCT.md)는 타깃 사용자를 정확히 "Lovable/v0/Bolt-style 툴에서 넘어온, 코딩 배경이 없는 논테크니컬 빌더"로 명시한다. "그 경험은 좋았는데 요금과 락인이 싫다"는 사람들을 정면으로 겨냥한 포지셔닝이다.

② BYOK(Bring Your Own Key) + 로컬 모델이라는 선택권

Dyad는 OpenAI/Anthropic/Google 키를 직접 붙이는 것은 물론, Ollama·LM Studio로 완전히 무료·오프라인 모델을 쓸 수도 있다. "AI 앱 빌더를 쓰고 싶지만 특정 회사 모델에 종속되긴 싫다"는 개발자들의 요구와 맞아떨어진다.

③ "로컬 우선(local-first)" 트렌드와 신뢰 문제

AI에게 코드 생성을 맡기는 것 자체가 아직 신뢰 이슈가 있는 상황에서, "적어도 내 파일은 내 디스크에, 되돌리기(git)도 내 손안에" 있다는 사실은 심리적 안전판이 된다. PRODUCT.md는 이를 "Local-first (fast, private, no lock-in) is the core differentiator"라고 스스로 밝힌다.

경쟁 지형
완전 오픈소스도, 완전 SaaS도 아닌 중간지대

Dyad는 무료·오픈소스 코어에 "Dyad Pro"라는 유료 게이트웨이(스마트 컨텍스트, 레이지 에딧, 클라우드 샌드박스 등)를 얹은 오픈코어(open-core) 모델이다. "완전 무료 자급자족"과 "완전 관리형 SaaS" 사이에서, 코드 소유권은 지키면서 필요할 때만 클라우드 편의 기능을 사는 구조다.

3무엇을 해결하나

코드 락인 제거 · 모델 선택권 · "AI가 뭘 바꿨는지 모르겠다" 문제
문제 ①

"내 앱 코드가 남의 서버에만 있다"는 불안

Dyad는 앱을 만들 때 로컬 디렉토리(getDyadAppsBaseDirectory())에 실제 프로젝트 폴더를 만들고 git으로 초기화한다. 클라우드 빌더를 쓰다가 서비스가 종료되거나 요금이 오르면 손쓸 수 없는 상황을 원천적으로 피한다.

문제 ②

"어떤 모델을 쓸지"를 도구가 강요하는 문제

src/ipc/utils/get_model_client.tsmodel.provider 문자열 하나로 OpenAI·Anthropic·Google·Azure·xAI·Bedrock·OpenAI-호환·Ollama·LM Studio를 모두 같은 인터페이스로 다룬다. 사용자는 설정 화면에서 프로바이더/모델을 자유롭게 바꿔 끼울 수 있다.

문제 ③

"AI가 무슨 파일을 왜 바꿨는지 모르겠다"는 불투명성

모든 응답은 <dyad-write path="..." description="...">처럼 파일 경로와 설명이 태그에 못박힌 구조화된 형태로만 나오도록 시스템 프롬프트가 강제한다(마크다운 코드블록은 명시적으로 금지). 그 덕분에 UI는 "이번 턴에 어떤 파일이 어떻게 바뀌었는지"를 정확히 보여줄 수 있고, 매 턴이 git 커밋 하나로 남아 되돌리기(버전 보기)도 가능하다.

문제 ④

"로컬인데 백엔드는 어떻게 만들지"

순수 로컬 앱은 인증·DB 같은 백엔드가 없다는 한계가 있다. Dyad는 이를 Supabase(Auth/DB/Edge Functions)·Neon(서버리스 Postgres)·Vercel(배포)·GitHub(원격 저장소) 연동으로 메꾼다. AI가 생성한 SQL을 감지해 Supabase/Neon에 바로 실행해 주는 것까지 자동화되어 있다(executeSupabaseSql, executeNeonSql).

4전체 구조

Electron 3계층 — 렌더러(React) ↔ preload(contextBridge) ↔ 메인 프로세스(IPC 핸들러 ~50개 모듈)

Dyad는 일반적인 Electron 앱의 교과서적인 3계층 구조를 아주 크게 확장한 형태다. src/main.ts(1,544줄)가 앱 생명주기를 관리하고, src/preload.tscontextBridge로 안전한 통로만 열어주며, src/ipc/ipc_host.ts가 도메인별 핸들러 약 50개를 등록한다. 렌더러(React UI)는 이 통로로만 파일시스템·git·AI 호출에 접근할 수 있다.

┌──────────────────────────────────────────────────────────────┐ │ DYAD 3계층 아키텍처 │ └──────────────────────────────────────────────────────────────┘ [렌더러] React 19 UI (src/components, src/routes, chat_stream/) · 채팅 입력 → chat_stream_handlers 호출 · 파일 diff / 버전(git 커밋) 뷰어 / 통합 프리뷰 iframe │ window.electron.ipcRenderer.invoke(channel, ...) ▼ [preload.ts] contextBridge.exposeInMainWorld("electron", ...) · VALID_INVOKE_CHANNELS 화이트리스트만 통과 · IPC 응답을 IpcEnvelope로 감싸 unwrap │ Electron IPC (프로세스 간 통신) ▼ [메인 프로세스] src/ipc/ipc_host.ts → registerXxxHandlers() 약 50개 ├ chat_stream_handlers.ts → AI SDK 스트리밍 호출 ├ get_model_client.ts → 프로바이더별 LLM 클라이언트 생성 ├ response_processor.ts → dyad-* 태그 파싱 → 실제 파일 적용 ├ github/vercel/supabase/neon_handlers.ts → 외부 서비스 연동 └ db (better-sqlite3 + drizzle) → 채팅/설정/앱 메타데이터 저장 │ fs.writeFile / spawn(npm|pnpm) / dugite(git) ▼ [디스크] 사용자의 실제 앱 폴더 (Vite 개발 서버 + 프리뷰)

주목할 점은 "Dyad 자신의 데이터"와 "사용자가 만드는 앱의 데이터"가 완전히 분리돼 있다는 것이다. Dyad 자체의 채팅 기록·설정·앱 목록은 src/db/schema.ts가 정의하는 로컬 SQLite(better-sqlite3 + drizzle-orm)에 저장되고, 사용자가 만드는 앱의 실제 소스코드는 그냥 디스크 위의 일반 폴더(그 자체가 독립된 git 저장소)로 존재한다. Dyad를 지워도 이미 만든 앱 폴더는 평범한 Vite+React 프로젝트로 그대로 남는다.

용어
contextBridge
Electron에서 렌더러(웹페이지)가 Node.js 전체 기능에 직접 접근하지 못하게 막고, 메인 프로세스가 허용한 몇 가지 함수만 window.electron 같은 이름으로 안전하게 노출하는 보안 장치. Dyad는 여기에 채널 화이트리스트까지 얹어 이중으로 막는다.
용어
IPC (Inter-Process Communication)
Electron의 렌더러 프로세스와 메인 프로세스는 완전히 분리된 별개의 프로세스라서, 서로 직접 함수를 호출할 수 없다. 대신 메시지를 주고받는 통로(IPC)로만 소통한다. Dyad는 ipcRenderer.invoke(channel, ...) 방식(요청-응답)을 표준으로 쓴다.

5핵심 설계·동작 원리

"LLM 응답 = 의사 XML 태그" → 파서(dyad_tag_parser.ts) → 적용 엔진(response_processor.ts)

Dyad에서 가장 중요하게 봐야 할 코드는 "AI가 뭐라고 답해야 하는가"(시스템 프롬프트)"그 답을 어떻게 실제 파일로 바꾸는가"(응답 처리기) 두 파일이다. 이 둘의 계약이 Dyad라는 제품 전체의 심장이다.

① 코드 생성 계약 — <dyad-write> 의사 XML 태그

src/prompts/system_prompt.ts는 모델에게 "코드는 절대 마크다운 코드블록으로 쓰지 말고, 오직 전용 태그로만 출력하라"고 여러 번 강한 어조로 반복 지시한다. 실제 프롬프트 문구를 보면:

<dyad-write path="src/components/Button.tsx" description="...">
  ...파일 전체 내용...
</dyad-write>

<dyad-rename from="src/components/UserProfile.tsx" to="src/components/ProfileCard.tsx"></dyad-rename>
<dyad-delete path="src/components/Analytics.tsx"></dyad-delete>
<dyad-add-dependency packages="react-hot-toast"></dyad-add-dependency>
<dyad-chat-summary>Adding a new component</dyad-chat-summary>

/* 프롬프트 원문 경고 문구 그대로: */
"ONLY use <dyad-write> tags for ALL code output."
"NO MARKDOWN CODE BLOCKS. USE <dyad-write> EXCLUSIVELY."

이 태그는 HTML/XML 표준이 아니라 Dyad가 자체적으로 정의한 규약이다. dyad-write(파일 생성/전체 덮어쓰기) 외에도 dyad-rename·dyad-delete·dyad-add-dependency(패키지 설치)·dyad-execute-sql(DB 마이그레이션 실행)·dyad-search-replace(부분 수정)·dyad-copy·dyad-command(rebuild/restart/refresh 제안)·dyad-chat-summary(채팅 제목) 태그가 있다.

중요한 함정
이건 표준 diff/patch 포맷이 아니다

다른 코딩 에이전트(Claude Code, Cursor 등)의 파일 편집 포맷과 혼동하기 쉽지만, <dyad-write>Dyad 프로젝트 고유의 프롬프트 규약일 뿐이다. 모델이 이 형식을 깨고 마크다운 코드블록으로 답하면 파서가 그 코드를 인식하지 못해 "아무 파일도 바뀌지 않는" 상황이 생긴다 — 시스템 프롬프트가 그렇게까지 반복해서 경고하는 이유다.

② 스트리밍 파서 — streamingMessageParser.ts

LLM 응답은 토큰 단위로 조금씩 도착하는데(스트리밍), <dyad-write> 태그가 아직 다 안 닫힌 상태에서도 UI는 "지금까지 써진 코드"를 실시간으로 보여줘야 한다. src/lib/streamingMessageParser.ts(528줄)는 이 미완성 태그를 안전하게 부분 파싱해 채팅 화면에 코드가 타이핑되듯 나타나게 만든다.

③ 적용 엔진 — response_processor.ts (854줄)

응답이 끝나면 src/ipc/processors/response_processor.ts가 전체 텍스트에서 src/ipc/utils/dyad_tag_parser.tsgetDyadWriteTags·getDyadRenameTags·getDyadDeleteTags 등으로 태그를 모두 뽑아낸 뒤 순서대로 실행한다.

비유

AI는 "지시서 작성자", response_processor.ts는 "현장 감독"이다. AI는 종이에 "3번 방 벽지를 이걸로 바꿔라, 5번 방은 통째로 새로 발라라"라고 정해진 양식(태그)으로만 적는다. 현장 감독은 그 지시서를 한 줄씩 읽으며 실제로 벽지를 바르고(파일 쓰기), 자재를 주문하고(의존성 설치), 작업 일지에 서명(git 커밋)까지 남긴다. AI가 양식을 어기고 낙서로 적으면 감독은 그 지시를 아예 못 알아본다.

④ LLM 프로바이더 추상화 — get_model_client.ts (679줄)

src/ipc/utils/get_model_client.tsVercel AI SDK(ai 패키지)의 프로바이더 팩토리들(createOpenAI, createAnthropic, createGoogle, createAzure, createXai, createGoogleVertex, createAmazonBedrock, createOpenAICompatible)을 한 함수 뒤로 감춘다. model.provider 문자열 하나로 어떤 회사 API를 부를지 갈아 끼우고, ollama_provider.ts·lm_studio_utils.ts완전히 로컬에서 도는 모델도 동일한 인터페이스로 붙일 수 있게 만든다.

유료 Dyad Pro를 켜면 createDyadEngine(llm_engine_provider.ts)이 요청을 Dyad가 직접 운영하는 게이트웨이(DYAD_ENGINE_URL)로 우회시켜, "스마트 파일 컨텍스트"·"레이지 에딧"(전체 파일 재작성 대신 부분 수정) 같은 부가 기능과 dyad/auto/* 자동 모델 별칭을 추가한다. 이 경로가 꺼져 있으면 사용자의 API 키가 각 프로바이더로 직접 나간다 — 즉 기본값은 완전 BYOK, Pro는 그 위에 얹는 부가 레이어다.

⑤ 앱 스캐폴딩 — scaffold/ 폴더와 템플릿

새 앱을 만들 때 기본 "react" 템플릿을 고르면 createFromTemplate.ts가 저장소에 통째로 들어있는 scaffold/ 디렉토리(Vite + React + TypeScript + Tailwind + shadcn/ui 기반의 이미 동작하는 최소 앱)를 그대로 복사해온다. 다른 커뮤니티 템플릿을 고르면 cloneRepo()HTTPS GitHub URL만 허용하는 검증을 거쳐 해당 저장소를 클론한 뒤 앱 폴더로 복사한다.

⑥ "에이전트 모드"는 같은 태그로 수렴한다 — 도구 호출 → XML 역변환

Dyad Pro의 로컬 에이전트(src/pro/main/ipc/handlers/local_agent/)는 한 번에 통짜 텍스트를 뱉는 대신 write_file·delete_file·rename_file·add_dependency·execute_sandbox_script 같은 구조화된 AI SDK 도구 호출(tool calling)을 쓴다. 그런데 tools/write_file.tsbuildXml() 함수를 보면, 이 도구 호출 결과를 다시 <dyad-write path="...">...</dyad-write> 형태의 같은 XML 문자열로 역변환해 돌려준다. 즉 "한 방에 텍스트로 답하는 기본 모드"와 "단계적으로 도구를 부르는 에이전트 모드"가 서로 다른 입력 방식을 쓰면서도, 결국 같은 response_processor.ts 파이프라인 하나로 수렴하도록 설계돼 있다 — 적용 로직을 두 번 만들지 않으려는 선택이다.

에이전트가 임의 스크립트를 돌려야 할 때는 Node.js eval이 아니라 mustardscript라는 별도의 제한된 스크립팅 언어worker_threads 안에서(sandbox/runner.ts, sandbox_worker.ts) 실행해, 시간·메모리 제한(limits.ts)을 두고 read_file/list_files/file_stats/write_file 같은 딱 정해진 호스트 함수만 호출하게 한다(capabilities.tsSANDBOX_HOST_CALL_NAMES).

⑦ 동시성 제어 — 자체 액터 모델(distributed_machines/)

Dyad는 src/distributed_machines/ 아래 직접 만든 액터(actor) 모델 프레임워크(actor_host.ts, keyed_admission_gate.ts, remote_protocol.ts)를 갖고 있다. 앱 실행 상태·채팅 스트림 같은 것들을 "액터"로 다루면서, 같은 키(예: 같은 앱)에 대한 중복·낡은 명령이 잘못 끼어들지 못하게 "입장 게이트(admission gate)"로 세대(generation)를 관리한다. 이 저장소를 클론한 시점의 가장 최근 커밋(#4139, "keyed actor admission fences")이 정확히 이 모듈을 강화하는 리팩터링이었다 — 여러 창·여러 앱을 동시에 다루는 데스크탑 앱에서 레이스 컨디션을 막는 문제가 여전히 활발히 다뤄지고 있다는 뜻이다.

용어
BYOK (Bring Your Own Key)
서비스가 자체 AI 요금을 받는 대신, 사용자가 자기 OpenAI/Anthropic 등 API 키를 직접 입력해 그 회사에 직접 비용을 지불하는 방식. Dyad의 기본 모델이다.
용어
도구 호출 (tool calling / function calling)
LLM이 자유 텍스트 대신 미리 정의된 함수 이름과 인자(JSON)를 "호출"하는 형태로 답하게 하는 방식. Dyad Pro의 에이전트 모드는 이를 쓰고, 이후 다시 dyad 태그 형식으로 변환해 재사용한다.
용어
액터 모델 (actor model)
상태를 가진 독립적인 단위("액터")들이 서로 메시지만 주고받으며 동작하게 하여 동시성 버그(레이스 컨디션)를 구조적으로 줄이는 설계 기법. Dyad는 앱 실행·채팅 세션 등의 동시성 관리에 자체 구현체를 쓴다.

6기술 스택·의존성

Electron 40 + React 19 + Vite · Drizzle/SQLite · Vercel AI SDK · dugite(git) · oxlint/oxfmt
영역실제 사용 기술
데스크탑 셸Electron 40.0.0 + electron-forge 7(VitePlugin으로 main/preload/renderer 각각 빌드) + FusesPlugin(보안 강화 옵션)
프론트엔드React 19.2.4 + TanStack Router/Query + Jotai(원자 상태) + Tailwind CSS v4 + shadcn/ui("new-york") + Base UI/Radix
에디터/터미널Monaco Editor(코드 편집) · xterm.js(+addon 5종, 통합 터미널) · Lexical(메타의 리치텍스트 엔진, 채팅 입력의 @멘션 처리)
LLM 연동Vercel AI SDK(ai v6) + @ai-sdk/{openai,anthropic,google,azure,xai,amazon-bedrock,google-vertex,openai-compatible,mcp} · MCP(@modelcontextprotocol/sdk)로 외부 도구 서버 연결
로컬 저장better-sqlite3 + drizzle-orm(스키마: apps, prompts, mcpServers 등) — Dyad 자체 메타데이터 전용, 사용자 앱 코드는 그냥 디스크 파일
git 연동dugite(GitHub가 만든 Node용 git 바이너리 래퍼) — 매 AI 턴을 커밋 하나로 기록
외부 서비스 SDK@octokit류(GitHub), @dyad-sh/supabase-management-js, @neondatabase/api-client, @vercel/sdk
스크립트 샌드박스mustardscript(제한된 자체 스크립팅 언어) — 에이전트가 "코드를 실행"해야 할 때 Node eval 대신 사용
빌드/타입체크tsgo(TypeScript 네이티브 프리뷰 컴파일러, 빠른 --noEmit 체크) · oxlint/oxfmt(Rust 기반 초고속 린트·포맷터) · Husky pre-commit
테스트Vitest(유닛/통합, 파일 475개) + Playwright(E2E, 스펙 127개) + node --test(스크립트 자체 테스트)
배포/서명electron-forge Maker: Squirrel(Win)·ZIP/dmg(mac)·Deb/Rpm·커스텀 MakerAppImage(Linux) + windowsSign.ts(코드서명) + update-electron-app(자동 업데이트)
용어
오픈코어 (open-core)
핵심 기능은 오픈소스로 무료 공개하고, 그 위에 클라우드 전용 부가 기능(여기선 Dyad Pro 엔진·클라우드 샌드박스)을 유료로 얹는 사업 모델. Dyad는 src/pro/ 폴더만 별도 라이선스로 분리해 이 구조를 코드베이스에서도 물리적으로 나눈다.

7설치·요구사항

Mac/Windows 바이너리 다운로드 · 실질적으로는 Node.js 실행 환경도 필요
항목내용
일반 사용자dyad.sh에서 Mac·Windows용 설치 파일 다운로드(README 기준). 회원가입 불필요, 실행 즉시 온보딩(템플릿 선택 → API 키 입력)
AI 모델OpenAI/Anthropic/Google 등 중 하나 이상의 API 키(BYOK), 또는 로컬에 Ollama·LM Studio를 설치해 무료 로컬 모델 사용, 또는 Dyad Pro 구독
선택 연동GitHub(코드 푸시) · Supabase(백엔드/DB) · Vercel(배포) · Neon(서버리스 Postgres) — 전부 옵션, 없어도 로컬 프리뷰만으로 앱 개발 가능
개발자(소스 빌드)git clonenpm installnpm run init-precommitnpm run dev(내부적으로 scripts/start-supervisor.mjs). Node >=24 <26(package.json engines) 요구
네이티브 모듈macOS Keychain 접근용 dyad-keychain-reader(옵셔널 네이티브 모듈)는 npm run rebuild:keychain-reader로 별도 리빌드 필요 — Electron 패키징 시 자주 깨지는 지점이라 rules/native-modules.md로 따로 문서화돼 있다
주의
"코드를 몰라도 된다"는 "Node.js가 필요 없다"는 뜻이 아니다

Dyad는 생성된 앱을 실제로 로컬 Vite 개발 서버로 띄워 미리보기한다. 즉 내부적으로 진짜 npm install/npm run dev급 프로세스가 사용자 컴퓨터에서 돈다. 그래서 Dyad는 managed_node.ts 같은 자체 Node.js 버전 관리 로직까지 갖고 있다 — "논테크니컬 사용자"를 타깃으로 하지만 실제로는 Node 환경 문제가 온보딩 마찰의 큰 부분을 차지한다는 뜻이다.

8실제 사용 흐름

템플릿 선택 → 채팅 → 태그 적용 → git 커밋 → 프리뷰 → (선택) 배포

1. 앱 생성 — 템플릿 고르기

온보딩에서 프로바이더 API 키를 입력하고, "react"(내장 scaffold/) 또는 커뮤니티 GitHub 템플릿 중 하나를 고르면 createFromTemplate.ts가 로컬 앱 폴더를 만들고 git으로 초기화한다.

2. 채팅으로 요구사항 입력

"로그인 폼 추가해줘" 같은 프롬프트를 치면 chat_stream_handlers.ts가 시스템 프롬프트(system_prompt.ts) + 현재 코드베이스 컨텍스트와 함께 선택된 모델로 스트리밍 요청을 보낸다. Ask 모드(설명만)와 실제로 코드를 바꾸는 모드가 구분되어 있다.

3. 태그 파싱 → 실제 파일 적용

응답이 끝나면 response_processor.ts<dyad-write> 등을 실제 fs 쓰기·의존성 설치·SQL 실행으로 옮기고, 변경 전체를 git 커밋 하나로 남긴다. 필요하면 <dyad-command type="rebuild"> 같은 태그로 개발 서버 재시작도 제안한다.

4. 라이브 프리뷰 확인 & 되돌리기

이미 떠 있는 앱의 Vite 개발 서버가 변경을 감지해 iframe 프리뷰가 자동 새로고침된다. 마음에 안 들면 이전 git 커밋(버전)으로 그냥 되돌아갈 수 있다 — 별도 undo 시스템이 아니라 git 히스토리 자체가 버전함이다.

5. (선택) 백엔드 연결 · 배포

Supabase를 연결하면 AI가 만든 스키마/SQL이 자동 실행되고, GitHub에 원격 저장소를 만들어 푸시하거나 Vercel로 바로 배포할 수 있다. MCP 서버를 추가하면 외부 도구(예: 특정 API 문서 검색)를 채팅 컨텍스트에 붙일 수도 있다.

9함정·오해 방지

"완전 오픈소스" 아님 · "완전 로컬" 아님 · README와 실제 코드의 틈
오해 ①
"오픈소스"라고 해서 전체가 Apache 2.0은 아니다

README와 LICENSEsrc/pro/ 바깥은 Apache 2.0이라고 명시하지만, src/pro/ 안쪽은 별도의 src/pro/LICENSE를 따른다. 그 내용은 FSL-1.1-ALv2(Functional Source License) — "저작권자 Dyad Tech, Inc." 명의로, 소스는 공개돼 있지만 Dyad와 경쟁하는 상용 서비스로 재판매하는 용도(Competing Use)는 금지되고, 일정 기간이 지나야 Apache 2.0으로 전환되는 "훼어소스(fair-source)" 라이선스다. "레포 전체가 MIT/Apache라서 뭐든 자유롭게 가져다 써도 된다"고 오해하면 안 된다.

오해 ②
"완전 로컬 = 인터넷 연결 없이도 100% 동작"은 아니다

Ollama/LM Studio로 로컬 모델만 쓰면 오프라인에 가깝게 쓸 수 있지만, Dyad Pro 엔진·클라우드 샌드박스(cloud_sandbox_provider.ts, 로컬에서 돌리기 어려운 실행 환경을 원격 샌드박스에 동기화)·Supabase/Vercel/Neon 연동은 모두 클라우드에 의존하는 옵션 기능이다. "로컬 우선"이지 "로컬 전용"이 아니다.

오해 ③
README는 "Mac·Windows"만 말하지만 실제 빌드는 Linux도 만든다

README의 "Cross-platform: Easy to run on Mac or Windows" 문구만 보면 Linux 지원이 없어 보이지만, forge.config.ts에는 MakerDeb·MakerRpm·자체 제작한 MakerAppImage(x64/arm64)가 실제로 존재한다. 문서와 실제 배포 설정 사이의 대표적인 틈이다.

오해 ④
로컬 SQLite DB는 "내 앱의 데이터베이스"가 아니다

src/db/schema.tsbetter-sqlite3 DB는 Dyad 프로그램 자신의 채팅 기록·앱 목록·설정을 저장하는 것이지, 사용자가 만드는 앱(예: 할일 관리 앱)의 데이터베이스가 아니다. 생성된 앱이 실제 DB가 필요하면 Supabase나 Neon 같은 별도 백엔드를 연결해야 한다.

참고
이 프로젝트는 스스로 AI 코딩 에이전트를 리뷰어로 쓴다

.github/workflows/에는 claude-pr-review.yml·codex-pr-review.yml·claude-triage.yml·claude-rules-review.yml 등이 있다 — AI 앱 빌더를 만드는 팀이 실제로 Claude·Codex 같은 코딩 에이전트를 PR 리뷰·이슈 트리아지 자동화에 쓰고 있다는 뜻으로, "AI로 앱을 만드는 도구"를 만드는 과정 자체도 AI 에이전트로 굴러간다.

10대안 비교

Lovable · v0 · bolt.new · Onlook — "어디서 도는가"와 "코드는 누구 것인가"가 갈림길
도구실행 위치코드 소유/락인모델 선택권특징
Dyad로컬 Electron 앱내 디스크 + git, 락인 없음BYOK 전 프로바이더 + 로컬 모델(Ollama/LM Studio)무료 오픈코어, Pro는 부가 기능(엔진/샌드박스)만 유료
Lovable클라우드(SaaS)플랫폼 종속, GitHub 내보내기 가능플랫폼이 지정한 모델 위주크레딧 기반 과금, 원클릭 배포·백엔드 통합이 매끄러움
v0 (Vercel)클라우드(SaaS)Vercel 생태계에 최적화Vercel이 제공하는 모델UI 컴포넌트 생성/디자인 반복에 특히 강함
bolt.new (StackBlitz)브라우저 내 WebContainer(클라우드)내보내기 가능하나 편집은 브라우저 종속플랫폼 제공 모델 위주설치 없이 브라우저에서 즉시 실행, Node.js를 브라우저 안에서 흉내
Onlook로컬 데스크탑 앱(오픈소스)내 디스크BYOK 가능Dyad와 결이 가장 비슷한 "로컬 비주얼 코드 에디터" 계열, 다만 시각적 편집(디자인 툴 느낌)에 더 무게
비유

Lovable·v0·bolt.new가 "호텔 레스토랑"이라면(요리는 훌륭하지만 재료·주방은 호텔 것), Dyad는 "내 집 주방에 셰프를 초대해 요리하게 하는 것"이다. 냉장고(코드)와 그릇(파일)은 전부 내 것이고, 셰프(LLM)만 어느 회사에서 부를지 고를 수 있다.

11정리 · 누가 쓰면 좋은가

"코드 소유권 + 모델 자유도"가 최우선인 1인 빌더·개발자에게 적합

Dyad를 한 문장으로 정리하면 "클라우드 AI 앱 빌더의 UX를, 로컬 Electron 앱 + git + BYOK 조합으로 재구현한 오픈코어 도구"다. 핵심 설계는 화려한 신기술이 아니라 "LLM 응답을 태그로 구조화하고, 그 태그를 안전하게 실제 파일 시스템 작업으로 변환하는" 지극히 실용적인 파이프라인이다. 여기에 Vercel AI SDK로 프로바이더를 추상화하고, git 커밋을 버전 관리로 재활용하는 두 가지 선택이 제품 경험 대부분을 만들어낸다.

이런 사람에게 잘 맞는다

· 클라우드 AI 앱 빌더를 써봤지만 구독료·락인이 부담스러운 1인 개발자·사이드 프로젝트 빌더

· 특정 LLM 회사에 종속되기 싫고 여러 모델을 자유롭게 바꿔가며 비교해보고 싶은 사람

· "AI가 코드를 어떻게 적용하는지"를 실제 소스로 뜯어보며 배우고 싶은 학습자 — 태그 파서·응답 처리기·프로바이더 추상화 모두 읽을 수 있는 TypeScript 코드다

이런 사람에겐 별로다

· Node.js/git 개념조차 신경 쓰고 싶지 않은, 완전히 코드 개념 없는 초초보 사용자(내부적으로 실제 개발 서버가 돈다)

· 원클릭으로 팀 협업·클라우드 백엔드까지 매끄럽게 이어지는 완성형 매니지드 경험을 원하는 경우 (Lovable류가 더 매끄러울 수 있다)