Articlefirecrawl.dev·2026년 10월 6일·0

Claude Mods: What They Are and How to Build One in TypeScript

Quick Summary

Claude Mods는 Claude Code 내부에서 TypeScript·JavaScript 함수 훅으로 이벤트와 UI를 바꾸는 플러그인이며, 세 파일로 구현하고 핫 리로드할 수 있지만 실행 전 분석을 위해 외부 패키지와 직접적인 시스템 접근이 제한된다.

Claude Mods: What They Are and How to Build One in TypeScript 관련 대표 이미지

🖼️ 인포그래픽

Claude Mods: What They Are and How to Build One in TypeScript 내용을 설명하는 본문 이미지

🖼️ 4컷 인포그래픽

Claude Mods: What They Are and How to Build One in TypeScript의 핵심 내용을 4단계로 요약한 인포그래픽
Claude Mods: What They Are and How to Build One in TypeScript 핵심 내용을 4단계로 압축한 4컷 인포그래픽

💡 한 줄 요약

Claude Mods는 Claude Code 내부에서 TypeScript·JavaScript 함수 훅으로 이벤트와 UI를 바꾸는 플러그인이며, 세 파일로 구현하고 핫 리로드할 수 있지만 실행 전 분석을 위해 외부 패키지와 직접적인 시스템 접근이 제한된다.

📌 핵심 요약

  • Claude Mods는 일반 Claude Code 플러그인에 훅 모듈을 추가한 형태로, TypeScript·JavaScript 함수가 Claude Code 자체 프로세스 안에서 이벤트를 관찰·변경·처리하고 UI를 그린다. 외부에서 실행되는 settings hook과 달리 프로세스 격리를 포기하는 대신 내부 동작에 더 깊이 관여한다.
  • Claude Code v2.1.287부터 Mods가 기본 활성화되며 CLAUDE_CODE_ENABLE_FUNCTION_HOOKS 환경변수는 무시된다. 비활성화하려면 /plugin에서 해당 플러그인을 끄거나 --safe-mode를 사용하거나 disableAllHooks를 true로 설정하며, 마지막 방법은 settings hook과 사용자 지정 상태 표시줄도 중단한다.
  • 최소 모드는 플러그인 매니페스트, hooks/hooks.json, 훅 모듈의 세 파일로 구성되며 TypeScript를 직접 불러와 빌드나 패키지 설치가 필요 없다. 예제의 37줄 register.tsx는 /hello 명령과 프롬프트 위의 빨간 배너를 구현한다.
  • 훅 모듈은 자체 파일의 상대 경로와 Claude Code가 제공하는 타입·도우미 모듈만 가져올 수 있으며, npm 패키지·React 컴포넌트·WebAssembly를 가져올 수 없다. 파일·프로세스·네트워크 접근은 $.fs, $.process, $.http를 거쳐야 하며, Claude Code는 실행 전에 훅과 API 호출을 분석한다.
  • Claude Code는 --plugin-dir로 불러온 모드와 현재 세션에서 작성한 모드의 변경을 감지해 register를 다시 실행한다. 이때 모듈 수준 변수는 초기화되므로 유지할 값에는 $.state를 사용하며, claude plugin validate ./demo로 등록된 이벤트·조건과 API 호출을 확인할 수 있다.

🧩 주요 포인트

  1. 이벤트 처리 순서가 동작을 결정한다 → 먼저 실행되는 모드가 뒤의 모드를 감싸며, next(e) 호출 여부와 전달 데이터에 따라 이벤트의 계속 진행·수정·직접 응답이 갈린다.
  2. 자동 작성과 핫 리로드는 개발을 단순화하지만 보존 범위가 다르다 → Claude가 ~/.claude/dev-mods/<session-id>/에 작성한 모드는 해당 세션에서만 로드되고, 재로딩 시 변수도 초기화되므로 폴더의 영구 보관과 $.state 사용을 구분해야 한다.
  3. UI 확장과 사용량 표시는 서로 다른 활용 사례다 → 글은 로컬 게임 표시가 추가 토큰을 쓰지 않는다고 설명하며, Firecrawl 추적 사례에서는 한 세션에 10크레딧을 사용하고 그중 8크레딧이 개발자 인덱스 검색 4회에서 발생했으며 잔여량은 1,203크레딧이었다고 제시한다.

