<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by 조영제 on Medium]]></title>
        <description><![CDATA[Stories by 조영제 on Medium]]></description>
        <link>https://medium.com/@siosio3103?source=rss-e8991afece8c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*SlQWMArq2pnFsAMz-tcicA.jpeg</url>
            <title>Stories by 조영제 on Medium</title>
            <link>https://medium.com/@siosio3103?source=rss-e8991afece8c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 25 Jun 2026 03:00:19 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@siosio3103/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[[번역] 5가지 도구, 커스텀 훅, 강제 적용으로 Claude Code 토큰 사용량을 90% 이상 줄인 방법]]></title>
            <link>https://siosio3103.medium.com/%EB%B2%88%EC%97%AD-5%EA%B0%80%EC%A7%80-%EB%8F%84%EA%B5%AC-%EC%BB%A4%EC%8A%A4%ED%85%80-%ED%9B%85-%EA%B0%95%EC%A0%9C-%EC%A0%81%EC%9A%A9%EC%9C%BC%EB%A1%9C-claude-code-%ED%86%A0%ED%81%B0-%EC%82%AC%EC%9A%A9%EB%9F%89%EC%9D%84-90-%EC%9D%B4%EC%83%81-%EC%A4%84%EC%9D%B8-%EB%B0%A9%EB%B2%95-432e41806427?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/432e41806427</guid>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Sun, 31 May 2026 10:22:14 GMT</pubDate>
            <atom:updated>2026-05-31T10:22:14.767Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>원문: <a href="https://medium.com/@abdulgafoorabid/how-i-cut-claude-code-token-usage-by-90-with-4-tools-custom-hooks-and-enforcement-d3f8d2488cd6">https://medium.com/@abdulgafoorabid/how-i-cut-claude-code-token-usage-by-90-with-4-tools-custom-hooks-and-enforcement-d3f8d2488cd6</a></blockquote><h3>TL;DR</h3><p>저는 5개의 레이어를 쌓아서 Claude Code 토큰 사용량을 90% 이상 줄였습니다.</p><ol><li><strong>Codebase Memory MCP</strong>는 지식 그래프(knowledge graph)로 코드 탐색 시 파일 읽기를 대체합니다(99% 절감).</li><li><strong>context-mode</strong>는 큰 출력을 샌드박스 처리하고 요약본만 돌려줍니다(98% 절감).</li><li><strong>RTK</strong>는 CLI 출력을 그 자리에서 압축합니다(60–90% 절감).</li><li><strong>Headroom</strong>은 프롬프트가 머신을 떠나기 전에 전체 프롬프트를 압축하는 API 프록시입니다(47–92% 절감).</li><li><strong>Caveman</strong>은 Claude 자신의 응답을 간결하게 다듬습니다(50–75% 절감).</li></ol><p>커스텀 훅이 이 도구들을 강제해서 Claude가 우회하지 못합니다. 여기에 컴팩션(compaction)에도 살아남는 자동 핸드오프(handoff) 시스템 덕분에 긴 세션에서도 상태를 잃지 않습니다.</p><p>세션은 약 30분에서 3시간 이상으로 늘었습니다. 글 마지막에 원클릭 설치 스크립트가 있습니다.</p><h3>60초 안에 보는 치트시트</h3><ul><li>/clear를 적극적으로, 그리고 세션마다 쓰지 않는 MCP 서버는 비활성화하세요</li><li>아키텍처에는 **산문보다 머메이드(Mermaid)**가 낫습니다. 토큰은 적고, 네이티브로 파싱됩니다</li><li><strong>CBM</strong>(그래프)로 코드 탐색, <strong>context-mode</strong>로 큰 출력, <strong>RTK</strong>로 셸, <strong>Headroom</strong>으로 API 페이로드, <strong>Caveman</strong>으로 Claude의 응답을 다룹니다</li><li>무거운 일은 훅 두 개가 처리합니다. bash-ban-raw-tools가 cat/grep/find 같은 원시 명령을 차단하고, cbm-code-discovery-gate가 CBM이 호출되기 전까지 소스에 대한 Read/Grep을 막습니다</li><li>CLAUDE.md는 /caveman:compress로 압축합니다. 세션마다 로드되므로 절감이 곱셈으로 쌓입니다</li><li>스택별 룰 파일(rules/flutter.md, react.md, appwrite.md). 스킬 게이트와 번호 매긴 자체 점검을 겁니다</li><li>Tavily/Appwrite는 <strong>MCP보다 CLI</strong>를 씁니다. 같은 기능에 컨텍스트 비용은 훨씬 적습니다</li><li>MCP 서버는 단 2개. codebase-memory-mcp와 context-mode. 나머지는 전부 CLI 아니면 훅입니다</li><li>PostToolUse 거부 스캐너. ESLint 커스텀 규칙, node 정규식 스캐너, Dart analyzer 플러그인, Husky + lint-staged</li><li>설정. effortLevel: high, advisorModel: opus, ENABLE<em>PROMPT_CACHING_1H=1, </em><em>CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=50, </em><em>CLAUDE_CODE_SUBAGENT</em>MODEL=claude-sonnet-4-6</li><li>컴팩션 시 자동 핸드오프. PreCompact 훅이 claude -p --bare를 호출해 docs/handoff-context.md를 작성하고, SessionStart 훅이 다음 세션에서 자동으로 인라인합니다. 수동 /handoff도 언제든 가능합니다</li><li>멀티모델 파이프라인. Opus 4.7로 플랜 짜기(또는 /ultraplan), Opus로 구현, /unleash 스웜, 그다음 다른 벤더로 리뷰(저는 Codex GPT-5.5를 쓰지만 똑똑한 모델이면 뭐든 됩니다). E2E도 같은 방식입니다(웹은 Agent Browser dogfood, Flutter는 Dart MCP)</li><li><strong>Codeburn</strong>으로 절감을 측정하고, Fluid Voice(Parakeet)로 받아쓰기를 합니다</li></ul><p>Claude Code를 처음 쓸 때 저는 20~30분 만에 컨텍스트를 다 써버리고 끊임없이 레이트 리밋에 걸렸습니다. 몇 번의 시행착오 끝에 세션을 3시간 이상으로 늘리고 토큰 비용도 크게 낮춰 주는 계층형 스택을 찾아냈습니다.</p><p>동반 저장소 <a href="https://github.com/sgaabdu4/claude-code-tips">github.com/sgaabdu4/claude-code-tips</a>에 아래에 나오는 모든 설정, 훅, 스크립트가 들어 있습니다.</p><h3>문제</h3><p>Claude Code는 토큰을 많이 먹습니다. cargo test(262개 테스트) = 4,823 토큰. git diff HEAD~1 = 21,500 토큰. 500줄짜리 파일 한 번 Read 하면 컨텍스트 윈도가 금세 차오릅니다. 자동 컴팩트(autocompact)가 일찍 발동하고, 히스토리는 사라지고, 세션은 죽고, 예산은 타들어 갑니다.</p><h3>해결책. 파이프라인의 서로 다른 지점에 놓인 5개의 레이어</h3><pre>┌───────────────────────────────────────────────────┐<br>│                  프롬프트 / 쿼리                  │<br>└─────────────────────┬─────────────────────────────┘<br>                      │<br>         ┌────────────▼────────────┐<br>         │  레이어 1: CBM          │  &quot;파일을 아예 읽지 마라&quot;<br>         │  (지식 그래프)          │  구조적 쿼리에서 99% 절감<br>         └────────────┬────────────┘<br>                      │<br>         ┌────────────▼────────────┐<br>         │  레이어 2: context-mode │  &quot;실행은 하되, 출력은 샌드박스에&quot;<br>         │  (출력 가상화)          │  큰 출력에서 98% 절감<br>         └────────────┬────────────┘<br>                      │<br>         ┌────────────▼────────────┐<br>         │  레이어 3: RTK          │  &quot;컨텍스트에 들어오는 것을 압축&quot;<br>         │  (셸 압축)              │  CLI 출력에서 60-90% 절감<br>         └────────────┬────────────┘<br>                      │<br>         ┌────────────▼────────────┐<br>         │  레이어 4: Headroom     │  &quot;API에서 모든 것을 압축&quot;<br>         │  (API 레이어 프록시)    │  남은 모든 토큰에서 47-92%<br>         └────────────┴────────────┘<br>                      │<br>              ┌───────▼───────┐<br>              │   Caveman     │  &quot;Claude도 말을 줄인다&quot;<br>              │ (출력 스타일) │  Claude 응답에서 50-75%<br>              └───────┬───────┘<br>                      │<br>                      ▼<br>                Anthropic API</pre><p>각 레이어는 이전 레이어가 놓친 부분을 잡습니다. 지점이 다르고 서로 겹치지 않습니다.</p><h3>훅을 건드리기 전에 챙겨야 할 것</h3><p>별다른 노력 없이 오늘 당장 토큰을 아낄 수 있는 세 가지입니다.</p><ul><li><strong>/clear를 적극적으로</strong>. 짧고 집중된 세션이 긴 세션을 이깁니다. 세션이 길어질수록 Claude는 자신이 남긴 흔적을 다시 읽습니다. (<a href="https://code.claude.com/docs/en/claude-code/slash-commands">Claude Code slash commands</a>)</li><li><strong>세션마다 쓰지 않는 MCP 서버 비활성화</strong>. claude mcp list로 확인하고 이번 작업에 필요 없는 건 빼세요. 쓰지 않는 서버도 툴 디스크립션을 통해 컨텍스트를 조용히 태웁니다. (<a href="https://code.claude.com/docs/en/claude-code/cli-reference#mcp">claude mcp reference</a>)</li><li><strong>아키텍처는 산문 대신 머메이드</strong>. 6줄짜리 머메이드 다이어그램이 3개 문단과 같은 형태의 정보를 토큰 일부만으로 담아냅니다. 게다가 Claude가 네이티브로 파싱합니다.</li></ul><h3>레이어 1. Codebase Memory MCP (코드 탐색에서 99% 토큰 절감)</h3><p>저장소: <a href="https://github.com/DeusData/codebase-memory-mcp">github.com/DeusData/codebase-memory-mcp</a></p><p><strong>무엇을 하는가</strong>. 전체 코드베이스를 tree-sitter AST 파싱(66개 언어 지원)으로 영속적인 지식 그래프에 색인합니다. “이 함수를 누가 호출하는가?”, “아키텍처를 보여 줘” 같은 질문에 답하려고 파일을 읽는 대신, Claude는 그래프에 쿼리해서 50개 파일(400K 토큰)을 읽는 대신 50 토큰짜리 구조화된 답을 받습니다.</p><p><strong>실제 숫자</strong>. 다섯 개의 구조적 쿼리가 CBM으로는 약 3,400 토큰을 썼고, 파일 하나하나를 grep으로 탐색했을 때는 약 412,000 토큰을 썼습니다. <strong>99.2% 감소</strong>입니다.</p><h3>강제 적용하는 방법</h3><p>Claude에게 CBM을 먼저 쓰라고 <em>말해 두기만</em> 하지 않습니다. CBM을 쓰지 않고는 파일 읽기로 <em>돌아갈 수 없게</em> 막아 둡니다.</p><p><strong>게이트 패턴</strong>. 훅 두 개가 함께 작동합니다. PreToolUse 훅이 소스 파일에 대한 Grep/Glob/Read를 차단합니다. PostToolUse 훅은 codebase-memory-mcp 도구가 실행될 때마다 마커 파일을 만듭니다. 게이트는 CBM 호출 후 120초 동안 Read를 허용해서 읽고-편집의 흐름을 살리고, 코드가 아닌 파일(설정, 문서, JSON)은 언제나 허용합니다.</p><p>~/.claude/hooks/cbm-code-discovery-gate(PreToolUse). <a href="https://github.com/sgaabdu4/claude-code-tips/blob/main/hooks/cbm-code-discovery-gate">전체 파일은 저장소에</a> 있습니다. 핵심 로직입니다.</p><pre>case &quot;$TOOL&quot; in<br>  Read)<br>    FP=$(echo &quot;$INPUT&quot; | jq -r &#39;.toolinput.filepath // &quot;&quot;&#39;)<br>    # Allow configs, docs, tests, settings<br>    if [[ &quot;$FP&quot; =~ \.(json|yaml|yml|md|toml|lock|txt|env|sh)$ ]] \<br>      || [[ &quot;$FP&quot; =~ (\.claude|CLAUDE\.md|settings|hooks/|/test/|_test\.) ]]; then<br>      exit 0<br>    fi<br>    # Allow Read if CBM was used in last 120s<br>    if [ -f &quot;$MARKER&quot; ]; then<br>      AGE=$(( $(date +%s) - $(stat -f %m &quot;$MARKER&quot; 2&gt;/dev/null || stat -c %Y &quot;$MARKER&quot;) ))<br>      [ &quot;$AGE&quot; -lt 120 ] &amp;&amp; exit 0<br>    fi<br>    echo &quot;BLOCKED Read on source without a recent codebase-memory-mcp call.&quot; &gt;&amp;2<br>    exit 2<br>    ;;<br>esac</pre><p>Grep과 Glob 분기도 같은 패턴을 따릅니다. 짝을 이루는 훅이 두 개 더 있습니다(<a href="https://github.com/sgaabdu4/claude-code-tips/tree/main/hooks">저장소</a>).</p><ul><li>cbm-mcp-marker(PostToolUse). CBM 도구가 발동하면 /tmp/cbm-mcp-used-$PPID를 touch해서 게이트가 120초 동안 잠금을 풀게 합니다.</li><li>cbm-session-reminder(SessionStart, resume/clear/compact 매칭). 세션 중간에 Claude가 잊지 않도록 CBM 프로토콜을 다시 주입합니다.</li></ul><p><strong>핵심 통찰</strong>. CBM을 <em>제안</em>만 하면 Claude는 <em>언제든</em> Read/Grep으로 돌아갑니다. 제안은 강제가 아닙니다. 차단이 강제입니다.</p><h3>레이어 2. context-mode (큰 출력에서 98% 토큰 절감)</h3><p>저장소: <a href="https://github.com/mksglu/context-mode">github.com/mksglu/context-mode</a></p><p><strong>무엇을 하는가</strong>. 컨텍스트 가상화 레이어입니다. 도구 출력이 그대로 대화 컨텍스트로 흘러 들어가게 두는 대신, 출력을 가로채 샌드박스 서브프로세스에서 실행하고, 전체 출력을 로컬 BM25 지식 베이스에 색인한 다음, 간결한 요약본만 돌려줍니다. 전체 출력은 필요할 때 검색할 수 있게 남습니다.</p><p><strong>실제 숫자</strong>.</p><p>작업 원본 context-mode 적용 절감 Playwright DOM 스냅샷 56.2 KB 299 B <strong>99%</strong> GitHub Issues (20개) 58.9 KB 1.1 KB <strong>98%</strong> Git log (커밋 153개) 11.6 KB 107 B <strong>99%</strong> 전체 세션 315 KB 5.4 KB <strong>98%</strong></p><p>같은 200K 컨텍스트 윈도에서 세션이 약 30분에서 약 3시간으로 늘어납니다.</p><h3>제공하는 핵심 도구</h3><ul><li>ctx<em>batch</em>execute. 한 번의 호출로 여러 명령을 실행하고, 모든 출력을 자동 색인한 뒤, 여러 쿼리로 검색합니다. 원시 데이터가 아니라 요약본을 돌려줍니다. 한 번의 호출이 개별 도구 호출 30개 이상을 대체합니다.</li><li>ctx_search. 세션에서 이미 색인된 무언가에 대해 BM25 후속 검색을 수행합니다.</li><li>ctx<em>execute / </em><em>ctx_execute</em>file. 샌드박스에서 코드와 분석을 실행합니다. 출력된 요약본만 컨텍스트에 들어옵니다.</li><li>ctx<em>fetch_and</em>index. URL을 가져와 색인하고 약 3KB짜리 미리보기를 돌려줍니다. 전체 콘텐츠는 검색할 수 있게 남습니다.</li><li>ctx_stats. 현재 세션의 토큰 절감 분석을 보여 줍니다.</li></ul><h3>통합하는 방법</h3><p>라이프사이클 이벤트 하나당 훅 하나(PreToolUse/PostToolUse/PreCompact/SessionStart)를 두고, 각각 context-mode hook claude-code &lt;event&gt;를 호출합니다. 전체 <a href="https://github.com/sgaabdu4/claude-code-tips/blob/main/settings/settings.json">settings.json</a>을 보세요.</p><p>팁. 테스트 러너(npm test, pytest, go test ./...)에 형제 PreToolUse 훅을 하나 더 달아서 Claude가 ctx<em>batch</em>execute를 쓰도록 경고하세요. 테스트 스위트 전체는 수천 줄의 출력을 만듭니다.</p><h3>레이어 3. RTK — Rust Token Killer (셸 출력에서 60–90% 절감)</h3><p>저장소: <a href="https://github.com/rtk-ai/rtk">github.com/rtk-ai/rtk</a></p><p><strong>무엇을 하는가</strong>. CLI 명령 출력을 가로채서 컨텍스트 윈도에 들어가기 전에 압축하는 Rust 바이너리입니다. 보일러플레이트를 제거하고, 비슷한 항목은 묶고, 긴 출력은 잘라내고, 중복 항목은 제거합니다. 단일 바이너리, 10ms 미만 오버헤드, 네트워크 호출 없음.</p><p><strong>실제 숫자</strong>.</p><p>명령 일반 토큰 RTK 적용 절감 cargo test (262개 테스트) 4,823 11 <strong>99%</strong> git diff HEAD~1 21,500 1,259 <strong>94%</strong> npm test 25,000 2,500 <strong>90%</strong> git add/commit/push 1,600 120 <strong>92%</strong></p><p>context-mode와 비교하면 겹치는 부분이 없습니다. context-mode는 큰 출력(20줄 초과)을 샌드박스 처리합니다. RTK는 작은-중간 크기의 셸 출력(git status, npm install, 간단한 테스트 결과)을 그 자리에서 압축합니다. RTK는 Headroom(다음 레이어) 안에 번들로 들어 있습니다.</p><h3>레이어 4. Headroom (API에 도달하는 모든 것에서 47–92% 절감)</h3><p>저장소: <a href="https://github.com/chopratejas/headroom">github.com/chopratejas/headroom</a></p><p><strong>무엇을 하는가</strong>. Claude Code와 Anthropic API 사이에 자리 잡습니다. <strong>전체 프롬프트</strong>(대화 기록, 시스템 프롬프트, 도구 출력 등 전부)를 머신을 떠나기 전에 압축합니다. 쓰이는 기술은 다음과 같습니다.</p><ul><li><strong>CodeCompressor</strong>. Python, JS, Go, Rust, Java, C++에 대한 AST 인지 압축</li><li><strong>SmartCrusher</strong>. JSON 배열/객체 압축</li><li><strong>Kompress-base</strong>. 에이전트 트레이스로 학습된 HuggingFace ML 모델</li><li><strong>CacheAligner</strong>. 프롬프트 프리픽스를 안정화해 Anthropic KV 캐시가 실제로 히트하게 함</li></ul><p><strong>이 도구만의 가치</strong>. 레이어 1–3은 컨텍스트 윈도에 <em>들어오는</em> 것을 줄입니다. Headroom은 컨텍스트 윈도를 <em>떠나는</em> 것을 압축합니다. 다른 도구는 손대지 않는 대화 기록, 시스템 프롬프트, CLAUDE.md 지시문까지 포함됩니다.</p><p><strong>보고된 절감은 다음과 같습니다</strong>.</p><p>작업 유형 절감 코드 검색 (결과 100개) <strong>92%</strong> SRE 인시던트 디버깅 <strong>92%</strong> 로그에서 바늘 찾기 <strong>87%</strong> GitHub 이슈 분류 <strong>73%</strong> 코드베이스 탐색 <strong>47%</strong></p><h3>설정. 셸 함수 하나</h3><pre># Bash/Zsh (Fish: wrap in `function claude ... end`)<br>claude() { command headroom wrap claude &quot;$@&quot;; }</pre><p>로컬 프록시를 띄우고, ANTHROPIC<em>BASE</em>URL을 설정한 다음, Claude를 띄웁니다. --resume, -p &quot;query&quot; 같은 모든 인자가 그대로 전달됩니다. RTK는 자동으로 등록됩니다.</p><h3>레이어 5. Caveman 플러그인 (Claude 자신의 출력에서 50–75% 절감)</h3><p>저장소: <a href="https://github.com/JuliusBrussee/caveman">github.com/JuliusBrussee/caveman</a></p><p>이 부분은 자주 간과됩니다. <strong>Claude 자신의 장황한 응답도 컨텍스트 윈도에 카운트됩니다</strong>. “물론이죠! 도와드릴 수 있어 기쁩니다. 겪고 계신 문제는 아마…” 같은 문장 하나하나가 낭비된 토큰입니다.</p><p>Caveman은 Claude가 압축된 스타일로 응답하게 만드는 Claude Code 플러그인입니다. 관사(a/the 같은 영어 장식어), 군더더기 단어, 우회 표현, 인사말을 떨어냅니다. 기술적 내용은 모두 남기고 군더더기만 죽입니다.</p><p><strong>Before</strong>. “물론이죠! 도와드릴 수 있어 기쁩니다. 겪고 계신 문제는 아마 인증 미들웨어에서 발생한 레이스 컨디션 때문일 가능성이 높습니다. 토큰 만료 검사가 less-than-or-equal이 아니라 strict less-than 비교를 쓰고 있거든요.”</p><p><strong>After</strong>. “인증 미들웨어 버그. 토큰 만료 검사 &lt;= 아닌 &lt; 씀. 고침:&quot;</p><h3>단순한 말투 이상입니다</h3><p>Caveman은 자동 훅과 서브-스킬을 함께 제공합니다.</p><ul><li>/caveman:compress. CLAUDE.md와 메모리 파일을 <strong>영구적으로</strong> caveman 형식으로 압축합니다. CLAUDE.md는 매번 컨텍스트에 로드되므로 앞으로 모든 세션 시작에서 토큰을 아낍니다. 절감이 곱셈으로 쌓이죠.</li><li>/caveman:caveman-commit. 압축된 커밋 메시지 생성기. 제목 50자 이하, 본문은 &quot;왜&quot;가 자명하지 않을 때만.</li><li>/caveman:caveman-review. 압축된 코드 리뷰 코멘트. 코멘트 하나가 한 줄. 위치, 문제, 해결.</li><li>/caveman-help. 모든 모드와 명령에 대한 빠른 참조.</li></ul><p><strong>압축 강도 단계</strong>. lite(부드러운 압축), full(클래식 caveman, 기본값), ultra(최대 압축).</p><h3>설치</h3><p>Caveman은 Claude Code 서드파티 플러그인 마켓플레이스로 설치합니다. settings.json의 enabledPlugins에서 활성화하고, extraKnownMarketplaces가 JuliusBrussee/caveman을 가리키게 합니다. 훅은 SessionStart와 UserPromptSubmit에서 자동 활성화됩니다. 전체 스니펫은 동반 <a href="https://github.com/sgaabdu4/claude-code-tips/blob/main/settings/settings.json">settings.json</a>에 있습니다.</p><h3>자동 핸드오프. 상태를 잃지 않고 컴팩션 살아남기</h3><p>긴 세션은 자동 컴팩트에 부딪힙니다. 진행 중이던 것은 요약되어 사라지고, 다음 턴은 Claude가 이미 읽은 파일들을 다시 탐색하기 일쑤죠. 해결책은 컴팩션이 실행되기 <em>전에</em> 구조화된 핸드오프 JSON을 합성하는 PreCompact 훅, 그리고 다음 세션에서 그 JSON을 자동으로 인라인해 주는 SessionStart 훅입니다.</p><h3>훅</h3><ul><li>~/.claude/hooks/handoff-precompact(PreCompact). stdin으로 transcript<em>path와 </em><em>cwd를 받아서, JSONL 트랜스크립트의 마지막 200KB와 엄격한 JSON 스키마 프롬프트로 </em><em>claude -p --bare --model claude-sonnet-4-6을 헤드리스 모드로 호출합니다. </em><em>&lt;cwd&gt;/docs/handoff-context.md를 작성합니다. 60초 타임아웃. </em><em>claude -p가 실패하거나 타임아웃되면 </em><em>HANDOFF_AUTO</em>PARTIAL 태그가 붙은 원시 트랜스크립트 꼬리 덤프로 폴백해서 복구 거리는 남깁니다. 컴팩트는 진행돼야 하므로 항상 exit 0.</li><li>~/.claude/hooks/handoff-session-resume(SessionStart, matcher: compact|resume). docs/handoff-context.md가 있으면 {hookSpecificOutput: {hookEventName: &quot;SessionStart&quot;, additionalContext: &quot;...&quot;}}를 내보내서 JSON을 새 세션의 컨텍스트에 곧바로 인라인합니다. Read 도구 왕복이 필요 없습니다.</li><li>~/.claude/commands/handoff.md(슬래시 명령). 같은 스키마, 원할 때마다 /handoff로 수동 트리거.</li></ul><h3>스키마 (10개 필드, 해당되는 경우 전부 필수)</h3><pre>{<br>  &quot;session_started&quot;: &quot;ISO8601&quot;,<br>  &quot;task&quot;: &quot;한 문장 — 전체 목표&quot;,<br>  &quot;completed_tasks&quot;: [&quot;구체적으로 끝난 것들&quot;],<br>  &quot;current_state&quot;: &quot;진행 중인 작업, 수정한 파일, 동작/고장 상태&quot;,<br>  &quot;constraintstopreserve&quot;: [&quot;사용자 규칙 그대로&quot;, &quot;배제한 접근법 + 이유&quot;],<br>  &quot;files_touched&quot;: [{&quot;path&quot;: &quot;...&quot;, &quot;status&quot;: &quot;created|modified|deleted&quot;, &quot;summary&quot;: &quot;...&quot;}],<br>  &quot;issues_discovered&quot;: [&quot;버그/함정 + 우회 방법&quot;],<br>  &quot;open_questions&quot;: [&quot;미결 결정들&quot;],<br>  &quot;nextsteps&quot;: [&quot;순서대로, 구체적으로. nextsteps[0] = 말 그대로 첫 동작&quot;],<br>  &quot;resume_prompt&quot;: &quot;사용자가 새 세션에 그대로 붙여 넣을 수 있는 한 문단&quot;<br>}</pre><p><strong>--bare를 쓰는 이유</strong>. claude -p의 <a href="https://code.claude.com/docs/en/cli-reference">--bare 플래그</a>는 훅, 스킬, 플러그인, MCP 서버, 자동 메모리, CLAUDE.md의 자동 디스커버리를 건너뜁니다. 자식 세션은 Bash와 파일 읽기/편집만 갖습니다. 중첩된 훅 캐스케이드 없음, CLAUDE.md 재로드 없음, 빠른 콜드 스타트. 훅 서브프로세스에 결정적입니다.</p><p><strong>Haiku 대신 Sonnet 4.6을 쓰는 이유</strong>. 핸드오프는 판이 큽니다. 다음 세션 품질이 떨어지면 전체 의미가 사라집니다. Sonnet은 제약 사항과 배제된 접근법의 뉘앙스를 잡아내는데, Haiku는 “X 했음, Y 할 것”처럼 평탄화하면서 <em>왜</em>를 잃어버리는 경향이 있습니다. 컴팩트는 긴 세션당 한 번 발동하므로 비용(몇 센트)은 반올림 오차 수준입니다.</p><p><strong>CLAUDE</strong><strong><em>AUTOCOMPACT_PCT</em></strong><strong>OVERRIDE=50과 함께 동작합니다</strong>. (기본값 약 95% 대신) 50%에서 컴팩트를 발동시키면, PreCompact 훅은 합성 작업을 할 여유를 늘 충분히 확보합니다. 95%였다면 아슬아슬했을 겁니다.</p><p><strong>주의할 점</strong>. 훅의 timeout 필드는 밀리초가 아니라 <strong>초</strong> 단위입니다(일부 커뮤니티 조언이 반대로 주장하지만, 실제 CLI 스키마에서 확인했습니다). &quot;timeout&quot;: 90000이 아니라 &quot;timeout&quot;: 90으로 설정하세요.</p><p><a href="https://github.com/sgaabdu4/claude-code-tips/tree/main/hooks">전체 훅 스크립트는 저장소에</a> 있습니다. 슬래시 명령은 <a href="https://github.com/sgaabdu4/claude-code-tips/blob/main/commands/handoff.md">commands/handoff.md</a>에 있습니다.</p><h3>보너스 훅. bash-ban-raw-tools</h3><p>CBM 게이트의 형제 격입니다. 문제는 이렇습니다. Claude가 Bash로 cat file.py나 grep &quot;pattern&quot; src/를 실행하면, 원시 출력이 모든 압축 훅을 우회합니다. Read와 Grep은 MCP + context-mode가 조절하지만, Bash는 컨텍스트로 직진합니다.</p><p>해결책. 원시 명령을 차단하고 Claude를 최적화된 도구로 몰아넣습니다.</p><p><a href="https://github.com/sgaabdu4/claude-code-tips/blob/main/hooks/bash-ban-raw-tools">전체 파일</a>을 보세요. 핵심은 다음과 같습니다.</p><pre>case &quot;$FIRST&quot; in<br>  cat|head|tail|find|grep|rg|wc) banned=1 ;;<br>  rtk) exit 0 ;; # RTK wrappers pass through<br>esac<br># Truncation pipes still flood context before the trim<br>if echo &quot;$CMD&quot; | grep -qE &#39;\|\s*(tail|head)\b&#39;; then<br>  echo &quot;BLOCKED pipe truncation.&quot; &gt;&amp;2; exit 2<br>fi</pre><p>탈출구. touch /tmp/bash-raw-unlock(10분 후 자동 만료).</p><h3>전체 settings.json</h3><p><a href="https://github.com/sgaabdu4/claude-code-tips/blob/main/settings/settings.json">전체 파일은 저장소에</a> 있습니다. 최상위 형태는 다음과 같습니다.</p><pre>{<br>  &quot;$schema&quot;: &quot;https://json.schemastore.org/claude-code-settings.json&quot;,<br>  &quot;env&quot;: {<br>    &quot;CLAUDEAUTOCOMPACT_PCTOVERRIDE&quot;: &quot;50&quot;,<br>    &quot;BASHMAX_OUTPUTLENGTH&quot;: &quot;10000&quot;,<br>    &quot;MAXMCP_OUTPUTTOKENS&quot;: &quot;10000&quot;,<br>    &quot;CLAUDECODE_DISABLE_BACKGROUNDTASKS&quot;: &quot;1&quot;,<br>    &quot;CLAUDECODE_EXPERIMENTAL_AGENTTEAMS&quot;: &quot;1&quot;,<br>    &quot;CLAUDECODE_SUBAGENTMODEL&quot;: &quot;claude-sonnet-4-6&quot;,<br>    &quot;ENABLEPROMPT_CACHING1H&quot;: &quot;1&quot;<br>  },<br>  &quot;permissions&quot;: { &quot;defaultMode&quot;: &quot;auto&quot; },<br>  &quot;model&quot;: &quot;claude-opus-4-7[1m]&quot;,<br>  &quot;effortLevel&quot;: &quot;high&quot;,<br>  &quot;advisorModel&quot;: &quot;opus&quot;,<br>  &quot;statusLine&quot;: { &quot;type&quot;: &quot;command&quot;, &quot;command&quot;: &quot;bash ~/.claude/statusline-command.sh&quot; },<br>  &quot;enabledPlugins&quot;: { &quot;caveman@caveman&quot;: true },<br>  &quot;hooks&quot;: {<br>    &quot;PreToolUse&quot;:  [ /* Bash → context-mode + bash-ban-raw-tools; Grep|Glob|Read → cbm-code-discovery-gate */ ],<br>    &quot;PostToolUse&quot;: [ /* context-mode + cbm-mcp-marker */ ],<br>    &quot;PreCompact&quot;:  [ /* context-mode + handoff-precompact (timeout: 90초) */ ],<br>    &quot;SessionStart&quot;:[ /* context-mode + handoff-session-resume (compact|resume 매칭) + cbm-session-reminder */ ]<br>  }<br>}</pre><h3>각 환경 변수의 역할</h3><p><strong>핵심</strong>.</p><ul><li>CLAUDE<em>AUTOCOMPACT_PCT</em>OVERRIDE=50. 컨텍스트 윈도의 50%(기본값 약 95% 대신)에서 컴팩션을 발동시킵니다. 자동 핸드오프 훅이 작업할 공간을 확보하고 프롬프트도 작게 유지합니다.</li><li>CLAUDE<em>CODE_SUBAGENT</em>MODEL=claude-sonnet-4-6. 위임된 서브에이전트를 Sonnet 4.6에 고정합니다(Opus보다 60% 저렴, 리서치/리팩터링/감사에는 충분히 똑똑합니다).</li><li>ENABLE<em>PROMPT_CACHING</em>1H=1. 프롬프트 캐시 TTL을 5분에서 1시간으로 늘립니다(긴 세션에서 비용을 크게 아낍니다). 전체 표는 다음과 같습니다.</li></ul><p>환경 변수 값 이유 CLAUDE<em>AUTOCOMPACT_PCT</em>OVERRIDE 70 기본값 대신 70%에서 컴팩트. 4개 압축 레이어 덕분에 여기까지 가는 일이 드뭅니다. ENABLE<em>PROMPT_CACHING</em>1H 1 프롬프트 캐시 TTL을 1시간으로 연장 (기본 5분). 긴 세션에서 큰 절감. BASH<em>MAX_OUTPUT</em>LENGTH 10000 Bash 출력 상한. context-mode와 RTK가 놓치는 것을 잡습니다. MAX<em>MCP_OUTPUT</em>TOKENS 10000 MCP 도구 출력에도 같은 상한. CLAUDE<em>CODE_DISABLE_BACKGROUND</em>TASKS 1 조용히 토큰을 태우는 백그라운드 작업을 차단. CLAUDE<em>CODE_EXPERIMENTAL_AGENT</em>TEAMS 1 작업 목록을 공유하는 병렬 특화 에이전트 활성화.</p><h3>기타 설정 설명</h3><ul><li>effortLevel: high. Opus 4.7 추론을 잠그지 않습니다(비용 민감 세션에서는 medium으로 내리세요. 4.7 기본값은 xhigh입니다).</li><li>advisorModel: opus. 내장 어드바이저 도구를 두 번째 의견용 최강 모델로 라우팅합니다. 서브에이전트는 환경 변수에서 claude-sonnet-4-6을 상속받고, 위험도 높은 작업(리팩터링, 다중 파일 영향, 감사)에서는 ~/.claude/agents/&lt;name&gt;.md 프론트매터의 model: claude-opus-4-7로 에이전트별로 오버라이드합니다. 전체 표는 다음과 같습니다.</li></ul><p>설정 값 이유 effortLevel medium 응답당 출력 토큰을 줄입니다. 아키텍처 결정 시에는 high로 올리세요. advisorModel opus 어려운 결정에 어드바이저 두 번째 의견을 받기 위한 최강 모델. defaultMode auto 권한 규칙에 맞는 도구 호출은 자동 수락. 왔다 갔다 하는 흐름을 차단합니다. skipDangerousModePermissionPrompt true --dangerously-skip-permissions 프롬프트 건너뛰기. skipAutoPermissionPrompt true auto 모드 프롬프트 건너뛰기.</p><h3>이 모든 것을 돌아가게 만드는 CLAUDE.md</h3><p>여러분의 CLAUDE.md는 <strong>세션 내</strong> 동작을 규정하는 지시문입니다. 외부 도구(Headroom, RTK)를 여기에 문서화하지 마세요. 이 도구들은 세션 바깥에서 작동하고 Claude는 볼 수 없습니다. Claude가 실제로 호출하는 도구에 대해서만 지시하세요.</p><p><a href="https://github.com/sgaabdu4/claude-code-tips/blob/main/CLAUDE.md.example">전체 파일은 저장소에</a> 있습니다. 핵심 섹션은 다음과 같습니다.</p><pre>## 원칙<br>DRY/KISS/YAGNI/SSOT. 추측 금지. 코드 먼저 읽기. 실패→접근 변경. 파괴적 작업 전 확인.<br> <br>## 구현 흐름 — 필수, 순서대로<br>단계 건너뛰면 → 중단, 건너뛴 단계부터 재시작.<br>1. **색인** — `indexstatus`. 미색인? `index_repository`. 색인됨? `detectchanges`.<br>2. **스킬 게이트** — 매칭되는 스킬을 모두 먼저 호출.<br>3. **명확화** — 모호하면? `AskUserQuestion`. 추측 금지.<br>4. **탐색** — CBM: `getarchitecture` → `search_graph` → `get_codesnippet`.<br>5. **계획** — 사소하지 않은 작업? `EnterPlanMode`.<br>6. **위임?** — 필수 기준 충족? 서브에이전트 생성. 1파일 편집 / 단일 grep만 인라인.<br>7. **파급** — 심볼 변경 → 모든 호출 지점에 `trace_path`.<br>8. **TDD** — red → 최소 코드 → green → 리팩터링.<br>9. **검증** — 린트 + 타입체크 + 테스트 통과.<br>10. **어드바이저** — 큰 작업 → 완료 전 `advisor()`.<br> <br>서브에이전트는 어떤 것도 자동 상속하지 않음. 에이전트 `.md`는 반드시 `skills:` 프론트매터 선언.<br> <br>## 스킬 게이트<br>Dart/Flutter → `building-flutter-apps` 먼저.<br>React/Next → `vercel-react-best-practices` 먼저.<br>Appwrite → `appwrite-backend` 먼저.<br>체크리스트: `.claude/rules/`.<br> <br>## 파급 검사. 타협 불가<br>어떤 추가/변경/삭제든 모든 사용처에 대해 심볼 grep + CBM `trace_path`. 모든 호출 지점 업데이트.<br> <br>## 도구. 퀵 레퍼런스<br>| 원하는 것 | 도구 |<br>|---|---|<br>| 정의 찾기 | `search_graph` |<br>| A→B 흐름 | `trace_path` |<br>| 아키텍처 | `get_architecture` |<br>| 스니펫 읽기 | `getcodesnippet` |<br>| 명령 실행 | `ctxexecute` / `ctx_batchexecute` |<br>| 로그/큰 파일 읽기 | `ctxexecutefile` |<br>| URL 가져오기 | `ctxfetch_and_index` → `ctxsearch` |<br> <br>## 금지된 Bash<br>`cat`/`head`/`tail`/`grep`/`find`.<br> <br>## 서브에이전트<br>위임이 기본. 메인 = 코디네이터.<br>- 필수 위임: 온라인 리서치, 2개 초과 파일 리팩터링, 1개 초과 파일 요약, 감사, 미지의 저장소 탐색, 다중 파일 영향, 큰 로그 분류.<br>- 건너뛰기: 1파일 읽기, 단일 grep, 알려진 단일 경로 편집. 인라인.<br>- 병렬 상한: 동시 3개. 의존이면 직렬.<br>- 타입: `general-purpose`(편집), `Plan`(읽기 전용 아키텍처), `Explore`(읽기 전용 탐색).<br>- 프롬프트: 자체 완결, 500 토큰 미만. 목표 + 컨텍스트 + 제약 + 반환 형식.<br>- 반환: &quot;200 단어 미만 보고&quot;.<br>- 모델: 환경 변수로 기본 sonnet. 리팩터링/감사/엣지케이스 사냥꾼/스태프 엔지니어는 에이전트 프론트매터에서 `model: claude-opus-4-7`로 오버라이드.<br>- 큰 작업 → 끝나면 어드바이저.<br> <br>## 핸드오프<br>PreCompact 훅이 `claude -p --bare`로 `docs/handoff-context.md`를 자동 작성. SessionStart 훅(compact|resume 매칭)이 파일을 자동 인라인. 수동 `/handoff`는 언제든.</pre><p>전체 파일은 스택별 스킬 게이트, 파급 체크, TDD 엣지 리스트, 서브에이전트 모델 전략, 자동 핸드오프 시스템, 응답 스타일 규칙까지 다룹니다.</p><h3>언어별 룰 파일</h3><p>.claude/rules/도 스택별 강제 적용에 씁니다. CLAUDE.md에서 @ import로 로드합니다. 스택 하나당 파일 하나. 각 파일에는 먼저 호출할 스킬과, Claude가 반복해서 밟는 함정 몇 가지를 번호 매긴 자체 점검 항목을 적습니다. 항목은 여러분이 실제로 겪은 실패에서 뽑으세요.</p><p>~/.claude/rules/flutter.md.</p><pre># Flutter/Dart 게이트. 타협 불가<br>`building-flutter-apps` 스킬을 먼저 호출. 생략 금지.<br>자체 점검 항목.<br>1. notifier의 모든 `await` 뒤에 `if (!ref.mounted) return;`<br>2. widget/State의 모든 `await` 뒤에 `if (!context.mounted) return;`. 단독 `mounted` 절대 금지. 린트 발동 → State에 `this.context`를 쓰는 sync 헬퍼 추출 (`BuildContext` 인자 없이)<br>3. `_buildXxx()` 금지. 위젯 클래스로 추출<br>4. 하드코드 문자열 금지. `*Strings` 상수<br>5. `ref.watch`는 build에서만, `ref.read`는 콜백에서만<br>6. Riverpod 3.x 코드젠: `FooNotifier` → `fooProvider`<br>7. ListView/GridView에 `shrinkWrap: true` 금지<br>반환 전 스킬 Pre-Flight 실행.</pre><p>~/.claude/rules/react.md.</p><pre># React/Next.js 게이트<br>`vercel-react-best-practices` 스킬을 먼저 호출.<br>자체 점검 항목.<br>1. 서버 컴포넌트가 기본. `&quot;use client&quot;`는 상호작용에만<br>2. 무거운 계산(`find()`/`filter()`/`sort()`/타임존/O(n) 스캔) → 안정적인 의존성으로 `useMemo`. `.map()` 콜백, JSX 어트리뷰트, 렌더 본문 안에서는 절대 금지<br>3. `enum` 금지 — `as const` 객체: `{ FOO: &#39;foo&#39; } as const`<br>4. 상태 변형 → 삼항 체인이 아니라 `Record&lt;Status, Variant&gt;` 맵</pre><p>~/.claude/rules/appwrite.md.</p><pre># Appwrite 게이트<br>어떤 Appwrite 코드(TablesDB/Auth/Storage/Functions/Realtime)든 `appwrite-backend` 스킬을 먼저 호출.<br> <br>## 백엔드 준수 검사<br>Appwrite 백엔드 리뷰 시 `api-designer` 에이전트 사용. 이 에이전트는 프로젝트 Appwrite MCP 도구를 보유.<br> <br>에이전트 필수 동작.<br>1. 모든 `Query.select([...])` 호출 grep<br>2. 필드 이름 추출<br>3. Appwrite CLI로 라이브 스키마 조회 (전체 명령 목록은 `appwrite-backend` 스킬 → `references/appwrite-cli.md` 참조. 예: `appwrite databases list-attributes --database-id &lt;id&gt; --table-id &lt;id&gt;`), 폴백으로 프로젝트 Appwrite MCP<br>4. 컬렉션 속성에 없는데 선택된 필드 플래그<br>5. 쿼리되는 필드에 누락된 인덱스 플래그<br>6. 종합 준수는 `appwrite-backend` 스킬로<br> <br>가드: 프로젝트가 Appwrite를 쓸 때만.</pre><p>여러분의 스택으로 갈아끼우세요. 요점은 실제로 출시하는 프레임워크 하나당 스킬 게이트가 걸린 룰 파일 하나입니다.</p><h3>커스텀 상태 줄</h3><p>색상 코드 대시보드. ctx/5h/7d 막대, 브랜치, 모델, 시간. statusLine.command를 <a href="https://github.com/sgaabdu4/claude-code-tips/blob/main/statusline/statusline-command.sh">statusline-command.sh</a>로 지정하세요.</p><pre>user in ~/project on  main │ ⬡ o4.7 │ ctx ████░░░░ 48% │ 5h ██░░░░░░ 23% │ 7d █░░░░░░░ 12% │ 09:59</pre><h3>결과</h3><p>헤드라인 숫자. 같은 200K 윈도에서 세션이 약 30분에서 3시간 이상으로 늘어납니다. 코드 탐색당 토큰은 약 400K에서 약 3.4K로 떨어집니다. 셸 출력은 원본의 10–40%, API 페이로드는 8–53%, Claude 자신의 응답 장황함은 25–50%에 안착합니다. 전체 before/after 표는 다음과 같습니다.</p><p>지표 Before After 세션 지속 시간 약 30분 <strong>3시간 이상</strong> 코드 탐색당 토큰 약 400K <strong>약 3.4K</strong> 자동 컴팩트 시 컨텍스트 100% <strong>70%</strong> (도달하는 일 드묾) 셸 출력 100% <strong>10–40%</strong> API 페이로드 100% <strong>8–53%</strong> 응답 장황함 100% <strong>25–50%</strong></p><p>레이어들은 곱셈으로 쌓입니다. 각 레이어가 이전 레이어가 놓친 부분을 잡아냅니다.</p><h3>설치</h3><pre>git clone https://github.com/sgaabdu4/claude-code-tips.git<br>cd claude-code-tips &amp;&amp; chmod +x install.sh &amp;&amp; ./install.sh</pre><p>Headroom(RTK 번들 포함), codebase-memory-mcp, context-mode, Caveman 플러그인, 모든 훅, 상태 줄, settings.json, 셸 래퍼(fish/bash/zsh)를 설치합니다. 기존 ~/.claude/settings.json은 먼저 백업합니다. 설치 후 모델, effortLevel, advisorModel을 취향껏 조정하세요.</p><h3>보너스. 이 환경이 열어 주는 워크플로우</h3><p>세션이 30분이 아니라 3시간이라면, 멀티모델 파이프라인이 한계에 부딪히지 않습니다. 제 파이프라인은 이렇습니다.</p><ul><li><strong>플랜</strong>. Claude Opus 4.7, 또는 /ultraplan으로 로컬에서 계속 작업하면서 클라우드 세션에 플래닝을 떠넘기기.</li><li><strong>구현</strong>. Claude Opus 4.7.</li><li><strong>리뷰 1라운드</strong>. /unleash 서브에이전트 스웜을 병렬로. 린트, 타입, 보안, 성능, DB 스키마 검사.</li><li><strong>리뷰 2라운드</strong>. 다른 똑똑한 모델로 크로스-모델 두 번째 의견. 저는 Codex(GPT-5.5)를 쓰는데, 벤더를 바꾸면 같은 패밀리 리뷰어가 놓치는 사각지대를 잡아내기 때문입니다. 다른 Claude나 Gemini도 잘 작동합니다.</li><li><strong>E2E</strong>. 같은 원칙. 브라우저를 모는 어떤 강력한 모델이든 됩니다. Codex + VS Code 통합 브라우저가 작동합니다. Claude도 <a href="https://github.com/vercel-labs/agent-browser">Agent Browser의 dogfood 스킬</a>로 잘 됩니다(모든 버튼을 클릭하고, 폼을 엣지 케이스로 테스트하고, 잠재적 버그를 찾으면 비디오를 녹화합니다). Flutter는 공식 Dart MCP + Flutter Driver로 LLM이 실제 디바이스를 엔드투엔드로 몰 수 있습니다.</li></ul><p>모델 선택, 솔직히 말해 교체 가능합니다. 플랜과 구현에는 Opus 4.7 high+가 제 선호지만, GPT-5.3+ Codex(high/xHigh)나 동급 Claude면 리뷰와 E2E에 잘 맞습니다. 크로스 벤더 리뷰가 같은 벤더 리뷰보다 더 잡습니다. 유일한 바닥은 “충분히 똑똑할 것”. Opus 출력물을 Haiku로 리뷰하지 마세요. 백그라운드 서브에이전트(리서치, 감사, 리팩터링)에는 CLAUDE<em>CODE_SUBAGENT</em>MODEL을 통한 Sonnet 4.6이 스위트 스폿입니다. Opus보다 60% 저렴하고, 충분히 똑똑하며, 고위험 작업을 위한 에이전트별 Opus 오버라이드도 가능합니다.</p><p>라이브 리서치를 위해 Tavily는 세션에 띄워 둡니다. 문서, 시그니처, 버전은 학습 데이터를 절대 믿지 마세요.</p><h3>그 외 효과 컸던 것들</h3><ul><li><strong>PostToolUse 훅의 거부 스캐너</strong>. 모든 편집이 구조 표준 스캔을 트리거합니다. 적발되면 곧바로 Claude에게 돌아가서 다음으로 넘어가기 전에 고치게 합니다. 구체적인 스택. TS/JS에는 커스텀 ESLint 규칙, 도메인 UI 패턴에는 node 정규식 스캐너, Dart에는 analysis_options.yaml로 연결한 Dart analyzer 플러그인, 그리고 <a href="https://github.com/typicode/husky">Husky</a> + <a href="https://github.com/lint-staged/lint-staged">lint-staged</a>로 pre-commit 게이트.</li><li><strong>MCP보다 CLI</strong>. Tavily와 Appwrite MCP 서버를 빼내고 그들의 CLI(tvly, appwrite)를 썼습니다. context-mode와 짝지으면 같은 기능에 컨텍스트 부풀림은 훨씬 적습니다.</li><li><strong>MCP 서버는 단 2개</strong>. codebase-memory-mcp와 context-mode. 나머지는 전부 CLI 아니면 훅.</li><li><strong>받아쓰기에 Fluid Voice</strong>(내부적으로 Parakeet/Nvidia 사용). 기본 받아쓰기를 이깁니다. 말하는 동안 AI가 편집해 주기 때문입니다.</li><li><strong>절감 측정</strong>. <a href="https://github.com/getagentseal/codeburn">Codeburn</a>은 Claude Code, Codex, Cursor에 걸친 세션별 토큰 비용을 보여 주는 TUI 대시보드입니다. 루프를 닫아 줍니다. 스택이 실제로 효과를 내고 있는지 알 수 있습니다.</li></ul><h3>마무리</h3><p>Claude에게 효율적으로 굴라고 <em>말하지</em> 마세요. 강제하세요. 낭비 패턴을 차단하는 훅이 CLAUDE.md 1000단어보다 강합니다. Claude는 가장 저항이 적은 길을 따라갑니다. 효율적인 길을 유일한 길로 만드세요.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=432e41806427" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[번역] Claude Code — MEMORY.md: 알아야 할 모든 것과 시작하는 법]]></title>
            <link>https://siosio3103.medium.com/%EB%B2%88%EC%97%AD-claude-code-memory-md-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-%EB%AA%A8%EB%93%A0-%EA%B2%83%EA%B3%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%B2%95-144ce3ce166c?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/144ce3ce166c</guid>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Tue, 05 May 2026 11:42:41 GMT</pubDate>
            <atom:updated>2026-05-05T11:42:41.750Z</atom:updated>
            <content:encoded><![CDATA[<blockquote><em>원문: </em><a href="https://levelup.gitconnected.com/claude-code-memory-md-everything-you-need-to-know-how-to-get-started-8ac99e161153?sk=ae626e60671c4aa99659f10f2ec76ce8"><em>https://levelup.gitconnected.com/claude-code-memory-md-everything-you-need-to-know-how-to-get-started-8ac99e161153?sk=ae626e60671c4aa99659f10f2ec76ce8</em></a></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/686/0*UTNW3FpFpeTuCF-v.jpeg" /></figure><p>이제 Claude Code에서 세션 컨텍스트를 잃을 걱정을 하지 않아도 됩니다. 새로 도입된 자동 메모리(auto-memory) 기능은 워크플로우에서 가장 성가셨던 부분 중 하나를 해결합니다. Claude Code를 써보신 분이라면 그 문제를 잘 아실 겁니다. 세션을 종료하고 다음 날 돌아오면 Claude는 처음부터 다시 시작합니다. 이전에 작업하던 지점으로 돌아가기 위해 같은 프로젝트 내용, 선호 사항, 결정 사항을 또다시 반복해서 알려줘야 합니다.</p><p>Anthropic이 이번에 Claude Code에 자동 메모리 기능을 도입했고, 그 목적은 단순합니다. 세션 간 인계를 훨씬 매끄럽게 만드는 것입니다. 이제 Claude는 여러분과 작업하는 동안 자체 메모리를 만들고 관리할 수 있습니다. 작업이 진행되는 동안 Claude는 빌드 명령어, 코딩 선호 사항, 아키텍처 선택, 함께 해결한 까다로운 버그 같은 프로젝트 관련 유용한 컨텍스트를 조용히 기록합니다.</p><p>새 세션을 열면 그 컨텍스트가 이미 준비되어 있어서, 처음부터 다시 시작하는 대신 멈췄던 지점에서 이어서 작업할 수 있습니다. 이 기능이 특히 흥미로운 점은 직접 관리하지 않아도 된다는 것입니다. Claude가 알아서 처리합니다.</p><p>대부분의 Claude Code 사용자는 Claude에게 지시를 내리는 데 사용되는 CLAUDE.md 파일에 이미 익숙합니다. 자동 메모리는 MEMORY.md라는 새 파일로 한 층을 더합니다. CLAUDE.md와 달리 이 파일은 Claude가 직접 작성하고 업데이트하며, 세션 전반에 걸친 일종의 스크래치패드(scratchpad) 역할을 합니다.</p><p>저는 실제 프로젝트에서 Claude Code의 새 자동 메모리를 테스트해보면서 Claude가 무엇을 기억하기로 선택하는지, 그 정보가 어디에 저장되는지, 새 세션으로 돌아왔을 때 얼마나 신뢰할 수 있는지 살펴봤습니다. 이 글에서는 자동 메모리가 어떻게 동작하는지 설명하고, CLAUDE.md와 MEMORY.md의 차이를 정리하며, 테스트 결과를 공유하고, 필요할 때 이 기능을 어떻게 제어할 수 있는지 보여드리겠습니다.</p><p>본격적으로 들어가기 전에 — 만약 Claude Code로 작업하면서 기본적인 프롬프팅을 넘어서고 싶다면, 제가 진행하는 실습 워크숍이 도움이 될 수도 있습니다. **<a href="https://www.tickettailor.com/events/todatabeyond/2123002">Building Agent Skills for Claude Code</a>**는 더 일관되고 반복 가능한 워크플로우를 만들어주는 재사용 가능한 <em>Skills</em>를 만드는 데 초점을 맞춘 실용적인 세션입니다.</p><h3>1. Claude Code의 자동 메모리는 어떻게 동작할까?</h3><p>자동 메모리는 Claude Code를 업데이트하면 곧바로 기본값으로 켜집니다. 별도로 설치하거나 설정할 것이 없습니다. 바로 동작하기 시작합니다. 세션 동안 Claude는 무엇이 일어나는지 조용히 지켜보면서 메모를 남깁니다. 어떤 내용을 향후 세션을 위해 저장할지는 Claude가 스스로 결정합니다.</p><p><strong>Claude가 저장하는 정보는 다음과 같은 종류입니다.</strong></p><ul><li>프로젝트 패턴 — 빌드 명령어, 테스트 워크플로우, 코드베이스의 구성 방식 등</li><li>디버깅 인사이트 — 까다로운 문제의 해결책, 특정 에러의 근본 원인 등</li><li>아키텍처 노트 — 중요한 파일, 모듈 간 관계, 핵심 추상화 등</li><li>사용자의 선호 사항 — 커뮤니케이션 스타일, 워크플로우 습관, 도구 선택 등</li></ul><p>핵심은 이 모든 것이 수동 입력에 의존하지 않는다는 점입니다. 무엇이 중요한지 Claude가 직접 판단하고 자동으로 기록합니다.</p><h3>자동 메모리는 어디에 저장될까?</h3><p>각 프로젝트는 자체 메모리 디렉터리를 가지며, 다음 위치에 저장됩니다.</p><pre>~/.claude/projects/&lt;project&gt;/memory/</pre><p>&lt;project&gt; 경로는 Git 저장소의 루트를 기준으로 하며, 같은 저장소 안의 모든 하위 디렉터리는 같은 메모리 위치를 공유한다는 뜻입니다.</p><p>Git worktree를 사용하는 경우, 각 worktree는 별도의 메모리 디렉터리를 가집니다.</p><p>Git 저장소 바깥에서 작업할 때는 Claude가 현재 작업 디렉터리를 대신 사용합니다.</p><p>해당 폴더 안에서는 보통 다음과 같은 구조를 보게 됩니다.</p><pre>~/.claude/projects/&lt;project&gt;/memory/<br>├── MEMORY.md           # 각 세션 시작 시 로드되는 메인 인덱스<br>├── debugging.md        # 디버깅 이력과 반복되는 이슈에 대한 노트<br>└── ...                 # Claude가 필요할 때 만드는 다른 주제 파일들</pre><p>MEMORY.md는 메인 진입점입니다. Claude가 저장한 모든 내용의 인덱스 역할을 하며, 각 세션이 시작될 때 자동으로 로드되는 유일한 메모리 파일입니다.</p><h3>200줄 제한 이해하기</h3><p>기억해야 할 중요한 점이 하나 있습니다. 새 세션이 시작될 때 Claude는 MEMORY.md의 처음 200줄까지만 시스템 프롬프트에 로드합니다.</p><p>MEMORY.md가 너무 길어지기 시작하면, Claude는 더 자세한 노트를 debugging.md나 api-conventions.md 같은 별도의 주제 파일로 옮기고, 메인 파일은 짧고 유용하게 유지하도록 되어 있습니다. 이런 추가 주제 파일들은 시작 시 로드되지 않습니다. Claude는 세션 중 해당 컨텍스트가 필요할 때만 이 파일들을 읽습니다.</p><p>따라서 워크플로우는 이렇게 됩니다.</p><ul><li>새 세션이 시작되고, MEMORY.md의 처음 200줄이 로드됩니다</li><li>Claude가 특정 디버깅 이력이 필요해지면 그때 debugging.md를 읽습니다</li><li>Claude가 새로운 무언가를 알게 되면 MEMORY.md나 주제 파일 중 하나를 업데이트합니다</li></ul><p>테스트하면서 한 가지 알게 된 점이 있습니다. 이 동작은 백그라운드 프로세스로 일어나지 않습니다. 처음에는 그렇게 예상했지만, 실제로는 세션 도중에 Claude가 메모리 디렉터리를 읽고 쓰는 것을 실시간으로 볼 수 있습니다.</p><h3>CLAUDE.md와 MEMORY.md의 차이는 무엇일까?</h3><p>많은 개발자가 같은 질문을 할 겁니다. CLAUDE.md가 이미 있는데 MEMORY.md가 왜 필요할까요? 정리해 보겠습니다.</p><p>CLAUDE.md는 항상 Claude Code의 일부였습니다. Claude가 따라줬으면 하는 지시 사항, 규칙, 선호 사항을 작성하는 파일입니다.</p><p>MEMORY.md는 다르게 동작합니다.</p><p>MEMORY.md는 직접 작성하지 않습니다. Claude가 만들고 자동으로 업데이트합니다.</p><p>가장 쉽게 이해하는 방법은 이렇습니다. CLAUDE.md는 사용자의 지시 사항을 위한 파일이고, MEMORY.md는 Claude의 자체 스크래치패드라는 점입니다. MEMORY.md 안에서 Claude는 함께 작업하며 알게 된 유용한 컨텍스트를 기록합니다.</p><ul><li>사용자의 선호 사항</li><li>반복되는 프로젝트 패턴</li><li>잘 동작했던 명령어</li><li>실패했던 명령어</li><li>이전 세션에서 얻은 유용한 노트</li></ul><p>중요한 점은 Claude가 이 내용을 시간을 들여 스스로 쌓아 간다는 것입니다. 사용자의 수동 입력이 필요하지 않습니다. 그러니 차이는 단순합니다.</p><ul><li>CLAUDE.md — <strong>사용자가 Claude에게 무엇을 할지 알려주는 곳</strong></li><li>MEMORY.md — <strong>Claude가 스스로를 위해 노트를 기록하는 곳</strong></li></ul><p>이 두 파일이 함께 세션 시작 시 Claude에게 더 풍부한 컨텍스트를 제공합니다.</p><p>한쪽은 Claude가 어떻게 행동하길 원하는지 알려주고, 다른 한쪽은 Claude가 프로젝트에 대해 이미 학습한 내용을 기억하도록 돕습니다.</p><h3>Claude Code 메모리 계층 구조 이해하기</h3><p>Claude Code는 CLAUDE.md와 MEMORY.md에만 의존하지 않습니다. 실제로는 계층화된 메모리 시스템으로 동작합니다. 각 계층은 지시 사항이 누구에게 적용되는지, 얼마나 광범위하게 사용되어야 하는지에 따라 서로 다른 역할을 합니다.</p><p>핵심 아이디어는 단순합니다. 더 구체적인 지시 사항이 더 광범위한 지시 사항보다 우선합니다.</p><p>이는 프로젝트 수준 CLAUDE.md가 사용자 수준의 전역 메모리보다 우선한다는 뜻입니다. 자동 메모리도 프로젝트 수준에서 동작하므로, 사용자 본인과 작업 중인 특정 프로젝트에 한정된 범위로 적용됩니다.</p><p>또 한 가지 유용한 점은 CLAUDE.local.md입니다. 이 파일은 자동으로 .gitignore에 추가되므로, 샌드박스 URL, 로컬 테스트 노트 등 팀과 공유할 필요가 없는 개인 로컬 설정을 두기에 좋은 곳입니다.</p><h3>Claude는 세션 시작 시 무엇을 로드할까?</h3><p>새 Claude Code 세션을 열면 Claude는 여러 계층에서 컨텍스트를 로드합니다.</p><p>보통 다음 항목이 포함됩니다.</p><ul><li>조직의 정책(존재하는 경우)</li><li>팀이 공유하는 지시 사항이 담긴 프로젝트 수준 CLAUDE.md</li><li>개인 ~/.claude/CLAUDE.md 선호 사항</li><li>Claude가 저장한 노트가 담긴 MEMORY.md의 처음 200줄</li></ul><p>따라서 첫 프롬프트를 작성하기도 전에 Claude는 이미 프로젝트 컨벤션, 사용자의 선호 사항, 그리고 이전 세션에서 학습한 컨텍스트를 어느 정도 파악하고 있습니다.</p><h3>Claude Code 자동 메모리 실전</h3><p>이제 자동 메모리를 실전에 투입해 보겠습니다. 처음부터 프로젝트를 만들면서 자동 메모리가 어떻게 동작하는지 확인해 봅니다.</p><h3>1. Claude Code 업데이트</h3><p>먼저 자동 메모리 기능을 사용할 수 있도록 최신 Claude Code 버전을 사용 중인지 확인해야 합니다.</p><pre>claude update</pre><p>그런 다음 현재 버전을 확인할 수 있는데, 2.1.76 이상이어야 합니다.</p><pre>claude --version</pre><h3>2. 테스트 프로젝트 설정</h3><p>이제 테스트 프로젝트를 만들고 그 폴더 안에서 git을 초기화해 봅시다.</p><pre>mkdir test-claude-memory &amp;&amp; cd test-claude-memory<br>git init</pre><p>여기서 git init을 실행하는 것이 중요합니다. Claude Code는 메모리가 저장될 위치를 결정할 때 Git 저장소 루트를 기준으로 하기 때문입니다. 그러니 프로젝트가 Git 저장소가 아니라면 이 프로젝트 수준 메모리 설정은 기대대로 동작하지 않습니다.</p><p>이제 이 테스트 프로젝트 안에서 Claude Code를 실행할 준비가 됐습니다.</p><pre>claude</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/0*l1VxWDWUzStxJO0w.png" /></figure><h3>3. Claude 메모리 시작하기</h3><p>자동 메모리는 단순히 세션을 열었다고 해서 파일을 만들지는 않습니다. Claude가 메모를 시작하려면 먼저 무언가 함께 작업할 필요가 있습니다. 저는 Claude Code에게 LangChain으로 RAG 파이프라인을 만들어 달라고 지시했습니다.</p><pre>Build a simple rag pipleine with langchain</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/444/0*Fz8UQ0q5UWxYezsr.png" /></figure><p>이제 /memory 명령어를 실행하면 자동 메모리가 켜져 있고 세 가지 메모리 옵션이 있는 것을 볼 수 있습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*xvNm2KUqNPT93P20.png" /></figure><h3>옵션 1: User Memory</h3><p>전역 ~/.claude/CLAUDE.md 파일을 시스템 편집기에서 바로 엽니다.</p><p>이 파일은 개인용 메모리 파일입니다. 어떤 프로젝트에서 작업하든 항상 따라다니는 지시 사항과 선호 사항이 담깁니다. 선호하는 코딩 스타일, 즐겨 쓰는 도구, 어떤 프로젝트에서든 Claude가 따랐으면 하는 일반적인 습관 같은 것들이 여기에 해당합니다.</p><p>이 파일은 사용자가 직접 관리합니다.</p><h3>옵션 2: Project Memory</h3><p>현재 프로젝트 안의 CLAUDE.md 파일을 엽니다.</p><p>이 파일은 프로젝트 공유 파일입니다. 코딩 표준, 아키텍처 결정, 팀 전체가 따르는 공통 워크플로우 같은 팀 수준의 컨텍스트가 보통 여기에 들어갑니다. 프로젝트가 소스 컨트롤로 관리된다면 이 파일을 커밋해서 팀 전원이 혜택을 받게 할 수 있습니다.</p><p>이 파일도 사용자가 작성하고 관리합니다. Claude는 읽기만 할 뿐, 업데이트하지는 않습니다.</p><h3>옵션 3: Open Auto-Memory Folder</h3><p>이 부분은 Claude가 관리합니다.</p><p>이 옵션을 선택하면 Claude가 자체 노트를 저장하는 메모리 디렉터리가 열립니다. MEMORY.md와 세션 전반에 걸쳐 만들어진 주제 파일들이 모두 여기에 있습니다. 이 글에서 계속 이야기해 온 그 폴더입니다.</p><p>Windows에서는 폴더가 항상 자동으로 열리지는 않습니다. 그런 경우에는 터미널에서 직접 이동할 수 있습니다.</p><pre>ls $env:USERPROFILE\.claude\projects\&lt;your-project-path&gt;\memory\</pre><h3>4. 자동 메모리 토글</h3><p>/memory 명령어를 입력하면 다음과 같이 표시됩니다.</p><pre>Auto-memory: on</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*UpBMMWmLv7oPRQH5.png" /></figure><p>여기에서 설정 파일을 건드리지 않고도 켜고 끌 수 있습니다. Auto-memory: on 줄에 멈춰서 엔터를 누르면 Auto-memory: off로 전환됩니다.</p><p>Claude가 기억하지 않았으면 하는 탐색적인 작업을 하려고 한다거나 일회성 세션을 돌릴 때, 이게 현재 프로젝트의 메모리를 가장 빠르게 멈추는 방법입니다.</p><p>새 프로젝트를 시작할 때마다 /memory 명령어를 실행해서, <em>토글이 켜져 있는지 확인하고 메모리가 쌓이기 전에 파일이 어디에 위치하는지 익혀 두는 것이 좋습니다.</em></p><h3>5. 콜드 세션에서 자동 메모리 테스트하기</h3><p>이제 Claude Code를 완전히 종료하고 같은 프로젝트에서 새 세션을 시작한 다음, 어떠한 컨텍스트도 없이 다음 메시지를 보내서 Claude의 메모리가 콜드 세션에서도 살아남는지 확인해 봅시다.</p><pre>What do you know about this project?</pre><p>Claude는 새 세션에서 메모리를 읽어 들이고 프로젝트에 대한 자세한 개요를 알려줍니다.</p><p>이 모든 내용은 이전 세션의 MEMORY.md에서 불러온 것입니다. 이게 바로 Claude Code 자동 메모리가 설계된 대로 동작하는 모습입니다.</p><h3>Claude 자동 메모리 제어하기</h3><p>자동 메모리는 기본적으로 활성화되어 있고, 대부분의 경우 그게 옳은 설정일 겁니다.</p><p>하지만 자동 메모리를 끄고 싶은 상황도 있습니다. Claude Code는 필요한 제어 수준에 따라 몇 가지 방법을 제공합니다.</p><h3>한 프로젝트에서만 자동 메모리 끄기</h3><p>특정 프로젝트 하나에서만 자동 메모리를 비활성화하고 싶다면, 해당 프로젝트의 설정 파일에 다음 설정을 추가합니다.</p><pre>// .claude/settings.json<br>{<br>  &quot;autoMemoryEnabled&quot;: false<br>}</pre><p>이렇게 하면 해당 프로젝트에서만 자동 메모리가 비활성화되고, 다른 모든 곳에서는 계속 활성 상태로 유지됩니다.</p><h3>전역으로 자동 메모리 끄기</h3><p>모든 프로젝트에서 자동 메모리를 비활성화하고 싶다면, 같은 설정을 사용자 수준 설정 파일에 추가합니다.</p><pre>// ~/.claude/settings.json<br>{<br>  &quot;autoMemoryEnabled&quot;: false<br>}</pre><p>이 변경은 전역으로 적용되므로 Claude는 모든 프로젝트에서 자동 메모리 사용을 멈추게 됩니다.</p><h3>CI 환경에서 강제로 끄기</h3><p>Claude Code를 CI 파이프라인이나 다른 관리 환경 안에서 실행 중이라면, 가장 안전한 방법은 환경 변수를 사용하는 것입니다.</p><pre>export CLAUDE_CODE_DISABLE_AUTO_MEMORY=1   # 강제로 끄기<br>export CLAUDE_CODE_DISABLE_AUTO_MEMORY=0   # 강제로 켜기</pre><p>이 변수는 /memory 토글과 settings.json에 설정된 내용을 모두 덮어씁니다.</p><p>CI 세션에서 Claude가 메모를 저장하는 것을 원치 않는 자동화 환경에서, 자동 메모리가 절대 실행되지 않도록 보장하는 가장 확실한 방법입니다.</p><h3>메모리 파일 편집하기</h3><p>메모리 파일은 그저 마크다운 파일이므로, 원할 때 언제든 열어서 편집할 수 있습니다.</p><p>가장 쉬운 방법은 Claude Code 안에서 /memory 명령어를 사용하는 것입니다. 메모리 파일 선택기가 열리고, 시스템 편집기에서 원하는 메모리 파일로 바로 이동할 수 있습니다.</p><p>오래된 메모를 제거하거나, 더 이상 의미 없는 항목을 정리하거나, 프로젝트가 변하면서 메모리를 재구성하고 싶을 때 유용합니다.</p><p>터미널에서 파일을 직접 열 수도 있습니다.</p><pre>open ~/.claude/projects/&lt;your-project&gt;/memory/MEMORY.md</pre><h3>도움이 되었고 더 깊이 알고 싶다면, 라이브 워크숍을 진행 중입니다</h3><p><a href="https://buytickets.at/todatabeyond/2123002"><strong>Building Agent Skills for Claude Code</strong></a></p><p>이 워크숍은 <strong>1.5시간 동안 진행되는 실습 세션</strong>으로, 이론을 넘어 아이디어 → 설계 → 구현 → 테스트 단계를 거치며 함께 <em>Skills</em>를 만들어 봅니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=144ce3ce166c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[당신의 CLAUDE.md는 아마 잘못되었을 겁니다 — Boris Cherny가 절대 하지 않는 7가지 실수]]></title>
            <link>https://siosio3103.medium.com/%EB%8B%B9%EC%8B%A0%EC%9D%98-claude-md%EB%8A%94-%EC%95%84%EB%A7%88-%EC%9E%98%EB%AA%BB%EB%90%98%EC%97%88%EC%9D%84-%EA%B2%81%EB%8B%88%EB%8B%A4-boris-cherny%EA%B0%80-%EC%A0%88%EB%8C%80-%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94-7%EA%B0%80%EC%A7%80-%EC%8B%A4%EC%88%98-f2201efd098b?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/f2201efd098b</guid>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Sun, 22 Mar 2026 08:07:14 GMT</pubDate>
            <atom:updated>2026-03-22T08:07:14.591Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>원문: <a href="https://alirezarezvani.medium.com/your-claude-md-is-probably-wrong-7-mistakes-boris-cherny-never-makes-6d3e5e41f4b7">https://alirezarezvani.medium.com/your-claude-md-is-probably-wrong-7-mistakes-boris-cherny-never-makes-6d3e5e41f4b7</a></blockquote><p><em>Boris Cherny의 파일은 2.5k 토큰입니다. 제 것은 15k였습니다. 그의 워크플로를 3주간 연구한 끝에, 대부분의 개발자가 놓치는 패턴과 그것을 빠르게 바로잡는 방법을 발견했습니다.</em></p><p>제 CLAUDE.md는 847줄이었습니다. 저는 이 파일이 자랑스러웠습니다. 모든 엣지 케이스가 문서화되어 있고, 모든 컨벤션이 명시되어 있으며, 모든 팀 선호 사항이 꼼꼼하게 기록되어 있었으니까요.</p><p><em>그러다 Claude Code를 만든 Boris Cherny의 파일을 봤습니다.</em>.</p><p>그의 파일은 겨우 100줄에 불과했습니다. 제 파일은 8배나 길면서 더 나쁜 결과를 내고 있었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*6iSWTAvHk5V6FEre.png" /></figure><p><em>참고: AI 도구가 리서치와 편집에 도움을 주었습니다. 테스트, 재구성, 실제 사례는 모두 제 실제 워크플로에서 가져왔습니다.</em></p><p>3주 동안 Boris가 공유한 워크플로를 연구했습니다. 모두가 다룬 터미널을 넘나 들며 실행하는 5개의 병렬 세션과 같은 화려한 내용보다는, 그의 팀이 실제로 CLAUDE.md를 어떻게 구성하는지 집중했습니다.</p><p>발견한 사실이 있습니다. 대부분이 같은 실수를 하고 있었습니다. 그리고 해결책은 복잡하지 않습니다.</p><h3>인터넷을 뒤흔든 워크플로</h3><p>2026년 1월 초, Anthropic의 스태프 엔지니어이자 Claude Code 개발자인 Boris Cherny가 X에 자신의 개발 환경에 관한 스레드를 올렸습니다. 가벼운 터미널 시연으로 시작한 것이 그 해 가장 많이 분석된 개발자 워크플로가 되었습니다.</p><p>Jeff Tang은 “Claude Code 만든 사람이 직접 공유한 모범 사례를 읽지 않고 있다면, 프로그래머로서 뒤처지고 있는 겁니다”라고 썼습니다. Kyle McNease는 이를 Anthropic의 “ChatGPT 모먼트”라고 불렀습니다.</p><p>하지만 대부분의 보도가 놓친 부분이 있습니다.</p><p>바이럴이 된 부분은 병렬 세션과 시스템 알림이었습니다. 정작 중요한 것은 스레드 속에 묻혀 있던 한 줄이었습니다.</p><blockquote>“제 설정은 놀라울 정도로 평범할 수 있어요! Claude Code는 기본 상태로도 잘 작동하기 때문에, 저는 개인적으로 많이 커스터마이징하지 않습니다.”</blockquote><p><em>그의 팀의 CLAUDE.md는 어떨까요?</em> 2.5k 토큰짜리 파일 하나가 git에 포함되어 있고, 팀 전체가 여기에 기여합니다. 그게 전부입니다.</p><p>정교한 설정도 없고, 50페이지짜리 선언문도 없습니다. 모든 줄이 제 역할을 하는, 집중된 파일일 뿐입니다.</p><p>우리 대부분은 정확히 그가 피하는 것을 하고 있습니다.</p><h3>7가지 안티 패턴(Anti-Pattern)</h3><h3>1. 컨텍스트 쑤셔 넣기 함정</h3><p><strong>대부분의 개발자가 하는 것.</strong> 모든 엣지 케이스, 모든 과거 결정, 모든 “혹시 모르니까” 지시사항을 등 모든 것을 AGENTS.md에 넣습니다. 심한경우 10,000 토큰이 넘는 파일도 본 적 있습니다.</p><p><strong>Boris가 하는 것.</strong> 총 2.5k 토큰의 간결하고 집중된 파일입니다.</p><p><strong>왜 중요한가.</strong> 컨텍스트 부패(context rot)는 실제로 일어나기 때문입니다. NoLiMa 벤치마크에 따르면, 32,000 토큰에서 테스트된 12개 모델 중 11개가 회상 작업 정확도 50% 아래로 떨어졌습니다. CLAUDE.md는 <em>모든</em> 대화 시작 시 로드됩니다. 비대한 파일은 질문을 하기도 전에 토큰을 소모합니다.</p><p>해결책은 민망할 정도로 간단합니다.</p><pre># 나쁨 (장황함)<br>&quot;When implementing authentication, always ensure you follow<br>security best practices including input validation, proper<br>error handling, secure token storage, and following our<br>established patterns in the auth/ directory...&quot;<br> <br># 좋음 (간결함)<br>&quot;Auth: validate inputs, handle errors securely, follow auth/ patterns&quot;</pre><p>같은 정보인데, 토큰 수는 80% 줄었습니다.</p><p>CLAUDE.md를 847줄에서 127줄로 줄였습니다. 토큰 오버헤드가 ~15,000에서 ~2,400으로 떨어졌습니다. 세션이 더 빠르게 시작되었고, Claude가 대화 중간에 지시사항을 <em>“까먹는”</em> 일이 사라졌습니다.</p><h3>2. 정적 메모리 문제</h3><p><strong>대부분의 개발자가 하는 것.</strong> 프로젝트 설정 시 CLAUDE.md를 한 번 만들고 다시는 손대지 않습니다.</p><p><strong>Boris가 하는 것.</strong> 동료의 PR에 @.claude 태그를 사용하여 배운 점을 추가합니다. 파일은 코드 리뷰가 진행될 때마다 발전합니다.</p><p><strong>왜 중요한가.</strong> 코드베이스는 변합니다. 정적인 지시사항은 금방 낡아버립니다. 더 나쁜 건, Claude가 실수에서 배우지 못해 같은 실수가 반복된다는 것입니다.</p><p>지난달, 제 팀에서 같은 TypeScript strict mode 위반이 4개의 별도 PR에서 지적되었습니다. 매번 리뷰어가 같은 수정을 제안했습니다. 이 패턴은 첫 번째 발생 이후 CLAUDE.md에 들어갔어야 했습니다.</p><p><strong>해결책.</strong></p><ul><li>PR 리뷰에서 배운 점이 쌓이는 <em>“Learnings”</em> 섹션을 추가합니다</li><li>세션 중 # 단축키를 사용하여 즉시 업데이트합니다 (# Always use named exports for utilities라고 입력하면 메모리에 추가됩니다)</li><li>매달 CLAUDE.md 점검합니다. 오래된 것은 삭제하고, 빠진 것은 추가합니다</li></ul><p>CLAUDE.md는 살아있는 문서여야 합니다. 타임캡슐이 아닙니다.</p><h3>3. 혼자만의 설정</h3><p><strong>대부분의 개발자가 하는 것.</strong> CLAUDE.md를 개인 파일로 유지합니다. .gitignore에 넣기도 합니다.</p><p><strong>Boris가 하는 것.</strong> <em>“Anthropic은 각 팀이 CLAUDE.md를 git에 두고 관리합니다.”</em></p><p><strong>왜 중요한가.</strong> 팀원마다 Claude 동작이 달라집니다. 새 개발자를 온보딩하면 컨텍스트를 처음부터 다시 구축해야 합니다. 한 사람이 발견한 모범 사례가 전파되지 않습니다.</p><p>주니어 엔지니어가 테스트 설정을 디버깅하느라 2시간을 보내는 걸 목격했습니다. 시니어 세 명은 이미 그 설정이 망가졌다는 걸 알고 있었습니다. 우회 방법은 존재했습니다. 누군가의 개인 Claude 설정 속에 말입니다. 공유되지 않았습니다. 발견할 수도 없었습니다.</p><p><strong>해결책.</strong></p><pre>project-root/<br>├── CLAUDE.md           # 공유, Git에 커밋<br>├── CLAUDE.local.md     # 개인 선호 사항, .gitignore<br>└── .claude/<br>    └── commands/       # 팀 슬래시 커맨드</pre><p><strong>팀 관행을 만드세요.</strong> CLAUDE.md 업데이트는 PR 프로세스의 일부여야 합니다. 함정을 발견했나요? 문서화하세요. 반복되는 문제를 고쳤나요? 패턴을 추가하세요.</p><h3>4. Plan 모드 건너뛰기</h3><p><strong>대부분의 개발자가 하는 것.</strong> 바로 자동 수락 편집 모드로 뛰어듭니다. Claude가 즉시 코드를 작성하게 합니다.</p><p><strong>Boris가 하는 것.</strong> “Pull Request를 작성하는 게 목표라면, Plan 모드를 사용하고 마음에 들 때까지 Claude와 계획을 주고받습니다. 거기서 자동 수락 편집 모드로 전환하면 Claude가 보통 한 번에 끝냅니다.”</p><p><strong>이것이 왜 중요한가.</strong> 계획 없이 자동 수락을 하면 잘못된 방향에 컨텍스트를 낭비하게 됩니다. 15개 파일이 변경된 후에야 아키텍처가 잘못되었다는 걸 깨닫고 처음부터 다시 시작해야 합니다.</p><p>계획을 세우면 수정 비용이 적을 때 실수를 잡아낼 수 있습니다.</p><p><strong>해결책.</strong></p><ul><li>Plan 모드를 기본으로 설정합니다 (Shift+Tab 두 번)</li><li>계획이 본인의 멘탈 모델과 일치할 때까지 반복합니다</li><li>그때서야 자동 수락으로 전환합니다</li><li>CLAUDE.md에 계획 수립 지시사항을 추가합니다</li></ul><pre>## Workflow<br>- Start complex tasks in Plan mode<br>- Get plan approval before implementation<br>- Break large changes into reviewable chunks</pre><h3>5. 검증 루프 부재</h3><p><strong>대부분의 개발자가 하는 것.</strong> Claude가 코드를 작성하면, 대충 눈으로 확인하고 배포합니다.</p><p><strong>Boris가 하는 것.</strong> “아마 Claude Code에서 훌륭한 결과를 얻기 위해 가장 중요한 것은 Claude에게 자신의 작업을 검증할 방법을 주는 것입니다.”</p><p>과장이 아닙니다. Claude Code 자체도 Claude가 테스트합니다. 브라우저 자동화를 사용해 UI를 테스트하고, 코드가 작동하고 UX가 만족스러울 때까지 반복합니다.</p><p><strong>왜 중요한가.</strong> Boris에 따르면 검증은 최종 품질을 <em>“2~3배”</em> 향상시킵니다. 검증이 없으면 Claude는 코드가 작동하는지 추측합니다. 검증 단계가 있으면 Claude는 코드가 실제로 동작하는지 확인할 수 있습니다.</p><p><strong>해결책.</strong> <strong>CLAUDE.md에 검증 요구사항을 추가하세요.</strong></p><pre>## Verification Requirements<br>- Run `npm test` after code changes<br>- Run `npm run typecheck` before marking complete<br>- For API changes, test with `curl` or Postman<br>- For UI changes, verify in browser before committing</pre><p>그러면 Claude가 실제로 이 검사를 실행합니다. 프롬프트에서 지시했기 때문이 아니라, 프로젝트 컨텍스트에 내장되어 있기 때문입니다.</p><h3>6. 위험한 권한 지름길</h3><p><strong>대부분의 개발자가 하는 것.</strong> 권한 프롬프트가 귀찮다는 이유로 --dangerously-skip-permissions를 사용합니다.</p><p><strong>Boris가 하는 것.</strong> “대신 <em>/permissions를 사용하여 일반적으로 안전한 명령을 미리 허용하고, 이를 팀 전체에 공유합니다.&quot;</em></p><p><strong>왜 중요한가.</strong> 권한 확인을 건너뛰면 모든 가드레일이 사라집니다. 잘못된 명령 하나로 데이터베이스가 날아간 이유를 디버깅하게 될 수 있습니다. Boris는 권한을 팀 자산으로 취급합니다. 공유하고, 리뷰하고, 버전 관리합니다.</p><p>그의 철학입니다. “자동으로 넘어가도 후회하지 않을 경계를 설계하세요.”</p><p><strong>해결책.</strong></p><pre># --dangerously-skip-permissions 대신 /permissions로 허용하세요<br>npm run test:*<br>npm run build:*<br>git commit:*<br>git push:*<br>bun run format</pre><p>안전한 것은 미리 허용하세요. 나머지는 가드레일을 유지하세요. 위험 모드는 장시간 자율 작업을 위한 샌드박스 환경에서만 사용하세요.</p><h3>7. 포맷 드리프트(Format Drift)</h3><p><strong>대부분의 개발자가 하는 것.</strong> 자동 포매팅이 없습니다. AI가 만든 파일마다 코드 스타일이 제각각이고, 린팅 문제로 CI가 깨집니다.</p><p><strong>Boris가 하는 것.</strong> 매번 편집 후 자동 포매팅하는 PostToolUse 훅을 사용합니다.</p><p><strong>왜 중요한가.</strong> Claude의 코드는 보통 잘 포매팅되어 있지만, 불일치가 생기곤 합니다. 수동 포매팅은 흐름을 끊습니다. 포매팅 규칙 때문에 CI가 실패하는 것만큼 기세를 꺾는 것도 없습니다.</p><p><strong>해결책.</strong> PostToolUse 훅을 추가하세요.</p><pre>{<br>  &quot;hooks&quot;: {<br>    &quot;PostToolUse&quot;: [{<br>      &quot;matcher&quot;: &quot;Write|Edit&quot;,<br>      &quot;hooks&quot;: [{<br>        &quot;type&quot;: &quot;command&quot;,<br>        &quot;command&quot;: &quot;npm run format || true&quot;<br>      }]<br>    }]<br>  }<br>}</pre><p>이제 Claude가 건드리는 모든 파일이 자동 포매팅됩니다. || true는 포맷 오류가 세션을 차단하는 것을 방지합니다.</p><h3>제가 바꾼 것</h3><p>제 CLAUDE.md 변환 과정입니다.</p><p><strong>변경 전 (발췌)</strong></p><pre>## Authentication Guidelines<br> <br>When working on authentication-related code, please ensure that<br>you follow our established security practices. This includes but<br>is not limited to: validating all user inputs before processing,<br>implementing proper error handling that doesn&#39;t leak sensitive<br>information, using secure token storage mechanisms as defined in<br>our security documentation located in /docs/security/...<br>[continued for 40 more lines on auth alone]</pre><p><strong>변경 후 (발췌)</strong></p><pre>## Auth<br>- Validate inputs, sanitize outputs<br>- Errors: no sensitive data in messages<br>- Tokens: use /lib/auth/tokenStore<br>- See /docs/security for edge cases</pre><p>같은 가이드인데도 토큰 수는 90% 줄었습니다.</p><p><strong>3주 후 결과입니다.</strong></p><p>지표 변경 전 변경 후 CLAUDE.md 토큰 ~15,000 ~2,400 주당 “Claude가 까먹은” 횟수 4–5 1–2 기여하는 팀원 수 1명 (저) 4명 재구성 소요 시간 — 3시간</p><p>복리 효과가 가장 중요합니다. 이제 모든 PR이 CLAUDE.md를 개선할 기회를 갖습니다. 파일이 그저 길어지는 대신 시간이 지남에 따라 더 똑똑해집니다.</p><h3>아직 파악 중인 것들</h3><p>깔끔하게 끝난 성공 스토리는 아닙니다. 아직도 해결해야 할 어려움이 남아 있습니다.</p><p><strong>팀 도입 마찰.</strong> 모든 사람이 CLAUDE.md에 기여하게 만드는 데는 문화 변화가 필요합니다. 7명의 엔지니어 중 2명이 적극적으로 업데이트합니다. 2명은 읽기만 합니다. 3명은 온보딩 이후 열어본 적이 없습니다.</p><p><strong>복잡한 시스템 검증.</strong> “테스트를 돌려라”는 단위 테스트에는 통합니다. “이 분산 시스템이 네트워크 파티션을 올바르게 처리하는지 검증하라”에는 통하지 않습니다. 일부는 여전히 사람의 판단이 필요합니다.</p><p><strong>10~20% 실패율.</strong> Boris도 Claude Code 세션의 10~20%를 아무 성과 없이 중단한다고 인정합니다. 정상입니다. 언제 포기할지 아는 것도 기술입니다.</p><p><strong>대규모 컨텍스트 관리.</strong> 2.5k 토큰도 세션이 많아지면 부담이 누적됩니다. 대규모 리팩터링 날에는 여전히 컨텍스트 한계에 부딪힙니다. 간결한 CLAUDE.md가 도움은 되지만, 근본적인 제약을 해결해 주지는 않습니다.</p><h3>진짜 생산성 향상</h3><p>무엇이 바뀌었고 무엇이 바뀌지 않았는지 솔직하게 말씀드리겠습니다.</p><p><strong>실제로 개선된 것.</strong></p><ul><li>팀 전반의 일관성</li><li>반복되는 실수 감소</li><li>더 빠른 온보딩 (새 개발자가 컨텍스트를 물려받음)</li><li>“Claude가 왜 저렇게 했지?” 디버깅 감소</li></ul><p><strong>크게 변하지 않은 것.</strong></p><ul><li>순수 코딩 속도 (Claude는 이미 빨랐음)</li><li>개별 결과물의 품질 (설정보다 모델이 더 중요함)</li></ul><p>진짜 가치는 학습 효과가 복리처럼 쌓인다는 데 있습니다.</p><p>PR을 올릴 때마다 CLAUDE.md가 더 똑똑해집니다. 팀원의 발견이 공유 지식이 됩니다. 시간이 지나면서 “Claude가 우리 코드베이스를 이해한다”와 “Claude가 추측하고 있다” 사이의 격차가 벌어집니다.</p><p>Boris의 워크플로는 마법이 아닙니다. 규율입니다.</p><p>파일이 작은 이유는 모든 줄이 제 역할을 해내기 때문입니다. 팀이 기여하는 이유는 시스템이 기여에 보상하기 때문입니다. 검증 루프가 존재하는 이유는 고장 난 코드를 배포하는 비용이 크기 때문입니다.</p><p>어려운 일은 없습니다. 다만 의식적으로 그렇게 해야 할 뿐입니다.</p><p>✨ 유용했다면, 더 실용적인 Claude Code 인사이트를 받아보려면 구독해 주세요.</p><p>당신의 CLAUDE.md에는 무엇이 있나요? 토큰 수를 댓글에 남겨주세요. 2.5k 벤치마크와 비교하면 어떤지 궁금합니다.</p><h3>저자 소개</h3><p>저는 Alireza Rezvani(Reza)이며, 엔지니어링 팀을 위한 AI 개발 시스템을 구축하는 CTO입니다. 실용적 자동화를 통해 개인의 전문성을 집단 인프라로 전환하는 주제를 다루고 있습니다.</p><p><strong>연결</strong> <a href="https://rezaverse.com/">웹사이트</a> | <a href="https://linkedin.com/in/AlirezaRezvani">LinkedIn</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f2201efd098b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[클로드 스킬을 안정적으로 불러오는 방법]]></title>
            <link>https://siosio3103.medium.com/%ED%81%B4%EB%A1%9C%EB%93%9C-%EC%8A%A4%ED%82%AC%EC%9D%84-%EC%95%88%EC%A0%95%EC%A0%81%EC%9C%BC%EB%A1%9C-%EB%B6%88%EB%9F%AC%EC%98%A4%EB%8A%94-%EB%B0%A9%EB%B2%95-a68ea430d044?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/a68ea430d044</guid>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Sun, 15 Feb 2026 09:07:03 GMT</pubDate>
            <atom:updated>2026-02-15T09:29:01.464Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>원문: <a href="https://scottspence.com/posts/how-to-make-claude-code-skills-activate-reliably">https://scottspence.com/posts/how-to-make-claude-code-skills-activate-reliably</a></blockquote><p>클로드 코드 스킬이 동전 던지기와 비슷하다는 <a href="https://scottspence.com/posts/claude-code-skills-dont-auto-activate">이전 블로그 글</a>을 기억하시나요? 당시 소개한 “간단한 훅”을 사용한 방법은 성공률이 50%에 불과했고, 그래서 “그냥 직접 실행해라”라고 결론을 내렸습니다.</p><p>그러나 그 결과가 마음에 들지 않았습니다. 동전 던지기는 어떤 음식을 시킬지 정할 때나 쓰는 거지, 내가 쓰는 개발 도구의 작동 여부를 운에 맡길 순 없잖아요. 그래서 어느 개발자들이 그렇듯 주말 동안 테스트 프레임워크를 만들었고, 다양한 프롬프트 유형에 대해 200번 이상의 테스트를 거치면서, 어떻게 해야 클로드가 스킬을 잘 불러올 수 있는지 파고들었습니다.</p><p>그 결과 50%의 동전 던지기 게임에서 <strong>80~84% 까지 성공률</strong>을 끌어올리는 두 가지 방법을 알아냈습니다. 완벽하진 않아도 이전보다는 훨씬 나아졌습니다.</p><h3>문제</h3><p>클로드 코드의 스킬은 각 설명에 따라 자율적으로 활성화되어야 합니다. 공식 문서에도 클로드가 “사용자의 요청에 근거해 스킬 사용 여부를 스스로 판단한다”라고 명시되어 있죠.</p><p>하지만 현실은 어떨까요? 어림도 없습니다. 클로드는 스킬의 존재를 보란 듯이 무시한 채 제 할 일만 하기 바쁘고, 스킬들은 그저 멍하니 자리만 지키고 있을 뿐입니다.</p><p>제가 처음 내놓은 ‘해결책’은 “지침: 프롬프트가 특정 스킬의 키워드와 일치하면 해당 스킬(Skill-name)을 실행하라”는 식의 간단한 훅을 넣어두는 것이었습니다. 이렇게 하니 활성화율이 50% 정도 나왔습니다. 안 하는 것보다는 낫지만, 결국 앞서 말한 ‘동전 던지기’랑 다름없었습니다.</p><h3>제대로 된 테스트 환경 구축하기</h3><p>자, 이제 앉아서 불평만 하는 대신 제대로 된 수치로 증명해 볼 차례입니다. 저는 아래와 같은 테스트 프레임워크를 직접 만들었습니다.</p><ul><li>결과 추적 및 기록을 위한 SQLite 데이터베이스</li><li>검증을 위한 다양한 훅 설정</li><li>합성 API 호출 방식과 수동(실제 Claude Code) 테스트 병행</li><li>성공률, 지연 시간, 비용 등 정교한 지표 측정</li></ul><p>전체 설정은 <a href="https://github.com/spences10/svelte-claude-skills">svelte-claude-skills</a> 레포에 올려뒀으니 참고하세요.</p><h3>테스트에 사용된 스킬들</h3><p>SvelteKit 개발을 위해 특정 도메인을 커버하는 4개의 Claude Code 스킬을 제작했습니다.</p><ol><li><strong>svelte5-runes</strong> — Svelte 5의 룬즈 시스템($state, $derived, $effect, $props, $bindable) 가이드 및 Svelte 4에서의 마이그레이션 방법</li><li><strong>sveltekit-data-flow</strong> — 데이터 로딩 패턴, 폼 액션, 서버 vs 유니버설 로드 함수, fail(), redirect(), 그리고 직렬화 규칙</li><li><strong>sveltekit-structure</strong> — 파일 기반 라우팅, 레이아웃, 에러 바운더리, SSR/하이드레이션, 파일 네이밍 컨벤션</li><li><strong>sveltekit-remote-functions</strong> — 타입 안전한 서버 호출을 위한 query() 및 command() 기반의 원격 함수 패턴</li></ol><p>원래 각 스킬에는 상세 설명이 포함되어 있어, 클로드는 이를 바탕으로 언제 스킬을 활성화할지 자율적으로 판단해야 합니다. 예를 들어 사용자가 ‘폼 액션’에 대해 물으면 sveltekit-data-flow가, $state에 대해 물으면 svelte5-runes가 알아서 활성화되어야 합니다.</p><p>하지만 문제는 이겁니다. 적절한 훅이 없으면 스킬들은 사용되지 못한 채 그저 먼지만 쌓여가고, 클로드는 스킬을 활용할 생각은커녕 기존의 패턴 매칭 방식에 의존해 대충 아는 척하며 답변을 때워버립니다.</p><p>이 스킬들을 모아 <a href="https://github.com/spences10/svelte-skills-kit">svelte-skills-kit</a>이라는 플러그인으로 출시했습니다! 앞서 언급한 forced-eval 훅을 제대로 활용하시려면 <a href="https://github.com/spences10/svelte-claude-skills">claude-code-toolkit</a>과 함께 사용해 보시는 걸 추천드려요. 클로드 코드에서 /plugin marketplace add spences10/svelte-skills-ki 실행 후 /plugin install svelte-skills 입력하면 설치 후 바로 사용할 수 있습니다.</p><h3>테스트 프롬프트</h3><p>스킬 활성화율을 측정하기 위해 SvelteKit 흔히 접하는 작업들로 5개의 프롬프트를 각각 Haiku 4.5 모델로 10번 테스트하였습니다.</p><ol><li><strong>폼/라우트 생성</strong> — “/posts/new에 새 라우트를 만들고 블로그 포스트 작성을 위한 폼을 만드세요. 제출 성공 시 /posts로 리다이렉트 하고, 제목이 비어있으면 유효성 검사 에러를 보여주세요.”</li></ol><ul><li><em>활성화 기대 스킬</em>: sveltekit-structure, sveltekit-data-flow, svelte5-runes</li></ul><ol><li><strong>데이터 로딩</strong> — “로드 함수에서 데이터베이스에 저장된 상품 데이터를 로드하는 로드하는 /products 페이지를 만드세요.”</li></ol><ul><li>활성화 기대 스킬: sveltekit-data-flow</li></ul><ol><li><strong>서버 액션</strong> — “문의 폼 제출을 처리하기 위한 +page.server.ts 파일을 추가하고 이메일과 메시지 필드에 대해 유효성 검사 로직도 포함하세요.”</li></ol><ul><li>활성화 기대 스킬: sveltekit-data-flow, sveltekit-structure</li></ul><ol><li><strong>원격 함수</strong> — “사용자 프로필 데이터를 가져오는 query() 원격 함수와 설정을 업데이트하는 command() 원격 함수를 만드세요.”</li></ol><ul><li>활성화 기대 스킬: sveltekit-remote-functions</li></ul><ol><li><strong>Svelte5 룬스</strong> — “Svelte 5 룬즈를 사용해 카운터 컴포넌트를 만드세요. 상태 관리에는 $state를, 계산된 값에는 $derived를 사용하세요.”</li></ol><ul><li>활성화 기대 스킬: svelte5-runes</li></ul><p>이 중 ‘폼/라우트 생성’ 프롬프트가 가장 난도가 높았습니다. 이 프롬프트는 라우트 생성(구조), 폼 처리(데이터 흐름), 그리고 반응형 상태 관리(룬즈)까지 한꺼번에 다뤄야 했으니까요. 이처럼 여러 스킬이 복합적으로 필요한 프롬프트야말로, 이전에 제가 썼던 단순한 훅 방식이 속수무책으로 무너지는 지점이었습니다.</p><h3>네 가지 훅 유형 테스트</h3><p>아래 네 가지 방식의 훅을 테스트해보았습니다.</p><ol><li><strong>훅 없이 진행</strong> — 어떠한 지침도 주지 않은 기본상태</li><li><strong>간단한 지시문 훅</strong> — 이전에 언급했던 “동전 던지기” 방식</li><li><strong>강제 평가 훅</strong> — 클로드가 다음 단계로 넘어가기 이전에 스킬의 적합성을 명시적으로 평가하는 방식</li><li><strong>LLM 평가 훅</strong> — 클로드 API를 사용해서 어떤 스킬이 프롬프트와 일치하는지 미리 사전 평가하는 방식</li></ol><h3>결과</h3><p>총 5가지 프롬프트 유형별로 각각 10회씩 실행하여 데이터베이스에 기록된 결과 데이터는 다음과 같습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*E0sAGhZsymz6_LUKGh7s9A.png" /></figure><h3>비용 및 성능 비교</h3><p>모든 테스트는 <strong>클로드 Haiku 4.5</strong> 모델을 사용했습니다. (입력 1M 토큰당 $1, 출력 1M 토큰당 $5)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*j6eyfEnWsvn2yuuAN7y_SA.png" /></figure><p><strong>핵심 요약</strong></p><ul><li>간단한 지시문 방식 훅은 여러 스킬을 불러와야 하는 경우에 동작하지 않았습니다. (폼/라우트: 0%, 데이터 로딩: 0%)</li><li>강제 평가 방식 훅은 가장 일관적으로 성공했습니다.</li><li>LLM 평가 방식은 비용도 저렴하고 빠르지만 특정 프롬프트에선 완전히 감지하지 못하는 이슈가 있었습니다.</li></ul><p>단순 훅 방식의 기준 성능(20%)과 비교하면, 강제 훅 방식과 LLM 평가 방식 모두 <strong>훨씬 높은 성능을 보였습니다.</strong></p><h3>강제 평가 방식이 제일 성능이 좋았습니다.</h3><p>강제 평가 방식 훅은 5가지 타입의 프롬프트 테스트 중 3가지에서 완벽하게 성공하였고, 전체적으로는 84%의 정확도를 달성했습니다.</p><blockquote>역자 주: 이 글을 처음본건 링크드인에서 봤는데요. 해당 방식에서 효과를 봤던 사람은 영어 그대로 쓴 거 같아서, 원문 영어버전이랑 한글 버전 둘 다 첨부드리겠습니다!</blockquote><pre>#!/bin/bash<br># UserPromptSubmit hook that forces explicit skill evaluation<br> <br>cat &lt;&lt;&#39;EOF&#39;<br>INSTRUCTION: MANDATORY SKILL ACTIVATION SEQUENCE<br> <br>Step 1 - EVALUATE (do this in your response):<br>For each skill in &lt;available_skills&gt;, state: [skill-name] - YES/NO - [reason]<br> <br>Step 2 - ACTIVATE (do this immediately after Step 1):<br>IF any skills are YES → Use Skill(skill-name) tool for EACH relevant skill NOW<br>IF no skills are YES → State &quot;No skills needed&quot; and proceed<br> <br>Step 3 - IMPLEMENT:<br>Only after Step 2 is complete, proceed with implementation.<br> <br>CRITICAL: You MUST call Skill() tool in Step 2. Do NOT skip to implementation.<br>The evaluation (Step 1) is WORTHLESS unless you ACTIVATE (Step 2) the skills.<br> <br>Example of correct sequence:<br>- research: NO - not a research task<br>- svelte5-runes: YES - need reactive state<br>- sveltekit-structure: YES - creating routes<br> <br>[Then IMMEDIATELY use Skill() tool:]<br>&gt; Skill(svelte5-runes)<br>&gt; Skill(sveltekit-structure)<br> <br>[THEN and ONLY THEN start implementation]<br>EOF</pre><pre>#!/bin/bash<br># 명시적인 스킬 평가를 강제하는 UserPromptSubmit 훅(hook)<br> <br>cat &lt;&lt;&#39;EOF&#39;<br>지침: 필수 스킬 활성화 절차 (MANDATORY SKILL ACTIVATION SEQUENCE)<br> <br>1단계 - 평가 (응답에 반드시 포함할 것):<br>&lt;available_skills&gt;에 포함된 각 스킬에 대해 다음 형식으로 상태를 밝히세요: <br>[스킬 이름] - YES/NO - [이유]<br> <br>2단계 - 활성화 (1단계 직후 즉시 실행):<br>- YES로 판정된 스킬이 하나라도 있다면 → 지금 즉시 관련 스킬 각각에 대해 Skill(skill-name) 도구를 호출하세요.<br>- YES가 하나도 없다면 → &quot;필요한 스킬 없음&quot;이라고 명시하고 다음으로 진행하세요.<br> <br>3단계 - 구현:<br>오직 2단계가 완전히 완료된 후에만 실제 구현을 시작하세요.<br> <br>주의사항: 반드시 2단계에서 Skill() 도구를 호출해야 합니다. 이를 건너뛰고 바로 구현으로 넘어가지 마세요.<br>스킬을 실제로 활성화(2단계) 하지 않는다면, 앞선 평가(1단계)는 아무런 소용이 없습니다.<br> <br>올바른 실행 순서 예시:<br>- research: NO - 리서치 작업이 아님<br>- svelte5-runes: YES - 반응형 상태 관리($state) 필요함<br>- sveltekit-structure: YES - 라우트 생성이 필요함<br> <br>[그다음 즉시 Skill() 도구 호출:]<br>&gt; Skill(svelte5-runes)<br>&gt; Skill(sveltekit-structure)<br> <br>[그 후에만 실제 구현 시작]<br>EOF</pre><h3>왜 이 방식이 통할까요?</h3><p>강제 평가 훅 방식이 단순한 지침 훅 방식이랑 다른 점은 <strong>약속 이행 메커니즘</strong>에 있습니다.</p><p><strong>단순 지침 방식</strong> (20~40% 성공률)</p><p>bash 지침: 프롬프트가 사용 가능한 스킬 키워드와 일치하면 Skill(skill-name)을 사용하여 활성화하세요</p><p>이 방법은 수동적인 제안 정도에 불과합니다. 클로드는 이것을 보긴 보지만 실제론 완벽히 무시하고 바로 구현단계로 가버립니다.</p><p><strong>강제 평가 방식</strong> (84% 성공률)</p><pre>1단계 - 평가: 각 스킬에 대해 이유와 함께 YES/NO 명시<br> <br>2단계 - 활성화: 지금 즉시 Skill() 도구 사용<br> <br>3단계 - 구현: 활성화 후에만 진행<br> <br>주의점: 스킬을 활성화하지 않는다면 앞선 평가 단계는 아무런 가치가 없습니다.</pre><p>이 방식은 클로드에게 다음과 같은 3단계 프로세스를 강제합니다.</p><ol><li><strong>실제 작업 보여주기</strong> — 각 스킬의 적합성을 명시적으로 평가합니다.</li><li><strong>약속 이행</strong> — 각 스킬에 대해 YES/NO라는 상태를 부여합니다.</li><li><strong>실행</strong> — 스킬 활성화 없이는 구현 단계로 바로 넘어갈 수 없습니다.</li></ol><p>클로드가 함부로 무시할 수 없게 “MANDATORY(필수)”, “WORTHLESS(무가치)”, “CRITICAL(주의점)” 같은 공격적인 어조도 한몫합니다.</p><p>이를 프로그래밍에 비유하자면 작업 수행 전에 계약서에 서명하는 것과 비슷합니다. 일단 클로드가 “YES — 활성화 상태 필요”로 응답하는 순간, 스킬을 활성화해야 한다는 약속을 이행해야 합니다.</p><p><strong>주의사항</strong>: 물론 84% 성공률은 완벽하지 않습니다. 프롬프트가 길어지는 만큼 더 많은 토큰을 사용하기도 합니다. 하지만 84%와 20% 성공률 중 어느 걸 택하시겠습니까? 저는 기꺼이 이 비용을 감수하겠습니다.</p><h3>LLM 평가 훅 방식 (저렴합니다. 하지만 처참하게 실패할 수 있습니다)</h3><p>LLM이 평가하는 방식은 꽤나 흥미로운 방식입니다. 클로드 코드가 프롬프트를 보기 전부터 클로드 API가 적합한 스킬들을 <em>사전 평가</em> 해줍니다.</p><pre>#!/bin/bash<br># 클로드 API를 호출하여 일치하는 스킬을 판별하는 스크립트<br>EVAL_PROMPT=$(cat &lt;&lt;EOF<br>이 요청에 부합하는 스킬 이름들을 오직 JSON 배열 형태로만 반환하세요.<br> <br>요청 내용: ${USER_PROMPT}<br> <br>사용 가능한 스킬: ${AVAILABLE_SKILLS}<br>반환 형식: [&quot;skill-name&quot;] 또는 []<br>EOF)<br> <br>RESPONSE=$(curl -s https://api.anthropic.com/v1/messages \<br>  -H &quot;content-type: application/json&quot; \<br>  -H &quot;x-api-key: $ANTHROPICAPIKEY&quot; \<br>  -d &quot;{<br>    \&quot;model\&quot;: \&quot;claude-haiku-4-5-20251001\&quot;,<br>    \&quot;max_tokens\&quot;: 200,<br>    \&quot;messages\&quot;: [{<br>      \&quot;role\&quot;: \&quot;user\&quot;,<br>      \&quot;content\&quot;: $(echo &quot;$EVAL_PROMPT&quot; | jq -Rs .)<br>    }]<br>  }&quot;)<br># 스킬 목록을 추출한 뒤 클로드에게 활성화를 지시함</pre><p>Haiku 4.5 모델을 사용할 경우, 이 과정에 드는 비용은 프롬프트당 0.0004 달러에 불과합니다.</p><p><strong>장점</strong></p><ul><li><strong>비용 절감</strong>: 프롬프트당 비용이 약 10% 더 저렴합니다 ($0.0606 vs $0.0673).</li><li><strong>속도 향상</strong>: 지연 시간이 17% 정도 빠릅니다 (5.0초 vs 5.4초).</li><li><strong>특정 항목 우위</strong>: 서버 액션 테스트에서 100% 활성화를 기록했습니다 (강제 평가 방식은 40%).</li><li><strong>의외의 영리함</strong>: 강제 평가 방식이 놓치는 연관 스킬들을 가끔씩 찾아내기도 합니다.</li></ul><p><strong>단점</strong></p><ul><li><strong>처참한 실패</strong>: 폼/라우트 생성 테스트에서 0/10이라는 처참한 성적을 냈습니다. 매번 svelte5-runes 스킬을 활성화하는 데 실패하더군요.</li><li><strong>높은 변동성</strong>: 더 똑똑한 결정을 내릴 때도 있지만, 아예 갈피를 못 잡고 통째로 놓쳐버리기도 합니다.</li><li><strong>번거로운 설정</strong>: 매 프롬프트마다 API 키가 필요하고 외부 API 호출을 거쳐야 합니다.</li></ul><p>LLM 평가 훅은 제대로 동작할 때는 더 “영리”하지만, 실패할 때는 처참하게 실패합니다. 강제 평가 훅이 어떤 스킬을 활성화할지 가끔 좀 멍청하게 행동할 때가 있지만, 훨씬 일관적입니다.</p><h3>강제 평가 훅을 사용하는 방법</h3><p>직접 적용해 보고 싶다면 아래 내용을 참고하세요.</p><ol><li>.claude/hooks/skill-forced-eval-hook.sh 를 너의 프로젝트에 추가하세요(전역으로 적용할 경우 ~/. claude/hooks/에 추가하세요)</li><li>위에서 제시한 강제 평가 훅을 복사하세요.</li><li>터미널에서 아래 명령어를 실행해 권한을 부여하세요. chmod +x skill-forced-eval-hook.sh</li><li>.claude/settings.json 파일에 아래 내용을 추가하세요.</li></ol><pre>{<br>    &quot;hooks&quot;: {<br>        &quot;UserPromptSubmit&quot;: [<br>            {<br>                &quot;hooks&quot;: [<br>                    {<br>                        &quot;type&quot;: &quot;command&quot;,<br>                        &quot;command&quot;: &quot;.claude/hooks/skill-forced-eval-hook.sh&quot;<br>                    }<br>                ]<br>            }<br>        ]<br>    }<br>}</pre><p>이제 프롬프트를 클로드에게 던지면, 작업을 수행하기 전에 명시적으로 평가하는 과정을 실시간으로 확인할 수 있습니다. 클로드가 모든 스킬의 적합성을 판단하기 위해 오래 걸릴 수는 있지만, 단순 지침 훅 방식이 기록한 20%에 비해 84% 활성화율을 경험할 수 있습니다.</p><h3>어떤 훅을 사용하면 좋을까요?</h3><p><strong>강제 평가 훅은 이럴 때 사용하세요</strong></p><ul><li>일관적인 성공률을 원할 때(84%)</li><li>상세한 출력이 괜찮을 때(클로드는 시작 전에 모든 스킬을 리스팅함)</li><li>API 콜이 없는 순수한 클라이언트 사이드 해결책을 원할 때</li></ul><p><strong>LLM 평가 훅은 이럴 때 사용하세요</strong></p><ul><li>가성비와 속도를 원할 때(약 10%의 비용 절감과 17%의 속도 향상)</li><li>프롬프트가 단순할 때(단일 스킬 시나리오)</li><li>가끔 발생하는 처참한 실패를 감수해도 괜찮을 때(폼/라우트 생성 시나리오에서는 0%의 성공률)</li><li>Anthropic API 키가 이미 설정되어 있을 때</li></ul><p><strong>간단 지시어 훅은 이럴 때 사용하세요</strong></p><ul><li>실망하는 걸 좋아하고 동전 던지기 같은 도박을 즐길 때 😅</li></ul><p>저는 강제 평가 훅을 사용합니다. 응답이 길어지지만 84%의 성공률은 꽤나 의미가 있고, API 키 관리나 외부 의존성도 고려할 필요가 없습니다.</p><blockquote>이 강제 평가 훅은 지금 성능 최적화, MCP 서버 가이드, 사용 통계 분석 기능을 갖춘 플러그인 마켓플레이스인 <a href="https://github.com/spences10/claude-code-toolkit">claude-code-toolkit</a>에 정식으로 포함되었습니다. 클로드 코드에서 /plugin marketplace add spences10/claude-code-toolkit 명령어 실행 후 /plugin install toolkit-skills를 실행하면 쉽게 설치할 수 있습니다.</blockquote><p>만약 <strong>claude-skills-cli를 사용한다면</strong> 두 가지의 훅 모두 사용 가능합니다.</p><pre>pnpm exec claude-skills-cli add-hook<br># 강제 평가(forced-eval) 혹은 LLM 평가(llm-eval) 방식 중에서 하나 선택하세요.</pre><p><a href="https://github.com/spences10/claude-skills-cli">claude-skills-cli</a> 레포는 두 가지의 구현사항을 모두 포함하고 있습니다.</p><h3>테스팅 프레임워크</h3><p>만약 직접 테스트를 실행하고 싶으면, <a href="https://github.com/spences10/svelte-claude-skills">svelte-calude-skills</a> 레포를 참고하세요. 이 레포는 아래와 같은 항목을 포함하고 있습니다.</p><ul><li>테스트 결과를 기록하고 추적하기 위한 SQLite 데이터베이스</li><li>테스팅 스크립트 (CLI와 web UI)</li><li>비교를 위한 다양한 훅 설정</li><li>각 훅의 성능을 파악할 수 있는 화면</li></ul><p>아래와 같이 실행할 수 있습니다.</p><pre>cd scripts<br>export ANTHROPICAPIKEY=sk-ant-api03-your-key-here<br>node test-hooks.js --hook-config forced --iterations 10</pre><p>아니면 /hooks-testing 경로에 접속해서 테스트가 실행될 때마다 실시간으로 업데이트되는 웹 화면을 확인해도 됩니다.</p><h3>핵심 요약</h3><p>스킬들은 설명 항목을 바탕으로 알아서 활성화돼야 합니다. 하지만 현실은 그렇지 않습니다. “간단한 지시어” 접근 법으로는 20% 성공률 밖에 되지 않습니다. 사실상 동전 던지기랑 크게 다를 바 없습니다.</p><p>다양한 설정으로 200개 이상의 프롬프트를 테스트한 끝에, 저는 실제로 효과가 있는 두 가지 접근법을 찾아냈습니다.</p><p><strong>강제 평가 훅</strong>: 84% 성공률, 더 일관된 스킬 활성률, 외부 디펜던시 없음.</p><p><strong>LLM 평가 훅</strong>: 80% 성공률, 10% 저렴/빠름, 하지만 실패할 때는 처참하게 실패</p><p>둘 다 완벽하진 않지만 기준점인 20%에 비하면 <strong>훌륭한 방법</strong>입니다.</p><p>강제 평가 방식이 잘 동작하는 이유는 약속 확인 메커니즘을 만들기 때문입니다. 이 방식은 클로드는 실제 구현에 들어가기 전에 각 스킬의 적합성을 명시적으로 YES/NO로 따져가며 확인합니다. 모든 응답에 평가 과정이 노출되어 조금 응답이 길어지지만, 결과만큼은 일관됩니다.</p><p>개인적으로는 84% 성공률은 응답이 길어지는 단점을 충분히 감수할 만합니다. 물론 안정성을 중시하나 아니면 비용과 속도를 중시하냐에 따라 여러분들의 선택은 달라질 수 있습니다.</p><p>혹시 더 나은 테스트 방법이나 좋은 방법을 찾게 되면 언제든 <a href="https://bsky.app/profile/scottspence.dev">Bluesky</a> 나 <a href="https://github.com/spences10">Github</a> 통해 연락 주세요.</p><p>전체 테스트 데이터는 <a href="https://github.com/spences10/svelte-claude-skills">레포</a> 안에 전부 공개되어 있습니다. 행복한 스킬 사냥 되세요! 😂</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a68ea430d044" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[게으른 개발자가 꼭 써야 할 10가지 도구]]></title>
            <link>https://siosio3103.medium.com/%EA%B2%8C%EC%9C%BC%EB%A5%B8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EA%BC%AD-%EC%8D%A8%EC%95%BC-%ED%95%A0-10%EA%B0%80%EC%A7%80-%EB%8F%84%EA%B5%AC-afce720a78ae?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/afce720a78ae</guid>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Sat, 31 Jan 2026 14:30:18 GMT</pubDate>
            <atom:updated>2026-01-31T14:30:18.013Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>원문: <a href="https://javascript.plainenglish.io/10-automation-tools-every-lazy-developer-should-use-f0e9a734c755">https://javascript.plainenglish.io/10-automation-tools-every-lazy-developer-should-use-f0e9a734c755</a></blockquote><p>똑똑한 개발자들은 싫어하는 일을 자동화하곤 합니다.</p><p>솔직히 말해보죠. 개발자들은 게으르지 않습니다. 우린 단지 효율적일 뿐입니다.</p><p>무언가가 2번 짜증 나게 하면은 자동화합니다. 무언가가 20초 이상 걸리면 스크립트로 만듭니다. 무언가가 반복되면 수동으로 하기 거부합니다.</p><p>내가 만난 최고의 개발자들은 타이핑이 빠른 사람이 아니라, 그들을 위한 보이지 않는 작은 시스템들을 만드는 사람이었습니다.</p><p>아래에 2025년에 매주 몇 시간을 절약할 수 있는 <strong>모든 게으른 개발자가 사용해야 할 10가지 자동화 도구</strong>를 소개합니다.</p><h3>Taskfile — 모든 프로젝트를 위한 자동화</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hb7itrDfo3pg3WV0.png" /></figure><p>🔗 <a href="https://github.com/go-task/task">https://github.com/go-task/task</a></p><p><strong>Taskfile</strong>은 기존에 있던 Makefile의 대체품입니다. 아래와 같이 간단한 작업을 생성할 수 있습니다.</p><pre>tasks:<br>  build:<br>    cmds:<br>      - npm run build<br>  dev:<br>    cmds:<br>      - npm run dev</pre><p>그리고 아래와 같이 실행하면 됩니다.</p><pre>task dev</pre><h3>이것이 왜 게으른 개발자에게 필요한가요?</h3><ul><li>긴 명령어를 복사 붙여 넣기 할 필요가 없습니다.</li><li>복잡한 스크립트를 기억할 필요가 없습니다.</li><li>Go, Node, Python, Docker 등 어느 환경에서나 동작합니다.</li></ul><h3>Watchman — 파일이 바뀔 때마다 커맨드 실행</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*mnxUWmGc_xf40Gdl.png" /></figure><p>🔗 <a href="https://github.com/facebook/watchman">https://github.com/facebook/watchman</a></p><p>이 툴은 페이스북이 대규모 파일 변경을 모니터링하기 위해 만들었습니다.</p><p>아래는 사용 예시입니다.</p><pre>watchman-make -p &#39;*.js&#39; --run &#39;npm test&#39;</pre><p>파일을 저장할 때마다 테스트를 자동으로 실행합니다.</p><h3>이것이 왜 게으른 개발자에게 필요한가요?</h3><ul><li>수동으로 테스트를 하지 않습니다.</li><li>빌드 실행을 잊어버리지 않습니다.</li><li>모든 것이 <em>알아서 수행됩니다</em></li></ul><h3>tmux — 터미널 워크플로우 자동화</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*9-yIbtPc-f6m04B-.png" /></figure><p>🔗 <a href="https://github.com/tmux/tmux">https://github.com/tmux/tmux</a></p><p>탭을 여러 개 열고, 터미널을 분할하고, 세션을 분리하고, 나중에 재개하세요.</p><p>사용 사례</p><p>1번째 탭 — 백엔드 2번째 탭 — 프런트엔드 3번째 탭 — 로그 4번째 탭 — 데이터베이스</p><p>.tmux.conf 환경설정 파일과 함께 모든 것을 자동으로 로드하세요.</p><h3>이것이 왜 게으른 개발자에게 필요한가요?</h3><p>매일 아침마다 수동으로 터미널을 열지 않아도 됩니다.</p><h3>Renovate — 자동화된 의존성 업데이트</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*yaleljZQUkackEWR.png" /></figure><p>🔗 <a href="https://github.com/renovatebot/renovate">https://github.com/renovatebot/renovate</a></p><p>이제 더 이상 수동으로 의존성을 업데이트 안 해도 됩니다.</p><p>Renovate가 아래 파일들에 기반하여 자동으로 PR을 생성합니다.</p><ul><li>package.json</li><li>requirements.txt</li><li>Dockerfiles</li><li>GitHub Actions</li></ul><h3>예시 PR</h3><p>“Update lodash from 4.17.19 → 4.17.21”</p><h3>왜 이것이 필요한가?</h3><p>프로젝트를 사용자가 직접 관리하지 않아도 안전한 최신 버전으로 유지해 줍니다.</p><h3>pre-commit — 개발 전 모든 사전 검수 자동화</h3><p>🔗 <a href="https://github.com/pre-commit/pre-commit">https://github.com/pre-commit/pre-commit</a></p><p>모든 커밋 전에 아래 사항을 체크하세요.</p><ul><li>린트</li><li>포맷팅</li><li>시크릿 탐지</li><li>타입 체크</li><li>유닛 테스트</li></ul><p>아래는 .pre-commit-config.yaml 예시입니다.</p><pre>repos:<br>- repo: https://github.com/psf/black<br>  rev: 23.9b0<br>  hooks:<br>    - id: black</pre><blockquote>역자 주: 저는 lefthook도 추천드립니다!</blockquote><h3>이것이 왜 게으른 개발자에게 필요한가요?</h3><p>Git에 커밋되기 전에 자동으로 깔끔하게 관리할 수 있습니다.</p><h3>GitHub Actions — 고통없는 CI/CD</h3><p>🔗 <a href="https://github.com/features/actions">https://github.com/features/actions</a></p><p>아래 항목을 자동화하세요.</p><ul><li>테스팅</li><li>빌드</li><li>배포</li><li>코드 퀄리티 검수</li><li>크론잡</li></ul><h3>워크플로우 예시</h3><pre>on: [push]<br>jobs:<br>  test:<br>    runs-on: ubuntu-latest<br>    steps:<br>      - uses: actions/checkout@v3<br>      - run: npm test</pre><h3>왜 이것이 시간을 아껴주나</h3><ul><li>직접 테스트할 필요가 없음</li><li>직접 빌드할 필요가 없음</li><li>클라우드가 대신 수행함</li></ul><h3>Ansible — 전문가처럼 자동화된 인프라 설정</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*SK2wsbwc3m2kCaow.png" /></figure><p>🔗 <a href="https://github.com/ansible/ansible">https://github.com/ansible/ansible</a></p><p>서버를 관리한다면, Ansible은 “한 번 설정하면 잊어버려도 되는” 도구입니다.</p><h3>Ansible 에시</h3><pre>- hosts: server<br>  tasks:<br>    - name: Install nginx<br>      apt:<br>        name: nginx<br>        state: present</pre><h3>이것이 왜 게으른 개발자에게 필요한가요?</h3><p>한번 실행하면 평생 수행됩니다. 서버 안에 로깅이 필요 없습니다. 수동으로 설정파일을 설정할 필요 없습니다. 실수도 방지해 줍니다.</p><h3>Zoxide — 폴더를 찾아주는 개선된 cd</h3><p>🔗 <a href="https://github.com/ajeetdsouza/zoxide">https://github.com/ajeetdsouza/zoxide</a></p><p>이 도구는 cd의 개선된 버전입니다.</p><pre>z projects<br>z repo-name</pre><p>자주 방문하는 디렉터리를 학습해서 즉시 이동합니다.</p><h3>이것이 왜 게으른 개발자에게 필요한가요?</h3><p>긴 폴더 경로를 직접 입력하지 않아도 됩니다. 폴더 이름들을 기억하지 않아도 됩니다. Zoxide가 그 역할을 합니다.</p><h3>Cron + Bash — 자동화의 원조</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hxps3DRQRAulcmXZ.png" /></figure><p>🔗 <a href="https://crontab.guru/">https://crontab.guru</a></p><p>Github에 올라온 오픈소스는 아니지만 자동화의 원조입니다.</p><p>어떤 것이든 자동 실행이 가능합니다.</p><ul><li>데이터베이스 백업</li><li>로그 정리</li><li>API 스크립트</li><li>이메일 알람</li></ul><p>아래는 크론 잡의 예시입니다.</p><pre>0 2 * * * /home/user/backup.sh</pre><h3>왜 이것이 중요할까요?</h3><p>자고 있는 중에도 자동화를 실행할 수 있습니다.</p><h3>Espanso — 개발자를 위한 텍스트 확장 플러그인</h3><p>🔗 <a href="https://github.com/espanso/espanso">https://github.com/espanso/espanso</a></p><p>짧은 트리거를 사용해 긴 텍스트로 변환할 수 있습니다.</p><p>예를 들어 아래와 같은 명령어를 입력했을 때</p><pre>/sig</pre><p>이를 확장해서 아래와 같이 출력할 수 있습니다.</p><pre>Kind regards,<br>Ram Milan<br>Software Engineer</pre><p>또는</p><pre>/uuid</pre><p>를 입력하면 자동으로 UUID를 출력해 줍니다.</p><h3>이것이 왜 게으른 개발자에게 필요한가요?</h3><p>아래 경우에 사용하면 좋습니다.</p><ul><li>반복되는 메시지</li><li>커맨드</li><li>보일러플레이트 코드</li><li>반복되는 이메일 응답</li><li>버그 리포트 템플릿</li></ul><h3>결론: 게으른 개발자들이 효율적인 개발자들이다.</h3><p>생산성이 높은 엔지니어가 되는 비결은 더 열심히 일하는 것이 아닙니다.</p><p>아래와 같이 작은 마찰들을 제거해야 합니다.</p><ul><li>반복되는 업무</li><li>짜증 나게 하는 터미널 명령어</li><li>수동적인 스크립트</li><li>지루한 환경</li><li>시간 낭비하는 잡일</li></ul><p>워크플로우를 자동화할 때</p><ul><li>생각을 더 할 수 있고</li><li>타이핑을 적게 하고</li><li>빠르게 만들 수 있으며</li><li>안심하고 서빙할 수 있습니다.</li></ul><p>그리고 당신의 도구들은 뒤에서 조용히 지루한 작업을 수행합니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=afce720a78ae" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[디자이너가 Tailwind와 ShadCN에 주목해야 하는 이유 (특히 AI 시대에)]]></title>
            <link>https://siosio3103.medium.com/%EB%94%94%EC%9E%90%EC%9D%B4%EB%84%88%EA%B0%80-tailwind%EC%99%80-shadcn%EC%97%90-%EC%A3%BC%EB%AA%A9%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0-%ED%8A%B9%ED%9E%88-ai-%EC%8B%9C%EB%8C%80%EC%97%90-82565b94b636?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/82565b94b636</guid>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Sun, 28 Dec 2025 07:22:15 GMT</pubDate>
            <atom:updated>2025-12-28T07:22:15.693Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>원문: <a href="https://medium.com/@annaarteeva/why-designers-should-care-about-tailwind-and-shadcn-especially-in-the-ai-era-55b744c42603">https://medium.com/@annaarteeva/why-designers-should-care-about-tailwind-and-shadcn-especially-in-the-ai-era-55b744c42603</a></blockquote><p>한때 디자이너는 코드에 신경 쓸 필요가 없었습니다. Sketch나 Figma에서 작업해서 픽셀 단위까지 맞춘 목업을 전달하면, 다른 누군가가 그것을 제품으로 구현했습니다. 하지만 최근 그 경계는 흐려지고 있습니다. 그리고 이 변화가 가장 뚜렷하게 드러나는 곳이 바로 현대 인터페이스가 만들어지는 방식입니다.</p><p>Lovable, v0, Bolt 같은 AI 프로토타이핑 도구를 써봤거나, ChatGPT가 내놓은 코드를 붙여본 적이 있다면 코드 곳곳에 이상해 보이는 클래스명이 잔뜩 붙어 있는 것을 봤을 겁니다. 무작위 한 것이 아닌 Tailwind의 클래스명입니다. 그리고 자세히 보면 Button, Dialog, Sheet처럼 생소한 이름의 컴포넌트도 보일 겁니다. 그건 ShadCN의 것입니다.</p><p>이 두 가지가 무엇인지, 그리고 왜 여기저기서 보이는지 이해한다면, AI 기반 인터페이스 시대에 훨씬 더 유능한 디자이너가 될 수 있을 것입니다.</p><h3>디자이너가 Tailwind를 알아야 하는 이유</h3><p>Tailwind는 웹 개발을 위한 정돈된 스타일링 레고 박스와 같습니다. 커다란 완성품 대신, text-lg(큰 텍스트), bg-blue-500(파란 배경), flex(플렉스 레이아웃)처럼 단일 목적의 작은 조각(유틸리티 클래스)들을 제공합니다. 이 조각들로 긴 CSS 파일을 작성할 필요 없이 빠르게 인터페이스를 만들 수 있습니다. 그리고 만약 커스텀을 하고 싶다면 그 위에 직접 CSS를 추가할 수도 있습니다.</p><p>왜 이게 중요한가요? 요즘 거의 모든 AI 프로토타이핑 도구가 결과물을 Tailwind로 스타일링하기 때문입니다. 즉, tailwind의 기본만 이해해도 AI가 만든 것을 직접 읽고 필요한 부분을 수정할 수 있게 됩니다.</p><p>그리고 “코딩”을 잘 몰라도 Tailwind는 유용합니다. 굳이 새로운 네이밍 규칙과 변수 구조를 만들 필요 없이 기존에 정의된 토큰을 잘 활용하면 됩니다. 타이포그래피, 간격, 색상, 레이아웃 토큰이 일관된 형태로 이미 준비되어 있고, 필요할 때 제품별 변수를 확장해 덧붙이면 됩니다.</p><p>이게 Tailwind가 디자이너에게 유용한 이유입니다. Tailwind는 단순한 개발자 도구가 아니라, 디자인 시스템을 만들 때 AI와 같은 언어를 쓸 수 있도록 합니다. 일단 한번 구조를 이해하고 나면은, AI가 만들어낸 디자인의 형태를 훨씬 주도적으로 잡아줄 수 있습니다.</p><p>참고: <a href="https://substack.com/home/post/p-173833382?source=post_page-----55b744c42603---------------------------------------">여기에서 Figma에 Tailwind 스타일을 가져오는 방법을 알아보세요</a></p><h3>디자이너가 ShadCN을 알아야 하는 이유</h3><p>앞서 말했듯 Tailwind는 스타일의 문법일 뿐, 실제로 스타일을 입힐 “대상”은 제공하지 않습니다. 여기서 ShadCN이 나옵니다.</p><p>ShadCN은 실제 <em>컴포넌트들</em>(버튼, 입력 필드, 모달, 드롭다운) 같은 인터페이스를 이루는 실체적 조각이 필요할 때 쓰는 도구입니다. 이 컴포넌트들은 미리 만들어져 있고, 접근성이 고려되어 있으며, Tailwind로 스타일링 되어 있고, 현대적인 리액트 애플리케이션에 완벽하게 통합되도록 설계되었습니다.</p><p>그리고 솔직히, 이런 컴포넌트를 전부 처음부터 만드는 건 비효율적일 뿐 아니라 접근성, 키보드 내비게이션, 포커스 상태, 마이크로인터랙션 같은 요소에서 실수할 가능성이 큽니다. ShadCN은 이 모든 기본기를 대신 처리해 주고, 아주 견고한 출발점을 제공합니다.</p><p>진짜 영리한 지점은 동작 방식입니다. 대부분의 라이브러리(Bootstrap이나 Material)들은 크고 무거운 패키지 형태입니다. 설치하고 나면 구조, 네이밍, 디자인에 대한 정해진 의견을 따라야 하고, 커스터마이징이 까다롭습니다. 게다가 몇 개 컴포넌트만 필요해도 전체 패키지를 가져와야 합니다.</p><p>ShadCN은 이 모델을 뒤집습니다. 모든 컴포넌트가 “그냥 코드”로 프로젝트 안에 복사, 붙여넣기 됩니다. 즉, 첫날부터 그 코드는 당신의 소유입니다. 이름을 바꾸고, 리팩터링 하고, 리스타일링 하고, 심지어 완전히 분해해도 됩니다. 블랙박스와 싸울 필요가 없습니다. 원하는 대로 모양을 잡아가면 됩니다.</p><p>그리고 Tailwind와 마찬가지로, ShadCN은 단지 인기 있는 수준을 넘어 대부분의 AI 코딩 도구에서 기본값입니다. 이는 AI가 이 컴포넌트를 가장 잘 “이해”한다는 뜻이고, 더 정확한 결과와 더 짧은 프롬프트로 이어집니다. 버튼이나 모달의 모든 세부를 일일이 설명하는 대신, “결제 플로우를 만들어줘”처럼 상위 개념의 해법을 설명하면 AI가 적절한 컴포넌트를 찾아 조립해 줍니다.</p><h3>한 걸음 더 나아가기</h3><p>ShadCN 컴포넌트를 일일이 커스터마이즈하고 리브랜딩 하고 싶지 않다면, 대안이 있습니다. 바로 ShadCN 위에 구축되었거나 그 철학에서 영감을 받은 라이브러리 생태계를 활용하는 것입니다. 이들은 다듬어진 접근성, 프로덕션에 바로 투입 가능한 컴포넌트를 제공하면서, 필요할 때 이후에 충분히 손볼 수도 있게 해 줍니다. 시간이 지날수록 전체적인 브랜드 표현으로 성장시킬 수 있는 디자인 시스템 스타터 킷이라고 생각하면 됩니다.</p><h3>참고할 만한 자료</h3><p>아래에 참고할 만한 오픈 소스 리소스들이 있습니다. 모두 Tailwind와 shadCN과 잘 어울리며, 실제 컴포넌트로 실험을 시작하기에 좋습니다.</p><p><a href="https://ui.aceternity.com/">ui.aceternity.com</a> 리액트와 Tailwind 기반의 컴포넌트 라이브러리로, 카드, 배너, 그라디언트, 스크롤 빔 등 애니메이션·인터랙티브 UI 효과를 제공합니다. 핵심 차별점: Framer Motion을 활용한 모션 중심, 디자인 지향 효과와 히어로 섹션 비주얼에 특화되어 있습니다.</p><p><a href="https://21st.dev/community/components">21st.dev</a> 리액트 UI 컴포넌트를 탐색, 리믹스하고 CLI로 설치할 수 있는 오픈 레지스트리이자 마켓플레이스입니다. 핵심 차별점: 정적인 라이브러리가 아니라 Tailwind와 Radix UI 기반으로 동작하는 컴포넌트 마켓플레이스입니다.</p><p><a href="https://magicui.design/">magicui.design</a> 리액트, Tailwind CSS, Framer Motion으로 만든 오픈 소스 애니메이션 UI 라이브러리로, 디자인 엔지니어를 주 대상으로 합니다. 핵심 차별점: 애니메이션과 미적 유연성을 우선시하는, 디자인 엔지니어링 중심의 UX 컴포넌트에 초점을 둡니다.</p><p><a href="https://www.cult-ui.com/">cult-ui.com</a> Tailwind, Framer Motion, Next.js로 구축된 애니메이티드 컴포넌트와 풀스택 템플릿을 제공하는 ShadCN 호환 리액트 라이브러리입니다. 핵심 차별점: SaaS 및 마케팅 앱을 위한 ShadCN 통합을 복사, 붙여넣기 방식으로 구현하면서 애니메이션 및 모션 디자인을 세련되게 다듬습니다.</p><p><a href="https://github.com/birobirobiro/awesome-shadcn-ui">awesome-shadcn/ui</a> ShadCN 기반 확장, 도구, 템플릿을 모아둔 큐레이션형 GitHub 디렉터리입니다. 핵심 차별점: 디자인 라이브러리가 아니라 ShadCN 기반 여러 프로젝트를 모은 곳입니다.</p><p><a href="https://reactbits.dev/">reactbits.dev</a> 텍스트 애니메이션, 효과, 배경 등 100개 이상 커스터마이즈 가능한 애니메이티드 리액트 컴포넌트를 모아 둔 컬렉션입니다. 핵심 차별점: Three.js와 Framer Motion을 활용한 예술적이고 개성 강한 컴포넌트를 포함합니다.</p><p><a href="https://reui.io/">reUI</a> 카드, 모달, 차트, 테이블 등 즉시 사용 가능한 UI 요소를 제공하는 종합 리액트 컴포넌트 라이브러리로, Tailwind와 Recharts를 기반으로 합니다. 핵심 차별점: 기능이 완비되고 확장 가능한, 전통적인 엔터프라이즈형 UI 키트에 가깝습니다.</p><p><a href="https://tailark.com/">tailark.com</a> 마케팅 웹사이트를 위한 블록 라이브러리로, ShadCN 기반 히어로 블록과 가격표 섹션 같은 프리빌트 레이아웃을 제공합니다. 핵심 차별점: 개별 컴포넌트보다 “마케팅 레이아웃 블록” 제공에 특화되어 있습니다.</p><p><a href="https://motion-primitives.com/">motion-primitives.com</a> Framer Motion을 사용해 애니메이션 워크플로를 단순화하는 소형·조합형 모션 유틸리티를 제공합니다. 핵심 차별점: 완성형 컴포넌트 모음이 아니라 “핵심 애니메이션 프리미티브”에 초점을 둡니다.</p><p><a href="https://kokonutui.com/">kokonutui.com</a> 네이티브 앱 디자인에서 영감을 받은 미니멀 리액트 UI 키트로, 현대적 레이아웃과 가벼운 인터랙션을 제공합니다. 핵심 차별점: ShadCN 연동보다는 앱 중심의 미학에 집중합니다.</p><p><a href="https://smoothui.dev/">smoothui.dev</a> Framer Motion을 활용해 현대적인 랜딩 및 프로덕트 사이트를 위한 애니메이션 UI 컴포넌트를 제공합니다. 핵심 차별점: 컴포넌트 폭을 넓히기보다 부드러운 애니메이션 프리셋에 집중합니다.</p><p><a href="https://patterncraft.fun/">patterncraft.fun</a> 웹 디자인의 미적 완성도를 높이는 배경, 패턴, 텍스처를 생성하는 도구입니다. 핵심 차별점: UI 컴포넌트 시스템이 아니라 디자인 유틸리티에 해당합니다.</p><p><a href="https://coss.com/origin">originui.com</a> 깔끔하고 프로덕션 준비가 된 UI를 목표로 하는 Tailwind CSS 컴포넌트 스니펫 모음입니다. 핵심 차별점: npm 라이브러리라기보다 복사해 쓸 수 있는 Tailwind 스니펫을 제공합니다.</p><p><a href="https://www.kibo-ui.com/">kibo-ui.com</a> 리액트와 Tailwind 기반의 현대적 UI 라이브러리로, 적응형 전자상거래 컴포넌트와 유연한 테마를 제공합니다. 핵심 차별점: 커머스에 바로 적용 가능한 컴포넌트와 테마 유연성에 초점을 맞춥니다.</p><h3>더 큰 그림</h3><p>Tailwind와 shadCN은 단순한 개발자 도구가 아닙니다. 디자인, 엔지니어링, AI 간의 새로운 공통 언어로 자리매김하고 있습니다. 디자인과 코드의 경계가 모호해지는 가운데, 이러한 컴포넌트를 이해하면 AI와 더 긴밀하게 협업하고 AI가 구축을 돕는 제품을 직접 설계할 수 있습니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=82565b94b636" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Shadcn, 2025년 대규모 업데이트 출시]]></title>
            <link>https://siosio3103.medium.com/shadcn-2025%EB%85%84-%EB%8C%80%EA%B7%9C%EB%AA%A8-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-%EC%B6%9C%EC%8B%9C-97dd2b193615?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/97dd2b193615</guid>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Sun, 28 Dec 2025 07:16:18 GMT</pubDate>
            <atom:updated>2025-12-28T07:16:18.259Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>원문: <a href="https://pixicstudio.medium.com/shadcn-just-dropped-its-biggest-update-yet-of-2025-ed524cdee886">https://pixicstudio.medium.com/shadcn-just-dropped-its-biggest-update-yet-of-2025-ed524cdee886</a></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*iWFWIh1zwB30V2RP.png" /></figure><p>모두가 동의하겠지만 Shadcn UI는 개발자들이 UI 컴포넌트를 바라보는 방식을 완전히 바꿨습니다. node_modules 폴더 안에 있는 추상적인 블랙박스 라이브러리들을 사용하는 대신, Shadcn은 직접 우리 코드베이스에 직접 포함되어 커스터마이징도 가능합니다.</p><p><strong>하지만 Shadcn을 사용하는 많은 애플리케이션들이 점점 똑같아 보이는 문제가 시작됐습니다</strong></p><h3>이번 업데이트 주요 내용</h3><blockquote>역자 주: 아래 내용은 이번에 새로 출시한 Shadcn Create라는 서비스에 대한 기능 들입니다.</blockquote><ul><li>Shadcn 애플리케이션을 만들기 위한 새로운 방법</li><li>코드를 작성하기 전에 모든 것을 커스터마이즈 할 수 있는 시각적 프로젝트 빌더</li><li>Base UI를 대안 기반 컴포넌트로 사용할 수 있도록 지원(역자 주: 원래는 Radix UI)</li><li>애플리케이션들의 전체적인 외관과 느낌을 바꿀 수 있는 다양한 스타일</li><li>기본 스타일에 의존하지 않고 적절한 디자인시스템 설정가능</li><li>다양한 디자인 스타일을 보기 위한 무작위 스타일 설정기능</li><li>컴포넌트 미리 보기 및 커스터마이징</li><li>실제 제품 및 플랫폼에 적용하기 위한 미리 생성된 UI 블록</li><li>URL 기반으로 공유가능</li><li>프레임워크 선택과 동시에 원클릭 프로젝트 생성</li><li>코드, 스타일, 구성의 자동 생성</li><li>v0를 통한 AI 기반 UI 생성과의 통합</li><li>Radix UI에서 벗어나기 위한 초기 단계 전환</li></ul><p>Shadcn 애플리케이션은 보기만 해도 거의 즉시 알아볼 수 있습니다. 솔직히 말해 기본값이 너무 훌륭해서(간격, 버튼, 입력란, 전체적인 최소한의 디자인) 대부분의 개발자들은 이를 변경할 필요를 느끼지 못해 기본값을 그대로 사용하였습니다. 그 결과 많은 프로젝트들이 똑같은 디자인처럼 보이게 되었습니다.</p><p>Shadcn Create 출시 이후 이러한 패러다임에 변화가 생길 겁니다.</p><p>이는 작은 업데이트가 아닙니다. Shadcn UI 기반 프로젝트들을 시작하고, 커스텀하고, 접근하는 방식에 있어 근본적인 변화가 있습니다.</p><h3>말뿐만이 아닌, 첫 커밋부터 시작하는 진정한 커스터마이징</h3><p>Shadcn UI의 목표는 첫 커밋부터 커스터마이징이었습니다. 하지만 실제로는 기본 설정값이 잘 작동했기 때문에 그대로 사용하였습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*6JnzfNQrrjbXlMEn.png" /></figure><p>새로 출시한 Shadcn Create에서는 첫 줄의 코드를 작성하기 전부터 커스터마이징이 가능합니다.</p><p>프로젝트를 초기화한 후 서서히 스타일을 조정하는 것 대신, 완전히 커스텀 된 디자인시스템으로 바로 시작할 수 있습니다.</p><p>Shadcn Create 서비스를 여는 순간, 완전 다른 경험을 할 수 있습니다. 새로운 편집기, 새로운 레이아웃, 그리고 가장 중요한 오른쪽에 있는 강력한 설정을 변경할 수 있는 사이드 바로 전체 UI 시스템을 시각적으로 변경할 수 있습니다.</p><h3>디자인시스템 기본 파운데이션 라이브러리로 Base UI 선택가능</h3><p>이번 업데이트의 가장 큰 변화 중 하나는 기본 파운데이션 UI 라이브러리로 Radix UI 뿐만 아니라 Base UI도 선택가능하게 된 것입니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*g6o6fHyuU-nh6ckk.png" /></figure><p>이제 기존 설정과 Base UI 중에서 기본 파운데이션 UI 라이브러리를 선택할 수 있습니다. 그러나 Base UI를 선택했을 때 시각적으로 아무런 변화가 없습니다. 이것은 UI는 똑같이 유지하지만 기본 파운데이션 UI 라이브러리만 바뀌는 것으로 의도된 동작입니다.</p><p>이러한 변경의 이유는 Shadcn이 오랫동안 의존해 온 Radix UI가 최근 유지보수가 잘 안 되고 있기 때문입니다. 알려진 문제점들이 존재하며 진행 속도도 느려졌습니다. 반면에 Base UI는 활발히 유지보수 되고 있으며, Radix UI 개발에 참여했던 일부 인력도 Base UI를 작업하고 있습니다.</p><p>요약하자면 Shadcn은 Radix UI보다 더 활발히 유지보수되고 있는 Base UI로 전환을 가능하게 해 미래를 대비하고 있습니다.</p><h3>새로 추가된 5가지 스타일</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hJh08py17QsRtGeg.png" /></figure><p>이번 업데이트는 단순히 색상 변경만 한 게 아닙니다.</p><p>Shadcn Create는 간격, 모양, 레이아웃 및 전체적인 느낌을 변화시키는 다섯 가지 새로운 시각적 스타일을 소개합니다.</p><ul><li>Vega는 대부분의 사람들이 이미 익숙한 가장 고전적인 스타일입니다.</li><li>Nova는 더 콤팩트합니다. 패딩이 적고, 마진이 좁습니다. 밀집도가 높은 인터페이스들에 잘 어울립니다.</li><li>Maia는 부드럽고 둥급니다. 친근하고 현대적인 느낌이 있습니다. 일부 input 디자인이 취향이 갈릴 순 있지만, 전체적인 미감은 매력적입니다.</li><li>Lyra는 각진 느낌과 날카로운 디자인입니다. 특히 mono 폰트와 잘 맞고 기술적이고 체계적인 느낌을 줍니다.</li><li>Mira는 콤팩트하며 정보 밀도가 중요한 고밀도 인터페이스를 위해 설계되었습니다.</li></ul><p>이러한 5가지 스타일은 단순 테마가 아니라 시스템 전반에 걸쳐 컴포넌트의 동작과 느낌에 영향을 끼칩니다.</p><h3>컬러 시스템, 브랜딩, 시각적 정체성</h3><p>스타일을 선택한 후에는 컬러 설정 항목으로 이동해 봅시다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*OqaKJqmTyi4oylf8.png" /></figure><p>기본 색상은 gray, zinc(아연), stone, neutral 중에서 선택할 수 있습니다. 각각 미묘한 차이가 있는데 gray는 약한 푸른빛, zinc는 센 보랏빛, stone은 따뜻한 느낌, neutral은 톤 없는 순수한 회색입니다.</p><p>다음은 테마 색상입니다. 이는 브랜드 컬러를 의미하며 만약 제품에 주요 브랜드 컬러가 있다면, 여기에 적용할 수 있습니다.</p><p>이 옵션들을 변경할 때마다 모든 변경 사항을 즉시 미리 볼 수 있습니다. 굳이 시스템의 모드를 바꾸지 않아도 상단에서 라이트모드와 다크모드를 전환해 볼 수도 있습니다.</p><h3>아이콘, 폰트, 반경(Border radius), 그리고 중요한 디테일들</h3><p>Shadcn Create에서는 아이콘 라이브러리도 선택할 수 있습니다. 이제 Lucide 아이콘뿐만 아니라 Tabler Icons나 HugeIcons 같은 다양한 옵션을 사용할 수 있습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*wJAn1W2OeFSCWVGW.png" /></figure><p>HugeIcons는 특히 언급할만합니다. 만약 대담하고 표현력 있는 비주얼을 선호한다면 이 아이콘들은 꽤 멋집니다.</p><p>반경 부분은 익숙할 겁니다. 소형, 중형, 대형과 같이 Shadcn 사용자들이 이미 알고 있는 동일한 반경 시스템이 프로젝트 생성 시점에 바로 적용됩니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ccjog8y7hlo8Sulu.png" /></figure><p>또한 메뉴 강조 표시 구성도 있으며, 이는 Base UI의 드롭다운 및 메뉴 컴포넌트들과 연관이 있어 보입니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*_9cpRQ3ZyrtHHA7q.png" /></figure><h3>셔플 기능은 모든 것을 바꿀 겁니다</h3><p>이번 업데이트의 가장 강력한 기능 중 하나는 셔플 기능입니다.</p><p>키보드의 R키를 누르면 모든 요소가 무작위로 변경됩니다. 스타일, 색상, 아이콘, 글꼴, 간격 등 모든 것이 포함됩니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*pR3l_lf05CLGrsz6.png" /></figure><p>이것은 단순한 눈속임이 아닙니다. 이 기능으로 스스로 생각하기 어려운 디자인 조합을 빠르게 탐색할 수 있습니다. 뭔가 마음에 드는 조합이 나올 때까지 계속 셔플 할 수 있습니다.</p><h3>컴포넌트 수준의 커스터마이징 그리고 새로운 빌딩 블록</h3><blockquote>역자 주: 빌딩 블록은 프로덕션 레벨에 바로 사용할 수 있도록 Shadcn UI 기반으로 구성된 완성된 컴포넌트 예제라고 생각하면 됩니다.</blockquote><p>왼쪽 사이드바에서 입력란, 버튼, 배지 등 개별 컴포넌트들을 선택할 수 있습니다. 여기서 설정을 변경했을 때 디자인시스템이 어떻게 바뀌는지 바로 확인할 수 있습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*MyqGWYupKsWzVbi5.png" /></figure><p>기본 컴포넌트들 외에도 Shadcn Create는 완전한 빌딩 블록 세트도 도입했습니다.</p><p>첫 번째 세트는 Elevenlabs 블록입니다. 이 블록들은 오디오 관련 UI에 중점을 둡니다. 시각화 도구, 파형, 사운드 관련 컴포넌트 등이 포함되며, 정말 놀라운 모습을 보여줍니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*tS3YNZN-BPhVhxHc.png" /></figure><p>다음 세트는 GitHub 블록입니다. 레포지토리 툴바, 프로필, 컨트리뷰션 그래프, 액티비티 피드, 이슈 할당 인터페이스, 계정 메뉴 등 GitHub UI를 현대적으로 재해석한 느낌을 줍니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*u4L_6AXaMzlahLp_.png" /></figure><p>다음은 Vercel 블록입니다. Vercel 플랫폼을 사용해 본 적이 있다면 즉시 알아볼 수 있는 애널리틱스 대시보드, 피드백 양식, UI 패턴들입니다. 미니멀하고 깔끔하며 매우 효과적입니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*eubbnydGMtp3G1xH.png" /></figure><p>마지막으로 ChatGPT 및 AI 관련 블록이 있습니다. 채팅 인터페이스, 메시지 레이아웃, AI 기반 애플리케이션에 필요한 모든 요소가 포함됩니다. 이미 수많은 AI 중심 UI 라이브러리가 존재하지만, Shadcn에 직접 내장되어 있어 바로 적용할 수 있는 게 강점입니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*fGR26JjS5fht6FKS.png" /></figure><h3>URL 매개변수를 이용한 공유 가능한 디자인시스템</h3><p>Shadcn Create가 설정을 처리하는 방식은 좀 어색할 수 있지만 꽤나 스마트한 디테일을 가지고 있습니다.</p><p>사용자가 설정을 변경할 때마다 검색 파라미터를 통해 URL을 갱신하고 이를 활용해 단일 링크로 전체 디자인시스템을 공유할 수 있습니다. 여기서 세팅한 정확한 설정을 상대방에게 전달하고, 상대방은 즉시 동일한 설정을 확인할 수 있습니다.</p><h3>예시</h3><pre>https://ui.shadcn.com/create?base=base&amp;theme=violet&amp;font=dm-sans&amp;item=chatgpt&amp;baseColor=stone&amp;menuAccent=bold&amp;iconLibrary=hugeicons</pre><p>이 방식은 현대적인 디자인시스템 빌더가 작동해야 하는 방식입니다.</p><h3>프로젝트 생성과 실제 코드 생성</h3><p>일단 좋아하는 스타일을 찾으면 클릭으로 프로젝트를 생성할 수 있습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*gMsaNPxpMuV0nYW_.png" /></figure><p>Next.js, Tanstack Start, Vite 중 하나의 프레임워크를 선택하고, npm, pnpm, yarn, bun 중 하나의 패키지 관리자를 선택하세요.</p><p>그런 다음 명령어를 복사하여 터미널에 붙여 넣고 애플리케이션의 이름을 지정하면 됩니다.</p><pre>npx shadcn@latest create --preset &quot;https://ui.shadcn.com/init?base=base&amp;style=vega&amp;baseColor=stone&amp;theme=violet&amp;iconLibrary=hugeicons&amp;font=dm-sans&amp;menuAccent=bold&amp;menuColor=default&amp;radius=default&amp;template=next&quot; --template next</pre><p>Shadcn Create는 사용자가 선택한 설정이 반영된 실제 프로젝트를 생성합니다. Base UI가 세팅되고, 컴포넌트 JSON이 준비되며, 사용자 스타일이 적용된 글로벌 CSS가 생깁니다. 첫 실행 전에 모든 것이 준비됩니다.</p><p>이제 애플리케이션을 실행하면 바로 작동합니다.</p><h3>부족한 점과 개선할 점</h3><p>이 업데이트는 강력하지만 아직 완벽하지는 않습니다.</p><p>일부 Base UI의 자동 완성 기능이 누락되어 있습니다. 드래그 앤 드롭 기능과 같은 몇몇 컴포넌트들은 아직 구현되지 않았습니다. 그리고 특정 컴포넌트들은 여전히 Radix UI의 기본요소들을 내부적으로 사용하고 있습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*pT3hMeTccydytSRn.png" /></figure><p>이를 보면 Base UI의 통합 과정이 아직 프로젝트 빌더 환경으로 제한되어 있고, 아직 모든 요소에 통합되지는 않은 것 같습니다.</p><p>하지만 이는 일시적이며 앞으로는 해결될 문제입니다.</p><h3>V0 통합 및 AI가 주도하는 UI 개발</h3><p>마지막으로 언급할 만한 업데이트는 ‘v0에서 열기’ 버튼입니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*4GfVMLd_raokd_r5.png" /></figure><p>한 번 클릭으로 전체 Shadcn 디자인시스템이 v0 내에서 열립니다. 여기서 AI 프롬프팅을 통해 설정된 컴포넌트로 직접 UI를 구축할 수 있습니다.</p><p>이는 비개발자나 빠른 프로토타이핑에 특히 유용합니다. UI 레이아웃을 생성하고 아이디어를 테스트한 후, 해당 코드를 실제 프로젝트로 가져올 수 있습니다.</p><h3>끝이 아닙니다.</h3><p>이번 업데이트로 모든 Shadcn 애플리케이션이 똑같이 보이진 않을 겁니다.</p><p>이제 진짜 디자인 시스템을 시작할 수 있습니다. 프로젝트 시작 전에 시각적 정체성과 의도와 개인의견을 논의하고, 이러한 결정에 기반하여 코드를 작성할 수 있습니다.</p><p>Shadcn UI는 단순한 컴포넌트 집합체가 아닙니다. 완전한 디자인 시스템으로 진화하고 있고 이건 시작에 불과합니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=97dd2b193615" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[번역] 리액트 19.2.0의 새로운 기능]]></title>
            <link>https://siosio3103.medium.com/%EB%A6%AC%EC%95%A1%ED%8A%B8-19-2-0%EC%9D%98-%EC%83%88%EB%A1%9C%EC%9A%B4-%EA%B8%B0%EB%8A%A5-ebda8956006f?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/ebda8956006f</guid>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Sat, 25 Oct 2025 04:05:07 GMT</pubDate>
            <atom:updated>2025-10-25T04:05:27.101Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>원문: <a href="https://medium.com/@onix%3Cem%3Ereact/whats-new-in-react-19-2-0-04b9019ceb27">https://medium.com/@onix<em>react/whats-new-in-react-19-2-0-04b9019ceb27</em></a></blockquote><p>리액트 19.2.0는 컴포넌트 생명주기 관리 방식을 다듬고, 렌더링 성능을 최적화하며, 서버 사이드 렌더링(SSR) 워크플로를 간소화하는 중요한 개선 사항을 도입했습니다. 이번 릴리스는 지난 1년간 리액트 19와 19.1에 이어 나온 세 번째 버전으로, 더 빠르고 효율적이며 상태를 보존하는 애플리케이션을 만들 수 있도록 새로운 기능을 제공합니다.</p><p>이번 최신 업데이트를 살펴보며, 새로운 기능들이 개발 방식을 어떻게 혁신하고 애플리케이션 효율을 높여주는지 알아보겠습니다.</p><blockquote>이전 버전에 관심이 있다면 다음 링크에서 리액트 19의 상세 내용을 확인할 수 있습니다. <a href="https://ritviknag.com/markdown-to-medium/&#39;https://medium.com/@onix_react/whats-new-in-react-19-1-0-d87dda0905a9">리액트 19.1.0의 새로운 기능</a></blockquote><h3>새로운 리액트 기능들 ⚙️</h3><h3>Activity: 컴포넌트의 보이는 유무와 우선순위를 제어</h3><p>Activity 컴포넌트는 애플리케이션을 서로 구분되는 &quot;활성 영역”으로 나누고, 각 활성 영역에 대해 별도의 우선순위를 부여하고 독립적으로 관리할 수 있는 메커니즘을 제공합니다. 특히 현재 보이지 않는 요소의 상태를 유지해야 하는 경우에 기본적인 조건부 렌더링보다 더 뛰어난 해결책을 제공합니다.</p><pre>// 이전<br>{isVisible &amp;&amp; &lt;Page /&gt;}<br> <br>// 이후<br>&lt;Activity mode={isVisible ? &#39;visible&#39; : &#39;hidden&#39;}&gt;<br>  &lt;Page /&gt;<br>&lt;/Activity&gt;</pre><p>리액트 19.2에서 Activity는 기본적으로 두 가지 모드를 지원합니다.</p><ul><li><strong>hidden:</strong> 자식요소가 숨겨지고, 해당 이펙트는 언마운트되며, 리액트가 처리할 작업이 더 이상 없을 때까지 모든 업데이트가 연기됩니다.</li><li><strong>visible:</strong> 자식이 표시되고, 이펙트가 마운트 되며, 업데이트가 정상적으로 처리됩니다.</li></ul><p>이 기능은 백그라운드 작업에 매우 적합하며, 다음 내비게이션 단계에 필요한 컴포넌트나 데이터를 미리 로드할 수 있고, 사용자가 다른 화면으로 전환할 때 폼 입력값과 스크롤 위치를 유지하도록 해 줍니다.</p><h3>useEffectEvent: 이벤트와 이펙트 분리</h3><p>useEffect의 의존성 배열에 props나 state 변수를 나열해야 한다는 점으로 인해 복잡성은 자주 발생합니다. 이로 인해 이펙트가 불필요하게 다시 실행되는 경우가 많습니다. 새로운 useEffectEvent 훅은 “이벤트 핸들러”에 해당하는 콜백 함수를 정의하게 하여, 이를 이펙트의 의존성 추적 밖에서 동작하도록 할 수 있습니다.</p><p>useEffectEvent로 생성된 함수는 항상 최신의 props와 state를 참조하지만, 해당 함수를 사용하는 이펙트의 의존성으로는 추가하지 않아도 됩니다.</p><pre>const onConnected = useEffectEvent(() =&gt; {<br>    /****<br>     ** 이 함수는 theme 변경 시 아래 이펙트가 재실행되지 않도록<br>     ** 항상 최신 &#39;theme&#39;를 가져옵니다.<br>    **/<br>    showNotification(&#39;Connected!&#39;, theme);<br>  });<br> <br>  useEffect(() =&gt; {<br>    const connection = createConnection(serverUrl, roomId);<br>    connection.on(&#39;connected&#39;, () =&gt; {<br>      onConnected(); // 이벤트 함수 호출<br>    });<br>    connection.connect();<br>    return () =&gt; connection.disconnect();<br>  }, [roomId]); // ✅ &#39;onConnected&#39;를 의존성에 추가하지 않아도 됨</pre><p><strong><em>참고</em></strong>: 이 새로운 기능을 올바르게 도입하고 사용 규칙을 강제하려면 eslint-plugin-react-hooks@6.1.0으로 업데이트해주세요.</p><h3>서버 컴포넌트 리소스 관리를 위한 cacheSignal</h3><p>리액트 서버 컴포넌트에서만 사용할 수 있는 cacheSignal 유틸리티는 AbortSignal을 반환합니다. 이 신호는 리소스 관리에 매우 핵심적인 역할을 합니다. 컴포넌트의 cache() 범위가 만료될 때 발생하여 개발자가 진행 중인 비동기 작업(예: 확장된 데이터 가져오기)을 즉시 중지하거나 정리할 수 있게 합니다.</p><ul><li>이 신호는 중복 제거 작업에 대한 라이프사이클 관리를 제공하며, 다음 상황에서 발생합니다.</li><li>렌더링이 성공적으로 완료될 때.</li><li>렌더링 과정이 명시적으로 중단될 때.</li><li>렌더링 도중 실패가 발생할 때.</li></ul><pre>import {cache, cacheSignal} from &#39;react&#39;;<br>const dedupedFetch = cache(fetch);<br> <br>async function Component() {<br>  await dedupedFetch(url, { signal: cacheSignal() });<br>}</pre><h3>Chrome DevTools의 성능 트랙킹</h3><p>리액트 19.2는 Chrome DevTools의 Performance 패널에 맞춤 트랙을 통합하여, 애플리케이션 런타임 특성에 대한 뛰어난 인사이트를 제공합니다.</p><ul><li><strong>Scheduler ⚛️:</strong> 리액트 내부의 작업 우선순위를 시각화하여, 사용자 입력과 같은 높은 우선수위 작업(“blocking”)과 낮은 우선순위 작업(“transition”)을 구분해 보여줍니다. 이를 통해 업데이트의 실행 순서와 실행이 중단되는 시점을 명확히 파악할 수 있습니다.</li><li><strong>Components ⚛️:</strong> 렌더링인지 이펙트 실행인지에 따라 컴포넌트 처리의 계층적 흐름을 표시합니다. 이를 통해 한 프레임 동안 어떤 컴포넌트가 시간을 가장 많이 소모하는지 정확히 파악할 수 있습니다.</li></ul><h3>새로운 리액트 DOM 기능들 🚀</h3><h3>부분 프리렌더링: 가속화된 정적 부분 제공 후 렌더링 재개</h3><p>부분 프리렌더링 기술 덕분에 상당한 로드 시간 성능 개선을 할 수 있게 되었습니다. 이 방식은 애플리케이션의 정적 HTML 셀을 CDN을 통해 빨리 제공하고, 이후 렌더링을 재개하여 동적이고 사용자에 따라 다른 데이터를 주입할 수 있게 해 줍니다.</p><p>새로운 API들은 견고한 2단계로 이루어진 배포 패턴을 지원합니다.</p><ol><li><strong>첫 번째 단계: 정적 Prelude 프리렌더링:</strong> prerender API를 사용해 초기 정적 HTML(prelude)과 애플리케이션의 남은 렌더링 작업을 포함한 postponed 상태를 생성합니다.</li></ol><pre>const {prelude, postponed} = await prerender(&lt;App /&gt;, {<br>  signal: controller.signal,<br>});<br> <br>// 나중을 위해 postponed 상태 저장<br>await savePostponedState(postponed);<br> <br>// prelude 부분 사용자 혹은 CDN에게 전달.</pre><p><strong>2. 두 번째 단계: 렌더링 재개:</strong> postponed 상태를 resume 계열 API를 사용해서 렌더링을 마무리합니다. 결과는 다음과 같습니다.</p><p><strong>SSR 스트리밍의 경우</strong>: resume(웹 스트림) 혹은 resumeToPipeableStream(노드 스트림)을 사용합니다.</p><pre>const postponed = await getPostponedState(request);<br>const resumeStream = await resume(&lt;App /&gt;, postponed);<br>// resumeStream 부분을 클라이언트에게 전송.</pre><p><strong>SSG인 경우</strong>: resumeAndPrerender를 사용해 완전한 정적 파일 출력을 생성합니다.</p><pre>const postponedState = await getPostponedState(request);<br>const { prelude: completeHTML } = await resumeAndPrerender(&lt;App /&gt;, postponedState);<br>// completeHTML 부분을 디스크 혹은 CDN으로 전송</pre><p>이러한 새 API들은 react-dom/server(resume, resumeToPipeableStream)와 react-dom/static(resumeAndPrerender, resumeAndPrerenderToNodeStream)에 포함되어 있습니다.</p><h3>주요 변경사항 🛠️</h3><h3>SSR를 위한 Suspense 경계 일괄 처리</h3><p>클라이언트 렌더링과 스트리밍 SSR에서 Suspense 경계가 서로 다르게 드러나던 동작상의 버그가 수정되었습니다.</p><p>리액트 19.2부터 서버에서 드러나는 Suspense 경계를 잠시 동안 일괄 처리하여 더 많은 콘텐츠가 한꺼번에 표시되도록 하고, 클라이언트 렌더링과의 동작을 맞춥니다. 또한 이는 SSR에서 &lt;ViewTransition&gt;을 대비해 더 큰 덩어리의 콘텐츠를 한 번에 드러내도록 해 더 매끄러운 애니메이션을 가능하게 합니다.</p><p><strong><em>참고:</em></strong><em> 리액트는 일괄 처리가 Core Web Vitals에 악영향을 주지 않도록 휴리스틱을 사용합니다. 예를 들어 페이지 로드가 2.5초 LCP 임계값에 가까워지면, 적시에 콘텐츠를 표시하기 위해 일괄 처리를 건너뜁니다.</em></p><h3>Node.js에서의 SSR용 웹 스트림 지원</h3><p>Node.js 환경에서의 스트리밍 서버 사이드 렌더링(SSR)이 이제 공식적으로 웹 스트림을 지원합니다. 이에 따라 아래와 같은 현대적인 Readable 스트림 API를 사용할 수 있습니다.</p><ul><li>renderToReadableStream</li><li>prerender</li><li>resume</li><li>resumeAndPrerender</li></ul><p><em>⚠️ </em><strong><em>주의:</em></strong><em> Node.js 환경에서는 네이티브 Node Streams API(renderToPipeableStream, resumeToPipeableStream 등)를 권장합니다. 이들은 일반적으로 Node에서 웹 스트림보다 훨씬 빠르며, 기본적으로 압축을 지원합니다. 웹 스트림을 직접 사용할 경우 이러한 이점을 놓칠 수 있습니다.</em></p><h3>eslint-plugin-react-hooks v6</h3><p>eslint-plugin-react-hooks@6.1.0가 다음과 함께 제공됩니다.</p><ul><li>권장 프리셋에서 Flat config가 기본값으로 적용됩니다.</li><li>React Compiler 기반의 선택적 규칙을 제공합니다.</li></ul><p>기존 구성 방식을 계속 사용하려면 다음과 같이 설정하세요.</p><pre>- extends: [&#39;plugin:react-hooks/recommended&#39;]<br>+ extends: [&#39;plugin:react-hooks/recommended-legacy&#39;]</pre><h3>useId Prefix 업데이트</h3><p>useId 훅이 생성하는 ID의 기본 Prefix가 :r: (19.1에서는 «r»)에서 <em>r</em>로 변경되었습니다.</p><p>이번 변경은 View Transitions 지원을 위해 필요한 현대적 웹 기능(예: view-transition-name CSS 속성 및 일반적인 XML 1.0 명명 규칙)에서 useId가 생성하는 값이 유효하도록 보장하기 위함입니다.</p><h3>추가 변경사항 🛸</h3><h3>주목할 만한 변경 사항</h3><ul><li>react-dom: hoistable 스타일에 nonce 속성을 사용할 수 있도록 허용.</li><li>react-dom: 텍스트 콘텐츠가 이미 있는 리액트 소유 노드를 컨테이너로 사용할 때 경고를 추가.</li></ul><h3>버그 수정</h3><ul><li><strong>Context:</strong> 콘텍스트 문자열화를 수정하여 &quot;SomeContext.Provider&quot; 대신 &quot;SomeContext&quot;로 표시되도록 함.</li><li><strong>Hooks:</strong> popstate 이벤트 동안 useDeferredValue에서 발생하던 무한 루프 버그를 수정.</li><li><strong>Client Actions:</strong> Client Actions를 사용하는 폼 제출 시 발생하던 크래시를 수정.</li><li><strong>Suspense:</strong> 다시 suspend 되는 경우, dehydrated 된 Suspense 경계의 콘텐츠를 숨기거나 다시 표시하는 동작을 개선.</li><li><strong>Debugging:</strong> 다양한 상황에서 컴포넌트 스택을 개선하여 디버깅 경험 향상.</li><li><strong>DOM:</strong> ARIA 1.3 속성 사용 시 발생하던 경고를 중단.</li><li><strong>SSR:</strong> 렌더링 도중 abort 이후 스트리밍이 멈춰버리던 문제를 수정.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ebda8956006f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[번역] 클로드 코드를 10배로 잘 활용할 수 있는 15가지 방법]]></title>
            <link>https://siosio3103.medium.com/%EB%B2%88%EC%97%AD-%ED%81%B4%EB%A1%9C%EB%93%9C-%EC%BD%94%EB%93%9C%EB%A5%BC-10%EB%B0%B0%EB%A1%9C-%EC%9E%98-%ED%99%9C%EC%9A%A9%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8A%94-15%EA%B0%80%EC%A7%80-%EB%B0%A9%EB%B2%95-24ea82c93363?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/24ea82c93363</guid>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Sun, 07 Sep 2025 10:06:25 GMT</pubDate>
            <atom:updated>2025-09-07T10:06:25.732Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>원문: <a href="https://medium.com/@joe.njenga/15-pro-tricks-that-make-claude-code-go-x10-crazy-amateur-vs-pro-devs-e41aeeeda1ea">https://medium.com/@joe.njenga/15-pro-tricks-that-make-claude-code-go-x10-crazy-amateur-vs-pro-devs-e41aeeeda1ea</a></blockquote><blockquote>작성자: <a href="https://medium.com/@joe.njenga">Joe Njenga</a></blockquote><p><em>초보자처럼 클로드 코드</em> 를 쓰는 것을 멈추세요. 앞으로 알려드릴 방법이 여러분의 작업 방식을 즉시 바꿀 것입니다.</p><p>대부분의 개발자들은 클로드 코드를 완전히 잘못 사용하고 있습니다.</p><p>그들은 <strong>“이 버그 고쳐”</strong> 또는 <strong>“함수를 추가해”</strong> 같은 단순한 요청만 하고는, 왜 자신은 모두가 말하는 생산성의 향상을 얻지 못하는지 의아해합니다.</p><blockquote>반면 전문가들은 숨겨진 기능을 활용하여 클로드 코드를 스스로 생각하고, 계획하고, 복잡한 아키텍처를 결정하는 시니어 개발자로 만듭니다.</blockquote><h3>방법 #1: 복잡한 문제에는 “Think Mode” 활성화하기</h3><p>99%의 개발자가 모르는 것이 있습니다. 바로 클로드 코드에는 특정 단어를 사용할 때 활성화되는 숨겨진 추론 모드가 있다는 점입니다.</p><p>대부분 “사용자 인증을 어떻게 구현하나요?”와 같은 단순한 질문만 하고 기본적인 답변만 받습니다.</p><blockquote>반면 전문가들은 “확장 가능한 인증 시스템 아키텍처를 생각해”와 같이 구체적인 질문을 하고 훨씬 더 좋은 답변을 받습니다.</blockquote><blockquote><strong>프롬프트에 “think”라는 단어를 포함하면, 클로드 코드는 확장된 추론 모드로 전환됩니다.</strong></blockquote><blockquote>역자주: think 단어 말고도 megathink, ultrathink라는 단어를 포함하면 속도는 느리지만 훨씬 더 고품질의 답변을 받을 수 있습니다. 자세한 내용은 <a href="https://www.ultrathink.engineer/">https://www.ultrathink.engineer/</a> 를 참고해 주세요. 한글로 질문하더라도 더 좋은 답변이 필요하면은 think, megathink, ultrathink 같은 단어는 포함하시는 게 좋습니다.</blockquote><p>이 방법은 즉시 코드를 작성하는 것 대신에, 문제를 분석하고, 에지케이스를 고려하며, 아키텍처의 트레이드오프를 평가하고, 시니어 아키텍트처럼 구현 전략을 설계합니다.</p><h3>아마추어</h3><p><em>로그인 시스템 만들어줘</em></p><h3>전문가</h3><p><em>리액트 앱과 Node.js 백엔드를 기반으로 한 안전하고 확장 가능한 사용자 인증 시스템을 구축하는 방법을 깊이 생각해. JWT와 세션의 비교, 비밀번호 보안, 요청 제한, 그리고 기존 사용자 관리 시스템과의 통합 방법까지 고려해.</em></p><h3>방법 #2: 프로젝트 범위의 MCP 서버 사용하기</h3><p>다른 사람들이 여전히 기본적인 클로드 코드 기능만 사용하는 동안, 전문가들은 MCP 서버를 사용합니다.</p><blockquote>클로드 코드는 개발 환경에 직접 통합되는 커스텀 툴로 확장될 수 있습니다.</blockquote><blockquote>데이터베이스 연결, API 통합, 배포 파이프라인, 모니터링 시스템 등 모든 것을 자연어 명령어로 사용할 수 있습니다.</blockquote><h3>프로젝트 범위의 MCP 서버</h3><p>프로젝트 루트에 .mcp.json 파일만 생성하면, 팀 전체가 업그레이드된 클로드 코드 환경에서 작업할 수 있게 됩니다.</p><p>“내 PC에서는 잘되는데요?”같은 재앙은 일어나지 않고, 새 개발자가 환경 설정에 며칠을 낭비하는 온보딩 악몽도 사라집니다.</p><h3>클로드 코드 기본적인 MCP 설정</h3><pre>{<br>  &quot;mcpServers&quot;: {<br>    &quot;database&quot;: {<br>      &quot;command&quot;: &quot;npx&quot;,<br>      &quot;args&quot;: [&quot;@modelcontextprotocol/server-postgres&quot;],<br>      &quot;env&quot;: {<br>        &quot;POSTGRESCONNECTIONSTRING&quot;: &quot;postgresql://localhost:5432/myapp&quot;<br>      }<br>    },<br>    &quot;filesystem&quot;: {<br>      &quot;command&quot;: &quot;npx&quot;,<br>      &quot;args&quot;: [&quot;@modelcontextprotocol/server-filesystem&quot;],<br>      &quot;args&quot;: [&quot;/path/to/project&quot;]<br>    }<br>  }<br>}</pre><h3>전문가</h3><p>사용자 테이블을 쿼리 하고, 스키마를 분석한 후, 검증·에러 처리·테스트까지 포함된 완전한 CRUD API를 생성하세요. 또한 현재 배포 상태를 점검하고 최적화 방안을 제안하세요.</p><h3>방법 #3: 자연어 기반 Git 워크플로우 활용하기</h3><p>대부분의 개발자들은 오래된 방식의 Git 사용법에 머물러 있습니다. 여전히 git add, git commit, git push 같은 명령어를 수동으로 실행하는 반면, 전문가들은 대화형 명령어로 전체 개발 워크플로우를 조율합니다.</p><blockquote>Git을 외워둔 터미널 명령어 모음처럼 다루는 것을 멈추세요.</blockquote><p>대신 Git을 문맥과 의도, 그리고 모범 사례까지 이해하는 AI 자동화 시스템처럼 다루세요.</p><h3>아마추어</h3><pre>git checkout -b feature/user-auth<br>#... 코드작성...<br>git add .<br>git commit -m &quot;로그인 작업추가&quot;<br>git push origin feature/user-auth</pre><h3>전문가의 워크플로우</h3><p><em>Google Oauth2 인증을 구현하기 위한 feature 브랜치를 생성하세요. 리다이렉트 처리, 토큰 관리, 사용자 세션 유지를 포함한 전체 플로우를 구현하세요. 팀의 커밋 규칙을 따르고, 각 변경마다 상세한 커밋 메시지를 작성하세요. 이후 적절한 문서를 포함한 풀 리퀘스트를 생성하고, 보안팀을 태그 하여 리뷰를 요청하세요.</em></p><h3>개선된 워크플로우</h3><p><em>현재 브랜치를 분석하여 스타일 가이드 위반 코드를 찾고 수정하세요. 코드를 머지하기 전 전체 커밋을 리베이스 하여 깔끔한 히스토리를 유지하세요. 또한 의존성 업데이트가 필요한지 확인하고, 별도의 커밋으로 처리하세요.</em></p><h3>방법 #4: 방어적 코딩 전략 활용하기</h3><p>클로드 코드의 방어적 프로그래밍 집착을 이용해, 실패가 발생하기 전에 이를 예측하는 탄탄한 코드를 작성하세요.</p><blockquote>클로드 코드는 코드가 실패할 수 있는 모든 경우를 보안 전문가처럼 사고하여 탄탄한 코드를 만들 수 있습니다.</blockquote><h3>아마추어</h3><p><em>결제 처리 함수를 만들어줘</em></p><h3>전문가</h3><p><em>TDD 원칙을 적용하여, 먼저 결제 처리 시스템에 대한 포괄적인 테스트를 작성하세요. 이 시스템은 네트워크 실패, 잘못된 카드 데이터, 요청 제한, 멱등성, 부분 결제와 같은 에지 케이스를 모두 다룹니다. 모든 테스트를 통과하도록 함수를 구현하세요. 또한 적절한 로깅, 서킷 브레이커 패턴, 우아한 장애 대응까지 포함해야 합니다.</em></p><h3>방법 #5: 다중 파일 리팩토링 작업 연결하기</h3><p>많은 개발자들 “리팩토링”을 단순히 변수 이름을 바꾸거나 함수를 추출하는 정도로만 생각합니다.</p><p>그들은 파일 하나, 기껏해야 두 개 정도를 수정하고 일을 끝냈다고 생각합니다.</p><blockquote>그러나 중요한 아키텍처 수준의 변경을 두려워하기 때문에 코드베이스는 내부부터 썩어가기 시작합니다.</blockquote><h3>아마추어</h3><p><em>이 함수를 여러 개의 파일로 분리해 줘</em></p><h3>전문가</h3><p><em>리액트 컴포넌트들에 모든 인증 로직을 중앙 집중된 인증 서비스로 분리하세요. 코드베이스의 import를 업데이트하고, 기존의 API 호출을 새로 만든 함수를 사용하는 걸로 변경하세요. 적절한 타입스크립트 인터페이스를 추가하고, 일관된 에러 처리 패턴을 구현하며, 테스트 파일도 업데이트하여 새 함수를 모킹 하도록 하세요. 또한 유틸리티 파일에 하드코딩 된 인증 로직이 있는지 찾고 이를 마이그레이션 하도록 하세요.</em></p><h3>개선 버전</h3><p><em>우리의 유저 관리 로직은 15개의 다른 파일에 분산되어 있습니다. 이를 명확한 경계를 가진 적절한 도메인 주도 설계(DDD) 패턴으로 통합하세요. 유저 엔티티, 레포지토리, 서비스 계층을 만들어 기존 코드를 새로운 아키텍처로 업데이트하세요. 업데이트 과정에서 하위 호환성을 보장하고, 데이터 구조 변경이 필요한 경우 마이그레이션 스크립트도 작성하세요.</em></p><h3>방법 #6: 저수준, 비간섭적인 설계를 활용하기</h3><p>클로드 코드가 다른 AI 코딩 도구와 다른 점은 <strong>개발이 어떻게 진행되어야 하는지 다른 누군가가 정한 방식을 강제하지 않습니다</strong>.</p><p>Github 코파일럿이나 다른 도구들은 자신들이 선호하는 패턴이나 워크플로우로 사용자들을 유도합니다.</p><blockquote>그러나 클로드 코드는 모델의 능력에 직접 접근할 수 있도록 합니다.</blockquote><p>대부분의 개발자들은 이 점을 완전히 놓칩니다. 클로드 코드를 단순한 자동완성 도구처럼 쓰며, 기본적으로 제공되는 단순한 제안만 받아들입니다.</p><p>전문가들은 자신들이 훨씬 더 강력한 도구를 다루고 있음을 알고, 바로 팀의 고유한 프로세스에 맞춰 AI를 완전히 커스텀합니다.</p><h3>아마추어</h3><p><em>리액트 컴포넌트 작성 좀 도와줘</em></p><h3>전문가</h3><p><em>우리 팀의 특정 아키텍처를 이해하세요. 우리는 render props를 활용한 합성 컴포넌트, 상태 관리를 위한 커스텀 훅, 그리고 에러 바운더리 패턴을 사용합니다. 모든 컴포넌트는 우리의 디자인 시스템 간격 토큰과 접근성 가이드라인을 따라야 합니다. 이를 참고해서 주니어 개발자들에게 템플릿으로 쓸 수 있는 사용자 프로필 컴포넌트를 작성하세요</em></p><h3>개선버전</h3><p><em>우리 팀의 커스텀 로깅 포맷 사용, Git 커밋 메시지 규칙 준수, 특정 에러 처리 패턴 구현, 그리고 항상 표준 코드 리뷰 체크리스트를 참고해서 답변을 조정하세요. 앞으로 이 프로젝트의 모든 작업에 이러한 사항을 기억하고 반영하세요</em></p><h3>방법 #7: 문맥을 이해하는 코드 문서화 활용하기</h3><p>문서화는 많은 개발자들이 전문성을 보여주는 영역입니다.</p><p>과거에 머문 개발자들은 이 코드가 무얼 하는지만 설명하는 주석을 달거나, 작성 즉시 관리가 안 되는 README 파일들을 만듭니다.</p><blockquote>또한 함수에 대한 설명만 할 뿐, 그 뒤의 비즈니스 로직은 전혀 없는 API 문서를 만들기도 합니다.</blockquote><p>그러나 전문가들은 클로드 코드가 단순히 코드를 문서화하는 데 그치지 않고, 시스템 아키텍처 전반을 이해하여 더 나은 소프트웨어를 만들 수 있도록 돕는 문서를 작성합니다.</p><h3>아마추어</h3><p><em>이 함수 문서화해</em></p><h3>전문가</h3><p><em>모든 파일에서 사용자 인증 시스템을 분석하고, 아키텍처적 결정, 보안 고려사항, 컴포넌트 간 데이터 흐름, 잠재적 실패 지점, 그리고 전체 애플리케이션 아키텍처와 통합하는 포괄적인 문서를 작성하세요. 또한 전체 인증 플로우를 보여주는 시퀀스 다이어그램과, 일반적인 이슈 해결을 위한 의사 결정 트리도 포함하세요.</em></p><h3>방법 #8: 고급 프롬프팅 기술 익히기</h3><p>대부분의 개발자들은 첫 출근한 주니어 개발자와 대화하듯 클로드 코드에게 질문합니다.</p><p>요구사항은 모호하고, 조건은 불분명하며, 맥락도 없습니다.</p><p>반면 전문가들은 클로드 코드랑 어떻게 소통해야 시니어 아키텍트 수준의 사고를 이끌어낼 수 있는지 정확히 알고 있습니다.</p><h3>아마추어</h3><p><em>이 코드를 더 빠르게 만들어줘</em></p><h3>전문가</h3><p><em>이 함수의 성능 병목 현상을 Big O 분석을 사용해 분석하세요. 데이터 접근패턴, 알고리즘 복잡도, 메모리 사용에서의 비효율성을 구체적으로 파악하세요. 시간 복잡도 위주, 공간 복잡도 위주, 유지보수성 위주 총 3가지 관점에서 최적화 방법을 알려주세요. 각 접근법마다 최적화 전/후의 벤치마크를 보여주고, 트레이드오프를 설명하세요. 답변은 분속, 권장사항, 구현, 테스트 전략 순으로 명확한 섹션으로 구분해 주세요.</em></p><h3>개선버전</h3><p><em>문맥: [시스템 아키텍처 설명]</em></p><p><em>제약 조건: [기술적 한계와 요구사항 나열]</em></p><p><em>목표: [달성하고자 하는 구체적이고 측정 가능한 결과]</em></p><p><em>형식: [답변이 어떤 구조로 작성되길 원하는지]</em></p><p><em>예시: [좋은/나쁜 해결책의 사례 제시]</em></p><p><em>검증: [해결책이 작동하는지 검증하는 방법]</em></p><p><em>이제 위 프레임워크를 따라 [구체적인 문제]를 해결하세요.</em></p><h3>방법 #9: 지능형 코드 검색 활용하기</h3><p>대부분의 개발자들은 코드베이스를 수동으로 검색합니다.</p><p>그들은 함수 이름을 grep으로 찾거나, 문자열을 검색하거나, 특정 로직이 어디에 있는지, 왜 특정 결정이 내려졌는지 또는 시스템의 다른 부분들과 어떻게 연결되었는지 찾느라 많은 시간을 허비합니다.</p><p>하지만 전문가들은 클로드 코드가 초지능적인 코드 고고학자처럼, 인간 개발자라면 몇 주가 걸릴 패턴, 관계, 기술 부채 파악을 즉각적으로 할 수 있다는 사실을 알아냈습니다.</p><h3>아마추어</h3><p><em>유저 인증을 처리하는 부분을 찾아줘</em></p><h3>전문가</h3><p><em>코드베이스 전체를 분석해서 모든 인증 관련 로직을 파악하세요. 여기에는 직접 구현한 부분, 헬퍼 함수, 미들웨어, 훅 그리고 컴포넌트 곳곳에 흩어져 있는 하드코딩된 인증 검사까지 포함합니다. 인증 구현 간의 관계를 도식화하고, 인증 패턴의 불일치 문제를 찾아내고, 잠재적인 보안 취약점이나 코드가 중복된 부분을 알려주세요.</em></p><h3>방법 #10: 커스텀 MCP 서버 체인 구축하기</h3><p>클로드 코드를 단지 멋진 챗봇정도로 여기지 마세요. 전문가들은 MCP 서버들을 체인 형태로 연결해서, 인간의 개입 없이도 복잡한 다단계 작업을 수행하는 개발 파이프라인을 만드는 방법을 발견했습니다.</p><blockquote>대부분의 개발자들은 MCP 서버를 서로 연결할 수 있다는 사실조차 모릅니다.</blockquote><p>그들은 하나, 많아봐야 두 개 정도의 서버만 실행합니다.</p><p>반면 전문가들은 코드 분석부터 배포 자동화까지 모든 것을 처리하는 정교한 자동화 네트워크를 만들고 있습니다.</p><h3>아마추어</h3><pre>{<br>  &quot;mcpServers&quot;: {<br>    &quot;database&quot;: {<br>      &quot;command&quot;: &quot;npx&quot;,<br>      &quot;args&quot;: [&quot;@modelcontextprotocol/server-postgres&quot;]<br>    }<br>  }<br>}</pre><h3>전문가</h3><pre>{<br>  &quot;mcpServers&quot;: {<br>    &quot;codeAnalysis&quot;: {<br>      &quot;command&quot;: &quot;node&quot;,<br>      &quot;args&quot;: [&quot;./custom-servers/code-analyzer.js&quot;]<br>    },<br>    &quot;testRunner&quot;: {<br>      &quot;command&quot;: &quot;node&quot;, <br>      &quot;args&quot;: [&quot;./custom-servers/test-orchestrator.js&quot;]<br>    },<br>    &quot;deploymentPipeline&quot;: {<br>      &quot;command&quot;: &quot;node&quot;,<br>      &quot;args&quot;: [&quot;./custom-servers/deploy-manager.js&quot;]<br>    },<br>    &quot;securityScanner&quot;: {<br>      &quot;command&quot;: &quot;node&quot;,<br>      &quot;args&quot;: [&quot;./custom-servers/security-audit.js&quot;]<br>    }<br>  }<br>}</pre><p>전문가들은 복잡한 작업에서도 권한 확인 과정을 건너뛰고 한 번에 실행하는 one-shot 모드를 사용합니다. 예시 프롬프트는 아래와 같습니다.</p><p><em>코드베이스를 분석해 보안 취약점을 찾고, 수정된 부분에 대한 자동 테스트를 실행하세요. 보안 패치가 적용된 의존성을 업데이트하고, 적절한 문서를 포함해 변경 사항을 커밋하세요. 배포 파이프라인을 실행해 스테이징 환경에 배포하고, 배포된 버전에 대해 보안 스캔을 수행하세요. 모든 검증이 통과되면, 롤백 전략을 갖춘 상태에서 프로덕션에 배포하세요.</em></p><blockquote>이 단 하나의 명령으로 MCP 서버들이 연속적으로 실행되며, 각 단계를 자동으로 처리합니다.</blockquote><h3>방법 #11: 개발 워크플로우 설계하기</h3><p>대부분의 개발자들은 설정 파일을 제대로 이해하지 못한 채로 복사와 붙여 넣기를 실행합니다.</p><p>그러다 문제가 생기면 막히게 되고, 프로젝트를 전환하면 모든 것이 다르게 동작합니다.</p><p>새로운 팀원이 합류하면 그들의 한경 설정은 완전히 달라지고, 아무도 그것을 고치는 방법을 알지 못합니다.</p><blockquote>그러나 전문가들은 클로드 코드를 데브옵스 아키텍처처럼 활용해서, 에지케이스를 다루고 팀 전체에 확장 가능한 견고한 워크플로우를 설계하는 방법을 발견했습니다.</blockquote><h3>아마추어</h3><p><em>이 리액트 앱에 핫 리로드 설정을 추가해 줘</em></p><h3>전문가</h3><p><em>우리의 리액트/노드 스택을 위한 포괄적인 개발 환경을 설계하세요. 해당 개발 환경은 상태 유지가 되는 핫 리로드, 페이지 새로고침이 없는 CSS 주입, 백엔드 통합을 위한 API 프락시 설정, 단계별 환경 변수 관리, 유용한 개발 메시지를 제공하는 에러 바운더리 설정, 디버깅을 위한 올바른 소스 매핑의 요구사항을 만족해야 합니다. 각 요소가 어떻게 동작하는지 그리고 문제 해결 방법까지 이해할 수 있도록 설명하세요</em></p><h3>개선버전</h3><p><em>우리 팀을 위한 개발 워크플로우 전략을 만드세요. 해당 워크플로우는 새로운 개발자 온보딩 시 일관된 환경을 제공해야 하고, 로컬/스테이징/프로덕션의 환경 변수를 따로 관리해야 하며, 개발 중 데이터베이스 마이그레이션 조율을 할 수 있어야 합니다. 그리고 기능 개발 시 API 버전 관리를 할 수 있어야 하고, 개발 환경이 프로덕션 아키텍처를 확실히 반영하도록 해야 합니다. 또한 스크립트, 문서, 문제 해결 가이드도 포함하세요.</em></p><h3>방법 #12: 문맥 기반 디버깅 명령어 사용하기</h3><p>디버깅 과정에서도 대부분의 개발자들이 과거 방식에 머물러 있습니다. 그들은 console.log를 빵부스러기처럼 여기저기 찍어두거나, 브레이크 포인트를 설정하거나, 심지어는 에러 메시지를 멍하니 바라봅니다.</p><blockquote>그러나 전문가들은 클로드 코드가 복잡한 로직 흐름을 추적하고, 근본적인 원인을 찾거나, 디버거를 직접 열지 않고도 수정 방안을 제시할 수 있다는 사실을 발견했습니다.</blockquote><h3>아마추어</h3><p><em>왜 이것이 동작하지 않나요?</em></p><h3>전문가</h3><p><em>유저 인증 플로우에서 일관되지 않은 동작이 관찰됩니다. 유저들이 정상적인 사용 중에도 가끔 로그아웃 되는 경우가 있습니다. 인증 토큰 생명주기, 세션 관리 로직, 프런트엔드 상태 관리와 백엔드 토큰 검증 간의 레이스 컨디션을 분석하세요. 또한 브라우저 저장소의 한계, 네트워크 타임아웃, 동시 요청 처리 문제도 고려하세요. 전체 플로우를 추적하여 모든 잠재적 실패 지점을 식별하세요.</em></p><h3>개선버전</h3><p><em>우리의 결제 처리가 간헐적으로 실패하며, 명확한 패턴이 없습니다. 에러 로그에는 단순히 “거래 실패”라고만 표시되고 원인은 드러나지 않습니다. 네트워크 안정성, 서드파티 API 한계, 데이터베이스 트랜잭션 격리 수준, 재시도 로직, 요청 제한, 웹훅 전달 타이밍, 사용자 행동 패턴 등을 고려하여 결제 플로우를 분석하세요. 그리고 로깅 개선, 모니터링 알림, 폴백 메커니즘을 포함한 포괄적인 디버깅 전략을 수립하세요.</em></p><h3>방법 #13: 팀 전체 코딩 표준 구현하기</h3><p>일관성 없는 코드는 대부분의 개발팀을 무너뜨리는 원인이 됩니다.</p><p>어떤 개발자는 camelCase를 쓰고, 또 다른 개발자는 snake_case를 사용합니다. 누군가는 에러 처리를 try-catch 문법을 사용하고 다른 개발자는 에러 객체를 반환합니다.</p><p>주니어 개발자들은 이미 시니어가 해결한 패턴을 다시 발명하고, 코드베이스는 충돌하는 접근법으로 인해 점점 엉망이 됩니다.</p><p>아마추어는 린트 룰이나 코드 리뷰로 이를 해결하려 합니다.</p><blockquote>그러나 전문가들은 클로드 코드를 단순히 규칙 위반을 잡아내는 도구가 아니라, 팀을 교육하고 실제 사용 사례에 맞춰 표준을 발전시키는 지능적인 표준 강화 엔진으로 활용하고 있습니다.</blockquote><h3>아마추어</h3><p><em>이 코드가 우리의 코딩 표준을 따르는지 확인해</em></p><h3>전문가</h3><p><em>클로드 코드를 우리 팀의 코딩 표준 담당자로 설정하세요. 이 도구는 우리 팀의 특정 아키텍처 패턴인 커스텀 훅을 사용한 리액트 컴포넌트 구조, 에러 바운더리 구현, API 응답 처리 규칙, DB 쿼리 패턴, 보안 모범 사례 등을 이해해야 합니다. 생성된 모든 코드가 이러한 표준을 따를 뿐 아니라, 왜 이러한 패턴이 존재하는지, 언제 예외적으로 벗어날 수 있는지까지 설명해야 합니다.</em></p><h3>개선버전</h3><p><em>주니어 개발자와 작업할 때, 기술적으로는 동작하지만 팀의 모범 사례를 따르지 않는 코드를 찾아내세요. 단순히 무엇을 고쳐야 하는지 말하는 데 그치지 말고, 우리 팀이 왜 이러한 패턴을 배우게 되었는지, 어떤 문제를 해결하는지, 그리고 어떻게 전체 아키텍처에 녹아드는지 설명하세요. 과거에 이러한 패턴을 어겼을 때 어떤 문제가 발생했는지 사례도 함께 포함하세요.</em></p><h3>표준을 강화하는 프롬프트</h3><p><em>최근 커밋의 패턴을 분석하여, 아직 문서화되지 않은 새로운 규칙을 식별하세요. 팀이 자연스럽게 따르고 있는 경향을 기반으로 코딩 가이드라인 업데이트를 제안하고, 여러 개발자들이 유사한 문제를 상반된 방식으로 해결하고 있는 불일치 사례를 강조하세요.</em></p><h3>방법 #14: 다양한 언어 리팩토링 마스터하기</h3><p>이 부분에서 대부분의 개발자들이 실패합니다. 보통 자바스크립트, 많아야 파이썬 정도만 알고, 다른 언어에 손대는 것을 두려워합니다.</p><p>사업적으로 Node.js에서 Go로 마이그레이션해야 하거나, 파이썬으로 작성된 머신러닝 모델을 리액트 앱에 통합해야 할 때 패닉에 빠집니다.</p><blockquote>하지만 전문가들은 클로드 코드가 단순히 코드를 번역하는 것이 아니라, 비즈니스 로직을 보존하면서 각 언어의 강점을 살려 최적화할 수 있다는 걸 알게 되었습니다.</blockquote><h3>아마추어</h3><p><em>자바스크립트 함수를 파이썬으로 변경해 줘</em></p><h3>전문가</h3><p><em>사용자 인증 시스템을 Node.js/Express에서 Go로 마이그레이션 하세요. 모든 비즈니스 로직을 보존하면서 Go의 동시성 패턴을 최적화해 구현하세요. 동일한 API 계약을 유지하고, Go의 고루틴을 사용해 성능을 개선하세요. 또한 Go의 관례를 따른 적절한 에러 처리를 구현하고, 보안 모델이 그대로 유지되도록 하세요. 마지막으로 원래 구현과 동작 호환성을 검증할 수 있는 포괄적인 테스트를 포함하세요.</em></p><p>클로드 코드는 단순히 문법만 바꾸는 것이 아니라, 대상 언어에 맞게 아키텍처 자체를 재설계합니다.</p><ul><li>Node.js의 콜백 지옥은 우아한 Go 동시성으로 개선할 수 있습니다.</li><li>파이썬의 데이터 처리 로직은 Rust 성능에 맞게 최적화됩니다.</li></ul><h3>개선버전</h3><p><em>성능상의 이유로 전체 파이썬 데이터 처리 파이프라인을 Rust로 마이그레이션해야 합니다. 현재 pandas 기반 워크플로우를 분석하고 핵심 비즈니스 로직을 식별한 뒤, 이를 Rust의 소유권 모델과 제로 코스트 추상화를 활용해 재설계하세요. 동일한 데이터 변환과 검증 규칙을 유지하면서도 Rust의 성능 이점을 활용해야 합니다. 또한 기존 통합을 깨지 않고 점진적으로 이전할 수 있도록 호환 레이어를 만드세요.</em></p><h3>방법 #15: 자연어 기반 아키텍처 설계 활용하기</h3><p>이것이 단순히 기능을 만드는 개발자와 시스템을 설계하는 아키텍트의 궁극적인 차이입니다.</p><p>대부분의 개발자들은 요구사항을 이해하는 순간 곧바로 코딩에 들어갑니다.</p><p>그들은 컴포넌트, 함수 등을 여기저기에 만들고, 이들이 하나의 일관성 있는 무언가로 합쳐지길 바랍니다.</p><p>그러나 아키텍처가 잘못되었다는 걸 깨달을 때쯤이면, 이미 너무 깊이 들어가서 다시 시작할 수 없는 상태가 됩니다.</p><blockquote>하지만 전문가들은 클로드 코드를 사전 아키텍처 설계 도구로 활용하여, 코드를 작성하기도 전에 재앙을 예방하는 방법을 발견했습니다.</blockquote><h3>아마추어</h3><p><em>소셜 미디어 앱을 만들어</em></p><h3>전문가</h3><p><em>수백만 명의 사용자를 대상으로 확장 가능한 소셜 미디어 플랫폼을 설계해야 합니다. 유저 인증 및 권한 부여 패턴, 콘텐츠 생성 및 검토 워크플로우, 실시간 메시징 인프라, 피드 알고리즘 고려사항, 다양한 콘텐츠 유형에 맞는 데이터 저장 전략, 성능을 위한 캐싱 계층, 미디어 전송을 위한 CDN 전략, 마이크로서비스 경계 설정, 모바일 및 웹 클라이언트를 위한 API 설계, 모니터링 및 가시성 요구사항, 배포 전략을 체계적으로 생각하세요. 그리고 각각의 트레이드오프를 설명하는 포괄적인 아키텍처 문서를 작성하세요.</em></p><h3>구현 전략</h3><p><em>우리가 설계한 소셜 미디어 플랫폼을 위한 상세 구현 로드맵을 작성하세요. 그리고 MVP 기능, 개발 우선순위, 기술 스택 결정, 테스트 전략, 배포 단계, 리스크 완화 계획 항목으로 세분화하세요. 각 단계별 소요일과 컴포넌트 간 의존성도 포함하세요.</em></p><h3>최종 생각</h3><p>이러한 핵심 기법들은 클로드 코드를 단순한 자동완성 개발 도구에서 가장 강력한 개발 자동화 및 생산성 도구로 바꿉니다.</p><p>이 기술들을 배우고 완전히 익히는 데는 시간이 걸리지만, 시작은 반드시 필요합니다.</p><p>저는 클로드 코드가 처음 출시된 날부터 코딩에 활용했고, 어떻게 동작하는지 많은 것을 배웠습니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=24ea82c93363" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[번역] 리액트에서 SPA의 현재와 미래]]></title>
            <link>https://siosio3103.medium.com/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%97%90%EC%84%9C-spa%EC%9D%98-%ED%98%84%EC%9E%AC%EC%99%80-%EB%AF%B8%EB%9E%98-70e0645ccfc4?source=rss-e8991afece8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/70e0645ccfc4</guid>
            <dc:creator><![CDATA[조영제]]></dc:creator>
            <pubDate>Fri, 15 Aug 2025 04:06:59 GMT</pubDate>
            <atom:updated>2025-08-15T04:07:37.265Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>원문: <a href="https://www.felgus.dev/blog/future-spa">https://www.felgus.dev/blog/future-spa</a></blockquote><p>최근 리액트 생태계에서는 서버 컴포넌트와 Next.js를 중심으로 서버 렌더링에 대한 논의가 많이 이루어지고 있습니다. 그러나 고전적인 SPA의 미래는 어떨까요?</p><p>간단한 정적 파일과 하나의 HTML을 로드한 다음 애플리케이션을 렌더링 하는 현재의 패턴과 곧 다가올 미래에 일어날 수 있는 새로운 패턴에 대해서 얘기해 봅시다.</p><h3>현재의 패턴</h3><p>몇 년 전 SPA 진형에 등장했지만, 아직 널리 쓰이지 않는 패턴 중 <a href="https://www.felgus.dev/blog/suspense-gate">render-as-you-fetch</a>라는 개념이 있습니다.</p><p>과거에는 아래와 같이 컴포넌트 내부에서 fetch를 수행하는 것이 가장 일반적인 방법이었습니다.</p><ul><li>HTML 요청하기</li><li>초기 HTML을 UI에 렌더링</li><li>자바스크립트 파일 다운로드하기</li><li>다운로드한 자바스크립트 파일 파싱 및 실행, 리액트 초기화</li><li>리액트 트리 렌더링 시작</li><li>컴포넌트 안에서 fetch 요청 시작</li><li>fetch중에는 suspense fallback을 대신 표시</li><li>fetch가 끝나면 실제 컴포넌트 UI로 업데이트</li></ul><p>이런 식으로 렌더링과 함께 fetch가 수행되는 fetch-on-render 패턴을 사용했습니다. 이 방식은 간단하지만 워터폴과 UI 지연이 발생합니다. 이 패턴을 사용하는 비율은 정확히 알 수 없지만 여전히 대부분의 SPA가 이 방식을 따르고 있습니다. 이제 이 패턴과 비교되는 새로운 패턴인 render-as-you-fetch 방식에 대해서도 알아보겠습니다.</p><ul><li>HTML 요청하기</li><li>HTML 내에 있는 UI 그리기</li><li>자바스크립트 파일 다운로드하기</li><li>다운로드한 자바스크립트 파일 파싱 및 실행, 리액트 초기화</li><li>리액트 트리를 그리기 위해서 <em>라우트 로더</em> 호출하기</li><li>fetch가 진행되는 동안 suspense fallback을 대신 표시</li><li>fetch가 끝나면 실제 컴포넌트 UI로 업데이트</li></ul><p>라우트 로더 함수를 사용해서 한 단계 먼저 fetch를 시작하면은 수 ms를 절약가능합니다. 또한 suspense fallback도 빨리 그리면서 UX를 개선하고 fetch를 더 빨리 완료하며, 사용 가능한 UI를 더 빨리 보여줄 수 있습니다.</p><p>현재는 주로 React Router v7이나 Tanstack Router를 사용하면 적용할 수 있습니다. 그리고 작년의 Suspense Gate와 이 두 가지 패턴에 대한 모든 논쟁을 기억해 보면, 이 과정을 통해 리액트 팀은 장기적으로 render-as-you-fetch를 기본 패턴으로 삼으려는 비전을 보였습니다.</p><pre>&gt; 역자 주: Suspense Gate 논란<br> <br>- 리액트 19 RC에서 Suspense의 동작이 바뀌어 Suspense 경계 안에 있는 형제 컴포넌트가 병렬로 렌더링 되는 게 아니라 순차 렌더링되도록 변경된 것으로 인한 논란<br> <br>관련자료<br>- https://tkdodo.eu/blog/react-19-and-suspense-a-drama-in-3-acts<br>- https://github.com/facebook/react/issues/29898</pre><h3>서버 컴포넌트</h3><p>잠깐 우리 SPA에 대해서 얘기하고 있는 중 아니었나요? 그런데 서버요?</p><p>서버가 없어도 리액트 서버 컴포넌트를 생성할 수 있기 때문에, 이 네이밍은 적절하지 않습니다. 서버 컴포넌트는 빌드 단계에서 생성할 수 있으며 SPA에서 사용할 수 있도록 RSC 페이로드를 포함할 수도 있습니다.</p><p>아직 이 패턴은 명확히 정립되지 않았고, 대부분의 프레임워크가 RSC를 백엔드 측에서 생성하는 데 집중하고 있어 실제 서버에서 생성하는 방식이 일반적입니다. 그러나 세션 데이터나 상호작용에 관여하지 않는 “정적 컴포넌트”를 미리 생성해 두고, 필요할 때 로드해 고전적인 SPA에서 사용하는 방식은 어떨까요?</p><h3>동시성 패턴</h3><p>리액트 18에서는 <a href="https://react.dev/reference/react/useTransition">useTransition</a>와 <a href="https://react.dev/reference/react/useDeferredValue">useDeferred</a> 같은 동시성 기능이 도입되었습니다.</p><p>몇몇 사람들은 이 기능이 “대규모·복잡한 애플리케이션”을 위한 기능이고, 이는 대부분의 리액트 애플리케이션에는 해당하지 않는다고 분석했습니다.</p><p>그러나 이 분석은 프런트엔드의 복잡성에 대한 대부분의 주장과 마찬가지로 잘못된 것입니다. 우리는 UI를 구축하고 있으며, 각 사용자는 자신만의 세계를 가지고 있습니다. 프런트엔드에서 규모란 사용자 수가 아니라 UI를 통과하는 페이지, 상호작용, 정보의 양을 의미합니다.</p><p>모든 상호작용은 중요하며 언제든 임의의 순서로 발생할 수 있습니다. 하지만 자바스크립트 기반의 리액트는 단일 메인 스레드만 사용하여 모든 작업을 처리합니다. 따라서 동시에 여러 상호작용이 발생할 때 어떤 업데이트에 더 높은 우선순위를 부여해야 하는지, 어디서 우선순위 충돌이 발생하는지, 개발자나 사용자 모두 예측하기 어렵습니다.</p><p>하지만 리액트의 동시성 기능을 사용하면 우선순위를 지정하고 나머지는 리액트에게 맡길 수 있습니다. 즉 UI의 일부 업데이트를 낮은 우선순위로 설정할 수 있습니다.</p><p>이렇게 하면 리액트가 먼저 집중할 작업과 지연할 작업을 구분해 프레임 드롭 없이 더 부드러운 인터페이스와 좋은 UX를 제공할 수 있습니다.</p><p>UX 관점에서 리액트 개발자는 디자이너에게 동시성 기능의 능력을 알리고 설명해야 하며, 이는 디자이너가 다양한 인터랙션을 설계할 때 사용할 수 있는 새로운 도구가 될 것입니다.</p><h3>프리로드</h3><p>그러나 사용자가 여러 페이지를 오갈 때도 있는데, 이는 어떻게 개선할 수 있을까요?</p><p>모든 라우터는 HTML의 a 태그를 감싸고 라우터 로직과 연결하는 Link 컴포넌트가 있습니다. 이 덕분에 SPA는 페이지 새로 고침을 건너뛰고 새 페이지 코드로 UI를 업데이트할 수 있습니다.</p><p>여기서 코드 스플리팅과 지연 로딩은 흔한 전략입니다. 모든 SPA 코드를 하나의 큰 파일에 넣는 대신 항상 먼저 로드되는 메인 파일과 각 페이지 전용 자바스크립트 파일을 분리합니다.</p><p>이렇게 하면 사용자가 새 페이지로 이동할 때 해당 페이지의 자바스크립트 파일이 다운로드되고 구문 분석 및 실행됩니다. 그로 인해 메인 파일이 작아져 첫 로드가 빨라지고 웹의 핵심 지표 점수가 개선됩니다.</p><p>그렇다면 라우터나 프레임워크가 Link 컴포넌트를 다루는 김에 이를 활용해 동적으로 프리로드 하는 것도 가능하지 않을까요? 즉 사용자가 Link 컴포넌트 위에 마우스를 올린 시점을 감지해 일정 시간이 지나면 <a href="https://tanstack.com/router/v1/docs/framework/react/guide/data-loading">라우트 로더를 시작해 이 컴포넌트에 필요한 데이터를 미리 가져올</a> 수 있습니다. 이 몇 밀리초의 개선으로 UI가 콘텐츠와 함께 더 빨리 그려집니다.</p><h3>리액트 랩스</h3><p>리액트 랩스는 얼마 전 개발 중인 혁신 기능을 소개하는 블로그 글을 공개했습니다. 그중 <a href="https://react.dev/blog/2025/04/23/react-labs-view-transitions-activity-and-more">ViewTransition과 Activity</a>에 관심이 갔습니다.</p><p>ViewTransition은 리액트에 통합된 새로운 웹 표준으로, 컴포넌트가 API를 리액트 모델과 연결해 몇 가지 문제점을 해결합니다. 이는 애니메이션이 포함된 페이지 전환에 매우 유용하고 보다 유동적인 사용자 경험을 제공합니다.</p><p>하지만 여기서 더 중요하다고 생각하는 것은 Activity입니다. 이 개념은 완전히 새로운 개념은 아니며, 리액트에서 이미 Suspense 내부에서 사용되던 Offscreen 컴포넌트가 있었습니다. 이 개념은 리액트 내에 렌더링(컴포넌트를 호출해 UI 정의를 얻는 과정)과, 커밋(실제로 UI에 변화를 적용하는 과정) 이 두 가지 개념으로부터 비롯됩니다.</p><p>따라서 UI에 영향을 주지 않고 컴포넌트를 미리 렌더링 할 수 있는 방법이 있으면 매우 유용합니다. 리액트 핵심 팀은 오랫동안 이 아이디어에 대해서 얘기해 왔습니다. 그러나 이제는 점점 현실이 되고 있습니다. Activity 컴포넌트를 사용하면 컴포넌트가 가질 수 있는 첫 UI 정의를 얻어 나중에 재사용하도록 저장할 수 있습니다.</p><p>그리고 필요할 때 해당 정의를 가져와서 새로운 변경 사항과 함께 첫 커밋에 적용할 수 있습니다. 이렇게 하면 렌더링 과정을 피하면서 수 밀리초를 절약하고, UI를 더 빠르게 업데이트해 상호작용 경험을 더 향상할 수 있습니다.</p><p>먼저 설명한 프리로드를 합치면은 라우트를 미리 로드하고 특정 흐름으로 라우트 로더를 시작하여, 현재와 같은 지연 없이 새 페이지로 빠르게 전환할 수 있습니다. ViewTranstion 통합에 따라 사용자 경험은 은 네이티브 앱처럼 매끄러워질 수 있습니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=70e0645ccfc4" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>