Creating a Claude Code Mod in TypeScript: the first project
Create a Claude Code Mod in TypeScript: three files, local types, loading and validation. A small first project with explicit boundaries and checks.
Reading time: 11 min

For create a Claude Code Mod in TypeScript starts from a small plugin: manifest, module link and input files. The code can react to events and use the Mods API; Claude Code directly loads JavaScript and TypeScript into the base path, without requiring bundlers or builds. The Official Creation Guide Indicates Claude Code 2.1,287 or later.
The first goal should be to understand the cycle write, upload, validate and try, do not immediately build a complete business integration. This guide, verified the 9 October 2026, describes an educational project: a call counter to instruments. Configuration fragments are examples; we do not declare a plugin executed or a benchmark. For the general context see What are Mods.
In summary
- The first mod should have observable behavior and no unnecessary dependence.
- Manifest, hooks.json and input module have different responsibilities.
- The types generated by your own version describe the contract really available.
- Validate checks the structure; UI testing and testing verify the behavior.
- A development folder is not a distribution ready for the whole team.
What first mod to choose to learn without complicating the project?
A meter is a good exercise because its requirement can be described without network, credentials or customer data: it shows how many calls have been observed and offers a way to consult the value. The official tutorial uses just one counter. You can study its architecture without copying all the parts immediately: first clarify what matters, when it starts and where it appears.
An observed call is not necessarily a successful operation. This distinction must appear in the interface text, otherwise the number suggests a precision it does not possess. If you want to count completed operations, the requirement changes: you have to define what outcomes to include, how to deal with errors and waste, and what event to observe. It is a product choice before code.
An alternative is an indicator of the branch. It seems just as simple, but requires reading a data and keeping it up to date. An old branch shown as current can be more harmful than the absence of the indicator. Then choose the counter if you want to learn events and status; choose the indicator if the real need is to recognize the context of the repository. Do not join the two exercises just to make the first project more impressive.
What are the three files of the mod?
The basic packaging separates identity, upload and behavior. The manifest describes the plugin. hooks/hooks.json indicates which module to load. The module exports register, which connects events and functions. The plugin component documentation and the Mods guide describe these boundaries.
| File | Responsibility | What to check |
|---|---|---|
| .claude-plugin/plugin.json | Identity and version of the plugin | Consistent name and explicit version |
| hooks/hooks.json | Link to module | Path to hooks.json file |
| hooks/register.ts | Mod Behavior | Recognisable Exports and Recordings |
| .claude-plugin/types/ | Types generated by the local version | APIs and events available in the build |
| Test files | Verifiable expectations | Normal Case, Error and Status |
An educational manifest can be:
{
"name": "conteggio-locale",
"version": "0.1.0",
"description": "Contatore didattico delle chiamate osservate"
}
The link to the form, saved in hooks/hooks.json, may be:
{
"description": "Modulo del contatore didattico",
"modules": ["./register.ts"]
}
These two JSONs describe only the packaging. They intentionally lack the behavior and the proofs: their content is not enough to call the working mod. The path ./register.ts is related to hooks.json; placing the file elsewhere without changing the link is an easy error to diagnose before opening a session.
Assisted or manual path: how to decide?
The assisted path starts with a description in the interactive session and uses the built-in Skill /plugin-authoring. The manual path allows you to see every responsibility of the package. Both require understanding the code and the upload process; delegating the writing to Claude does not automatically transfer the responsibility of the plugin. The tutorial on claude.dev presents the context of the first project.
For an assisted request write a closed requirement: count observed calls, make the value available, declare when it resets and do not read file contents. Add behavior in case of reloading. This description makes the review possible: you can compare each operation of the code with something required. "Make me a useful mod" does not offer the same criterion.
The official guide includes approvals for development files and for loading into the session. The generated folder is session-related, not a permanent deployment location. If you decide to keep it, prepare a recognizable directory and a README before involving colleagues. The Guide to install Mods in Claude Code distinguishes the local test from the usual installation.
How to read events, APIs, and continuation without confusing them?
A handler receives the API, event data, and a continuation. In an observer the normal behavior must continue; in a command managed by the mod the result can be produced by the component. The difference must be deliberately chosen. Omitting continuation at a wrong point can turn a passive indicator into a flow-altering component. React to events.
For the counter, draw a text map first: an event initializes or prepares the function, one updates the value, one shows the required result. Then ask which part really needs the UI. A consultation command is already sufficient to verify the value; drawing during work is an additional requirement. Separating these steps facilitates debugging.
If the mod has to modify an event, do not reason as if you could freely change the object received. The reference documents a frozen event: the transformation passes from a copy. Even the relationship between multiple Mods deserves attention: the function observes a point in the chain, not an all-knowing view of all operations. Reference Mods.
Why do local types count more than an online snippet?
Online pages evolve. The project must work on the installed version instead. The files .d.ts generated inside .claude-plugin/types/ describe events, methods, and components of that build; the guide invites you to prefer them when they diverge from the page. Searching for a method in the local type is a more useful verification of assuming that a copied name is already available.
This also applies to recent features. The ability to register a tool with isDeferred: false It has a border 2.1.293 or later, documented in Official Releases. The first counter does not need that field: adding it just because it exists would increase the compatibility requirement without helping the exercise.
In the README write the version against which you checked the project, the chosen surface and the meaning of the data shown. The typecheck may discover a missing field, but does not understand whether the word "completed operations" really describes a trial counter. The code review with Claude It must therefore be combined with precise functional criteria.
What forms of code must static analysis recognize?
The loader does not interpret the module as an arbitrary program without constraints. The guide requires literal event names, recognizable API calls, and import compatible with the Mods path. For example, making an API namespace a generic variable can prevent analysis. Before introducing helpers or generated recordings, check the local version rules. Static Analysis Rules.
For the first project it is better to keep explicit recordings. There is no need for an internal framework for a few events: it makes it less obvious what is being observed and what is being allowed to continue. A helper can be useful when it reduces real duplication, but it must remain compatible with analysis and make accountability clearer. Shortness does not coincide with the use of calculated names or with a hidden record in a cycle.
Before the review, prepare a small data map: from which event the value comes, who updates it and which input reads it. If the counter is temporary, clear the reset in the command. If he has to survive the reload, he designs that passage and his proof. This design avoids choosing a persistent store only because a variable has reset: the duration of the data must follow the product requirement.
What verification cycle to use during development?
Work on the development directory, not the cache of an installed copy. First check the structure and manifest with claude plugin validate, then verify the behaviors with the relevant tests. Only after it loads the examined plugin into the intended surface. The CLI reference separates validation and testing, including the narrow mode of validation.
The cycle can be described as follows: small modification, validation, proof of the affected behavior, comparison of the result, possible reload. No need to redo each experiment for a text correction; instead, you need to expand the proof when changing the status, events, or authority of the component. It records the outcome, without turning the simple saving of a file into a verification.
When can I say that the meter is verified?
When a known sequence produces the expected value, a non-relevant event does not alter the value and reloads or new session comply with the stated behavior. The UI must use a description that is consistent with what is counted. If one of these tests is missing, the project may be a valid prototype but not yet a verified function for that workflow.
The Guide to test a mod without login or model calls deepens fixture and stub. A behavior test does not require a productive session, but does not certify all visual rendering on its own. A UI component needs testing on surfaces that the project claims to support.
Two first hypothetical projects in an Italian team
Hypothetical example: a software house in Florence wants to understand a flow of tools. The group builds the counter on synthetic data. It defines that the number represents observed calls, not successful edits. A command shows the value after a known sequence and the test checks that the reload has the declared behavior. The component must not register customer names or file contents.
The first review then controls words and boundaries before aesthetics. If the number rises even when a call is rejected, it is not automatically a bug: it depends on the requirement. The team can change the description or choose a different event, updating the evidence. The project teaches you to make a metric explicit, not claim a productivity gain.
Hypothetical example: an agency in Verona tests a branch indicator. The requirement arises from a frequent passage between repositories. The indicator must show the current branch and a clear message when it cannot read it. The test includes changing directories, a folder with no repository, and reloading the mod.
The manager discovers that static information is not enough: his update counts. Before adding colors and buttons, the group decides when to re-read the value and how to recognize an old data. If he can't do it on a small contract, he reconsiders the idea. The reversibility of the test makes it possible to stop the experiment without making it dependent on daily work.
What shortcuts make the first mod fragile?
The first is to add network, processes, and credentials to an exercise that doesn't need them. The second is to modify the event as any object, ignoring the documented contract. The third is to use a module variable and expect it to survive each reload. The fourth is to consider static analysis as a test of the result. The fifth is to distribute the temporary folder without version and responsible.
Every shortcut hides a decision. What service does it really serve? When does the data have to live? What does the test prove? Who will receive the update? Responding before adding code reduces the number of items to diagnose. If a project does not load, keep the message and use the Practical Diagnosis of Mods, instead of rewriting the whole module blindly.
How to move from the first exercise to a useful function?
Choose only one workflow need and write the contract with input, result, error and duration of the state. Then decide if the command is enough or you also need a tool for Claude. The guide to commands and tools with the Mods API helps in this choice. Do not automatically turn each user command into a tool available to the model.
If customization is to enter the work of multiple people, prepare testing, versioning, and provenance before deployment. custom software can start from this small requirement and connect it to the team process. The guides to Claude by code and Data Security complete the framework to choose which responsibilities to entrust to the new function.
Giallo Studio guides: methodology and sources
How we apply it in the company
Related resources
Mods by Claude: what they are and when they are needed in Claude Code
Test a Claude Code Mod without login or model calls
Claude Mods API: add custom commands and tools
Claude Code Mod not working: loading, hot reload and state
Install Mods in Claude Code: scope, reloads and updates
Claude AI for code and development
Code review with Claude Opus 5.5: a prompt to find bugs before merging
Copilot Chat and Microsoft 365 Copilot: What ChangesFAQ
What files do you need to create the first Claude Code Mod?
The basic path includes the manifest .claude-plugin/plugin.json, hooks/hooks.json and an entry module. The modules key connects hooks.json to the code file. The module exports register to register handlers.
Better JavaScript or TypeScript for a mod?
Both are supported by the documented path. TypeScript is useful for controlling the contract of events and APIs through the types generated by your own version. JavaScript can suffice for very small customization.
Do I need to install Node.js and a bundler?
The basic guide loads .js and .ts directly, without requiring Node.js, bundlers or builds. Other development tools chosen by the team may have their own requirements. Don't add them if the first mod doesn't need them.
How do I ask Claude to create a mod?
Describe a narrowly defined behaviour in the interactive session; the built-in plugin-authoring Skill guides the process. Generated files and loading require the prescribed approval process. A code review is still necessary before use.
What types should I use when the documentation changes?
Use the .d.ts generated by the version of Claude Code installed in the mod project. They describe events, APIs and components available in that build. When they differ from the online page, the guide indicates to rely on local types.
Does Validate prove the mod works?
No. Validate checks manifests and static analysis of the module. Relevant testing and a test on the intended surface is required to state that the behavior works, distinguishing between normal cases and failures.