🧠 상세 정리

1. Claude Mods의 정의와 플러그인 구조

Richard Oliver Bray의 글은 Claude Mods를 Claude Code 자체 프로세스 안에서 실행되는 함수 훅을 가진 일반 플러그인으로 설명한다. 플러그인은 .claude-plugin/plugin.json 매니페스트가 있는 폴더이며 스킬, 명령, MCP 서버, 훅을 묶을 수 있고, 모드는 여기에 Claude Code가 읽어 실행할 훅 모듈을 추가한다. TypeScript나 JavaScript로 작성한 함수는 도구 호출, 프롬프트 제출, 인터페이스 렌더링 같은 이벤트를 받아 관찰하거나 수정하거나 직접 처리한다. Anthropic이 사용하는 기능명은 Claude Mods이고, 그 기반 기술을 가리키는 이름은 function hook이다. Claude Code의 인터페이스가 React로 만들어져 있어 훅이 UI 요소 트리를 반환하면 화면에 표시할 수 있으며, 글은 이를 프롬프트 위에 게임이나 브라우저를 배치하는 방식의 토대로 소개한다.

2. Settings hook과의 차이와 미들웨어 실행 순서

기존 훅은 글에서 settings hook으로 구분되며, 명령 훅은 별도 프로그램을 실행하고 HTTP 훅이나 프롬프트 훅은 서버 또는 모델을 호출한 뒤 결과를 기다린다. 반면 모드의 함수 훅은 Claude Code 내부 프로세스에서 실행되므로 화면의 패널, 프롬프트 위 영역, 스피너를 바꾸고 이벤트 자체를 다음 단계로 넘어가기 전에 수정할 수 있다. 외부 스크립트가 충돌해도 Claude Code와 분리되어 있다는 settings hook의 격리는 함수 훅에서 포기하는 특성으로 설명된다. 여러 모드를 함께 쓰면 앞선 모드가 뒤의 모드를 감싸는 순서가 적용되고, 각 훅은 Express의 미들웨어처럼 next 함수를 받는다. next(e)는 이벤트를 그대로 전달하고 변경한 사본을 넘기면 이벤트를 수정하며, next를 호출하지 않고 반환하면 해당 훅이 이벤트에 직접 응답한다.

3. 기본 활성화 버전과 모드 비활성화 방법

초기 접근 단계에서는 CLAUDE_CODE_ENABLE_FUNCTION_HOOKS 환경변수를 설정해야 Claude Code가 함수 훅을 불러왔으며, 셸이나 Claude Code 설정 파일에서 이를 지정할 수 있었다. 글에 따르면 Claude Code v2.1.287부터 Claude Mods가 변경 기록에 포함되고 기본 활성화되어, 해당 버전과 이후 버전은 이 환경변수를 무시한다. 따라서 이전에 ~/.claude/settings.json에 추가한 설정은 제거할 수 있으며, 현재 버전에서 값을 0으로 바꾸는 방식은 모드를 끄지 못한다. 모드를 중단하는 방법으로는 /plugin에서 해당 플러그인을 비활성화하거나 --safe-mode로 세션을 시작하거나 설정 파일에 disableAllHooks를 true로 지정하는 선택지가 제시된다. 다만 disableAllHooks는 모드에만 적용되는 설정이 아니어서 기존 settings hook과 사용자 지정 상태 표시줄도 함께 멈춘다는 범위 차이를 주의해야 한다.

4. Claude에게 요청해 모드를 만드는 흐름

글은 가장 빠른 제작 방법으로 Claude Code 세션에서 원하는 모드의 동작을 자연어로 설명하는 방식을 제시하며, 예시로 현재 Git 브랜치를 프롬프트 위에 표시하는 요청을 든다. Claude Code에 내장된 플러그인 작성 스킬은 사용 중인 버전이 지원하는 이벤트와 메서드, 파일을 작성할 위치, 모드를 불러오는 방법을 Claude에게 알려준다. 기본 권한 모드에서 보호되는 ~/.claude/dev-mods/<session-id>/ 경로에 파일을 작성하므로 각 파일 작성을 승인하고, 핫 리로드 요청에는 Enable for this session을 선택하는 절차가 설명된다. 로드 여부는 /plugin의 Installed 탭에서 확인할 수 있고, 이후 모드를 바꾼 턴이 끝날 때 다시 불러온다. 이렇게 만든 모드는 작성한 세션에서만 로드되므로 계속 보관하려면 폴더를 영구적인 위치로 복사해야 하며, 참고 예제로 claude-code 저장소의 내장 모드와 GitHub 이슈 #91870의 Sep 9 업데이트에 실린 치트시트가 소개된다.

5. 세 파일로 만드는 /hello 모드와 훅의 역할

수동 제작의 최소 구성은 .claude-plugin/plugin.json, hooks/hooks.json, hooks/register.tsx의 세 파일이며, 예제 폴더에는 타입과 JSX 설정을 위한 tsconfig.json도 포함된다. 매니페스트에는 모드 전용 필수 필드가 추가되지 않고, hooks.json의 modules 배열이 해당 파일을 기준으로 한 상대 경로 ./register.tsx를 지정하면서 플러그인에 훅 모듈을 연결한다. 모듈이 내보내는 register는 로드 시 호출되고, 전달받은 on 함수로 이벤트를 등록하며 각 훅은 API인 $, 고정된 일반 데이터인 e, 다음 처리를 잇는 next를 받는다. session.start 훅은 기본 세션 시작 처리를 통과시킨 뒤 /hello를 등록하고, command.run 훅은 hello 명령에만 반응해 showing 값을 뒤집고 $.ui.invalidate로 다시 그리도록 요청한다. ui.render 훅은 AbovePrompt 영역에서 배너가 꺼져 있으면 기존 처리를 그대로 전달하고, 켜져 있으면 $.ui.resolve(e)로 받은 Box와 Text를 이용해 기존 내용 위에 빨간 문구를 배치한다.

6. 타입 설정, 핫 리로드와 상태 유지

예제의 tsconfig.json은 jsx를 react로, jsxFactory를 h로 설정하며, v2.1.274에서 예제를 만들 당시 /plugin-types가 타입 선언을 작성한 .claude/types 경로를 포함한다. 글은 현재 버전에서는 모드를 불러올 때마다 모드 내부의 .claude-plugin/types/에 타입 선언이 작성된다고 구분하고, 한 세션에서 예제 폴더를 로드하는 명령으로 claude --plugin-dir ./demo를 제시한다. Claude Code는 이 플래그로 불러온 폴더와 현재 세션에서 작성한 모드를 감시하다가 파일이 바뀌면 재시작 없이 훅 모듈을 다시 불러오고 register를 재실행한다. 예제의 재로딩 메시지는 session.start, command.run, ui.render의 세 훅을 나열했으며, 작성한 훅이 목록에 없다면 이벤트 이름 오타 등으로 등록되지 않았을 가능성을 확인할 수 있다. 재로딩은 showing 같은 모듈 수준 변수를 초기화하므로 유지할 값에는 $.state를 쓰고, claude plugin validate ./demo로 실제 로드 없이 이벤트·매처와 모드 API 호출 목록을 살펴볼 수 있다.

7. 외부 의존성 제한과 실행 전 분석

글은 npm 패키지를 가져올 수 없는 이유를 Claude Code가 실행 전에 모드 전체를 읽고 수행하는 동작을 나열해야 한다는 보안 모델에서 찾는다. 훅 모듈이 가져올 수 있는 것은 상대 경로로 참조하는 자체 파일과 타입·도우미를 위한 Claude Code 모듈이며, npm 의존성이 추가되면 Claude Code가 검사할 수 없는 코드가 따라 들어온다는 설명이다. 앞부분의 핵심 요약은 React 컴포넌트와 WebAssembly를 가져오는 것도 제한된다고 명시한다. 모드에는 파일 시스템이나 네트워크를 직접 사용하는 권한이 주어지지 않아 Node의 fs나 fetch를 직접 호출할 수 없으며, 파일 읽기·프로세스 실행·요청 전송은 각각 $.fs, $.process, $.http를 거친다. 이 구조로 정적 분석이 부수 효과를 식별하고 claude plugin validate와 관리자 검토에 필요한 호출 목록을 제공한다는 것이 글의 논리이며, 제공된 본문은 의존성이 이 분석을 깨뜨린다는 설명 도중에 끝난다.

8. 게임과 Firecrawl 추적 사례의 근거 범위

글은 함수 훅으로 프롬프트 위에 Tetris, 터미널 웹 브라우저, DOOM을 표시한 사례를 소개하고, 이런 방식의 게임은 Claude가 작업하는 동안 로컬에서 실행되어 추가 토큰을 사용하지 않으며 모델로 아무것도 보내지 않는다고 설명한다. 도입부는 DOOM 구현에 모드의 가져오기 제한을 우회하는 방법이 필요했다고 언급하지만, 제공된 본문에는 그 구체적인 구현 과정이 포함되어 있지 않다. Firecrawl 사례는 도입부의 핵심 요약에 제시되며, 오픈소스 크레딧 추적 모드가 한 세션에서 10크레딧 사용과 1,203크레딧 잔여량을 표시했고 사용량 중 8크레딧은 개발자 인덱스 검색 4회에서 발생했다고 적혀 있다. 다만 해당 추적 모드를 만드는 세부 절차나 개발자 인덱스의 API 키 필요 여부를 설명하는 본문은 제공되지 않았다. 따라서 게임의 표시 방식과 제시된 사용량 수치는 요약할 수 있지만, 목차에 등장하는 후속 질문이나 보조 outline만으로 누락된 구현·인증 조건을 확정할 수는 없다.

🧾 핵심 주장 / 시사점

  • Claude Mods의 확장성은 내부 프로세스 실행에서 나오지만, 기존 settings hook이 제공하던 프로세스 격리를 함께 얻을 수는 없다는 교환 관계가 있다.
  • 빌드와 패키지 설치가 없는 개발 방식은 시작을 단순하게 만들지만, 외부 의존성 제한과 $ API 중심의 접근 방식이 구현 가능한 범위를 결정한다.
  • 핫 리로드는 코드 변경을 빠르게 반영하지만 모드 폴더의 보존, 세션에서의 로드 범위, $.state를 통한 값의 유지는 서로 구분해서 다뤄야 한다.

✅ 액션 아이템

  • Claude Code v2.1.287 이상에서는 CLAUDE_CODE_ENABLE_FUNCTION_HOOKS에 의존하지 않고, 중단 범위에 맞춰 /plugin, --safe-mode, disableAllHooks 중 적용 방법을 선택한다.
  • 세 파일로 구성한 /hello 모드를 claude plugin validate ./demo로 확인하고, 외부 접근이 $.fs, $.process, $.http를 거치는지 검토한다.
  • 핫 리로드 뒤에도 유지할 값은 $.state로 관리하고, ~/.claude/dev-mods/<session-id>/에서 만든 모드를 보관하려면 폴더를 영구적인 위치로 복사한다.

❓ 열린 질문

  • 구현하려는 기능은 npm 패키지 없이 자체 파일과 Claude Code의 타입·도우미 모듈만으로 구성할 수 있는가?
  • 모드를 중단할 때 해당 플러그인만 끄면 되는가, 아니면 settings hook과 사용자 지정 상태 표시줄도 멈추는 disableAllHooks가 필요한가?
  • Firecrawl 사용량 10크레딧 중 개발자 인덱스 검색 4회가 차지한 8크레딧을 사용 목적에 비추어 어떻게 평가할 수 있는가?

관련 문서

공통 태그와 주제 흐름을 기준으로 같이 보면 좋은 문서를 이어서 제안합니다.