Marginalia
Use this skill to add high-signal JSDoc that helps readers, IDEs, declaration files, and generated API docs. The goal is not comments everywhere; the goal is concise documentation at the right boundaries. Overly long JSDoc makes IDE hovers harder to use, so prefer the shortest comment that explains the missing context.
For TypeScript package APIs, treat JSDoc as the source of truth for API reference material, not as a replacement for authored docs. Props, exported types, defaults, constraints, callback contracts, and deprecations belong close to the public declarations so IDE hovers, .d.ts output, and generated docs agree. Usage guides, examples, conceptual explanations, migration notes, and recipes usually belong in README or site documentation.
Start
When invoked:
- State that you are using the
marginalia skill.
- Determine the documentation target:
- public package API
- all exports in a package or module
- complex internal code only
- React components, hooks, utilities, classes, or types
- generated docs or IDE hover quality
- If the user does not name a file, symbol, package, or scope, ask one concise clarification question before editing. Infer a public API pass only when the request clearly mentions package docs, publishing documentation, generated API docs, or IDE hover quality for a package.
- Read the right amount before editing:
- targeted pass: requested file/symbol, nearby types, and one relevant usage or test when available
- public API pass:
package.json exports/types, public entrypoints, barrels, tsconfig*, docs tooling, README/examples, and representative call sites
- complex internal pass: implementation, tests, and callers that reveal behavior
Do not infer behavior from names alone. Read the implementation and at least one usage path when available.
Documentation Density
Choose the smallest density that satisfies the request.
- Public API pass: Consider every exported symbol reachable from package entrypoints. Add JSDoc only where it teaches behavior, constraints, usage, or API intent; record obvious exports as
leave.
- Meaningful pass: Document exported symbols plus complex internal functions, tricky types, overloads, state machines, lifecycle behavior, side effects, and non-obvious constraints.
- Targeted pass: Document only the named file, component, or symbol.
Meaningful and targeted passes reuse steps 2-4 of the Package API Workflow (decide, write, validate) without the full public surface inventory from step 1.
Avoid blanket comments on obvious local variables, simple one-line wrappers, and code whose type signature already explains everything.
What To Document
Prioritize:
- exported functions, classes, constants with non-obvious semantics, React components, hooks, and types
- overloads, generics, conditional types, mapped types, branded types, and callback contracts
- options objects and config fields when IDE completion should guide consumers
- side effects, thrown errors, async behavior, caching, lifecycle, cleanup, ordering, and idempotency
- units, ranges, defaults, stability guarantees, runtime environment, and SSR/client constraints
- deprecations, experimental APIs, and internal-only exports when the repo uses those conventions
For published packages, focus on symbols included in exports and generated .d.ts files. Internal helpers only need JSDoc when they are complex enough that maintainers benefit.
For generated API docs, make defaults and behavioral constraints explicit in comments when they are not visible from the type alone. Prefer standard TSDoc-compatible tags such as @remarks, @defaultValue, @example, @deprecated, @see, and release tags when the repo's tooling recognizes them.
Comment Rules
Write comments that add information the type system cannot express. Keep them short enough to be useful in an IDE hover.
Brevity rules:
- Prefer one sentence for simple public APIs.
- Use one short summary plus one short paragraph for behavior or constraints.
- Use examples sparingly; include them only when they prevent likely misuse.
- Split long conceptual material into external docs instead of putting it in JSDoc.
- If a hover would feel like an article, cut it down.
Good JSDoc:
/**
* Builds a stable cache key for a request.
*
* The key includes the normalized URL and sorted query params so equivalent
* requests dedupe even when callers pass params in different orders.
*/
export function createRequestKey(input: RequestInput): string {
// ...
}
Avoid:
/** Gets the user. */
export function getUser(id: string): User;
Rules:
- Start with a concise summary sentence.
- Add a second paragraph only for behavior, constraints, or examples that matter.
- Prefer prose over noisy
@param tags when TypeScript names and types are clear.
- Use
@param for public APIs when parameter meaning is not fully obvious from the name, or when a function has multiple positional parameters, callbacks, options, units, defaults, side effects, or overloaded semantics.
- Use
@returns only when return semantics are not obvious from the type.
- Use
@typeParam for exported generics when the role, constraints, inference behavior, defaults, or relationship between type parameters is not obvious.
- Use
@throws, @deprecated, @example, @remarks, @defaultValue, @see, @internal, @public, @alpha, or @beta when the repo's tooling or docs use them.
- In TypeScript sources, do not duplicate declared types in
@param or @returns annotations. In plain JavaScript, JSDoc type annotations supply type information to IDEs and checkJs; preserve them and add them when needed.
- Do not add comments that simply restate the function name.
- Do not change runtime behavior while documenting.
When TypeDoc, API Extractor, or TSDoc conventions are present, follow the repo's established tag style, preserve release tags, avoid nonstandard tags unless configured, and run the existing docs or API report check when practical.
Generated API Reference
When the documentation target is generated API docs or single-source package documentation:
- Treat public source declarations as the canonical input for API reference.
- Inspect existing docs tooling first, such as TypeDoc, API Extractor, React docgen, declaration rollups, or custom site generators.
- Prefer structured tooling over parsing comments with ad hoc string matching.
- Keep generated API tables/reference data separate from authored examples, guides, and conceptual copy.
- Verify comments survive the package's declaration or docs pipeline before calling the pass complete.
- If no docs tooling exists, recommend a generated-docs plan but do not add new tooling unless the user asked for implementation.
Common split:
- JSDoc/TSDoc: API tables, prop descriptions, exported type docs, callback contracts, defaults, constraints, IDE hover text.
- Authored docs: installation, quick starts, composition examples, design rationale, migration guidance, recipes, and screenshots.
Package API Workflow
1. Build The Public Surface
List symbols exposed through:
package.json exports
types, typings, or declaration entrypoints
- root barrel files
- intentional subpath exports
Useful searches:
rg '^\s*export\b' -g '*.{ts,tsx,js,jsx,mts,cts,d.ts}'
rg '"(exports|types|typings|main|module|browser)"' -g 'package.json'
rg '^\s*(module\.exports|exports\.)' -g '*.{js,cjs,cts}'
rg '@public|@internal|@deprecated|@alpha|@beta|@remarks|@example' -g '*.{ts,tsx,js,jsx}'
For each public symbol, record whether it already has useful JSDoc and whether the declaration output would preserve it.
Use a lightweight inventory before package-wide edits:
| Symbol | Source file | Export path | Existing JSDoc | Decision | Reason |
| --- | --- | --- | --- | --- | --- |
2. Decide What Needs JSDoc
Classify each candidate:
- add: missing useful public API documentation
- improve: existing comment is stale, vague, or type-duplicative
- leave: signature and naming are already sufficient
- skip: private/simple helper with no meaningful hidden behavior
If the user asked for "everything", interpret that as every meaningful exported/public symbol unless they explicitly ask for exhaustive comments.
3. Write The Comments
Keep comments close to the exported declaration that consumers see. For overloads, place shared docs on the first overload or exported declaration, place distinct docs on each overload whose behavior differs, and do not rely on implementation-signature JSDoc for consumer docs.
For React components and hooks:
- document the component/hook purpose and key behavior
- document important props through exported prop interfaces when present
- mention controlled/uncontrolled behavior, accessibility expectations, SSR/client requirements, and side effects
- avoid documenting every visual prop when the prop name and type are enough
For types and interfaces:
- document the interface purpose
- document fields when users choose between them, when defaults matter, when they affect runtime behavior, or when they define callback contracts
- leave obvious structural fields undocumented
- prefer examples for complex config objects
Also inspect exported const assertions, token maps, schemas, namespace-like objects, discriminated unions, and inferred public types when they are part of the package API.
4. Validate
Choose commands from package.json scripts, workspace package scripts, or existing CI/docs config. Do not invent new tooling just to validate comments.
Run the narrowest meaningful checks:
- typecheck for touched packages
- lint/format if comments are linted
- package build when declaration output matters
- API docs generation if the repo uses TypeDoc, API Extractor, or similar
- inspect generated
.d.ts or docs output when publishing/IDE hover quality is the goal
For declaration preservation, check relevant compiler/doc settings such as removeComments, declaration emit, generated .d.ts entrypoints, re-exported symbols, stripInternal, API Extractor rollups, and whether docs remain attached after barrel or subpath export generation.
Report the exact commands run. If checks are unavailable or too broad, report exactly what was and was not verified.
Output
When planning, provide:
- public surface inspected
- symbols to add, improve, leave, and skip
- validation plan
For package-wide or multi-module passes, present the candidate public surface and intended documentation density before editing when the user asked for a plan. A request to add or improve documentation already authorizes the scoped edits.
When implementing, finish with:
- files changed
- kinds of APIs documented
- public symbols considered, JSDoc added, JSDoc improved, and symbols left undocumented with reasons
- validation results
Guardrails
- Do not create documentation theater. A comment must teach something.
- Do not add stale guesses. If behavior is unclear, read usage or tests before documenting.
- Do not write long comments that bury the useful detail. If the important point is not visible in the first sentence or two, rewrite.
- Do not document private helpers exhaustively unless complexity justifies it.
- Do not use JSDoc to hide poor names. Rename only when the user asked for refactoring or the rename is necessary and safe.
- Do not add examples that are not typechecked or at least consistent with real usage.
- Do not introduce generated docs tooling unless the user asks or the repo already uses it.
- Do not alter public API while adding JSDoc unless explicitly requested. Preserve release and deprecation tags; add or remove
@internal, @public, @alpha, @beta or @deprecated only when that API-status change is requested. These can affect emitted declarations or consumer diagnostics.
Completion Check
Before finishing, verify:
- public exported symbols requested by the user were considered
- comments explain behavior, constraints, examples, or IDE-helpful usage
- comments are concise enough to improve hover clarity
- no comments merely restate obvious names or TypeScript types
- generated declarations/docs preserve comments when that matters
- validation ran or the gap is reported
1---2name: marginalia3description: Add concise, useful JSDoc where IDE hover help or a generated API reference needs a non-obvious contract. Use for exported JavaScript or TypeScript APIs, components, hooks, classes, complex types, or package publishing. Not for self-explanatory internal code, narrating comments, prose docs, or anything that changes behavior.4---56# Marginalia78Use this skill to add high-signal JSDoc that helps readers, IDEs, declaration files, and generated API docs. The goal is not comments everywhere; the goal is concise documentation at the right boundaries. Overly long JSDoc makes IDE hovers harder to use, so prefer the shortest comment that explains the missing context.910For TypeScript package APIs, treat JSDoc as the source of truth for API reference material, not as a replacement for authored docs. Props, exported types, defaults, constraints, callback contracts, and deprecations belong close to the public declarations so IDE hovers, `.d.ts` output, and generated docs agree. Usage guides, examples, conceptual explanations, migration notes, and recipes usually belong in README or site documentation.1112## Start1314When invoked:15161. State that you are using the `marginalia` skill.172. Determine the documentation target:18 - public package API19 - all exports in a package or module20 - complex internal code only21 - React components, hooks, utilities, classes, or types22 - generated docs or IDE hover quality233. If the user does not name a file, symbol, package, or scope, ask one concise clarification question before editing. Infer a public API pass only when the request clearly mentions package docs, publishing documentation, generated API docs, or IDE hover quality for a package.244. Read the right amount before editing:25 - targeted pass: requested file/symbol, nearby types, and one relevant usage or test when available26 - public API pass: `package.json` exports/types, public entrypoints, barrels, `tsconfig*`, docs tooling, README/examples, and representative call sites27 - complex internal pass: implementation, tests, and callers that reveal behavior2829Do not infer behavior from names alone. Read the implementation and at least one usage path when available.3031## Documentation Density3233Choose the smallest density that satisfies the request.3435- **Public API pass:** Consider every exported symbol reachable from package entrypoints. Add JSDoc only where it teaches behavior, constraints, usage, or API intent; record obvious exports as `leave`.36- **Meaningful pass:** Document exported symbols plus complex internal functions, tricky types, overloads, state machines, lifecycle behavior, side effects, and non-obvious constraints.37- **Targeted pass:** Document only the named file, component, or symbol.3839Meaningful and targeted passes reuse steps 2-4 of the Package API Workflow (decide, write, validate) without the full public surface inventory from step 1.4041Avoid blanket comments on obvious local variables, simple one-line wrappers, and code whose type signature already explains everything.4243## What To Document4445Prioritize:4647- exported functions, classes, constants with non-obvious semantics, React components, hooks, and types48- overloads, generics, conditional types, mapped types, branded types, and callback contracts49- options objects and config fields when IDE completion should guide consumers50- side effects, thrown errors, async behavior, caching, lifecycle, cleanup, ordering, and idempotency51- units, ranges, defaults, stability guarantees, runtime environment, and SSR/client constraints52- deprecations, experimental APIs, and internal-only exports when the repo uses those conventions5354For published packages, focus on symbols included in `exports` and generated `.d.ts` files. Internal helpers only need JSDoc when they are complex enough that maintainers benefit.5556For generated API docs, make defaults and behavioral constraints explicit in comments when they are not visible from the type alone. Prefer standard TSDoc-compatible tags such as `@remarks`, `@defaultValue`, `@example`, `@deprecated`, `@see`, and release tags when the repo's tooling recognizes them.5758## Comment Rules5960Write comments that add information the type system cannot express. Keep them short enough to be useful in an IDE hover.6162Brevity rules:6364- Prefer one sentence for simple public APIs.65- Use one short summary plus one short paragraph for behavior or constraints.66- Use examples sparingly; include them only when they prevent likely misuse.67- Split long conceptual material into external docs instead of putting it in JSDoc.68- If a hover would feel like an article, cut it down.6970Good JSDoc:7172```ts73/**74 * Builds a stable cache key for a request.75 *76 * The key includes the normalized URL and sorted query params so equivalent77 * requests dedupe even when callers pass params in different orders.78 */79export function createRequestKey(input: RequestInput): string {80 // ...81}82```8384Avoid:8586```ts87/** Gets the user. */88export function getUser(id: string): User;89```9091Rules:9293- Start with a concise summary sentence.94- Add a second paragraph only for behavior, constraints, or examples that matter.95- Prefer prose over noisy `@param` tags when TypeScript names and types are clear.96- Use `@param` for public APIs when parameter meaning is not fully obvious from the name, or when a function has multiple positional parameters, callbacks, options, units, defaults, side effects, or overloaded semantics.97- Use `@returns` only when return semantics are not obvious from the type.98- Use `@typeParam` for exported generics when the role, constraints, inference behavior, defaults, or relationship between type parameters is not obvious.99- Use `@throws`, `@deprecated`, `@example`, `@remarks`, `@defaultValue`, `@see`, `@internal`, `@public`, `@alpha`, or `@beta` when the repo's tooling or docs use them.100- In TypeScript sources, do not duplicate declared types in `@param` or `@returns` annotations. In plain JavaScript, JSDoc type annotations supply type information to IDEs and `checkJs`; preserve them and add them when needed.101- Do not add comments that simply restate the function name.102- Do not change runtime behavior while documenting.103104When TypeDoc, API Extractor, or TSDoc conventions are present, follow the repo's established tag style, preserve release tags, avoid nonstandard tags unless configured, and run the existing docs or API report check when practical.105106## Generated API Reference107108When the documentation target is generated API docs or single-source package documentation:109110- Treat public source declarations as the canonical input for API reference.111- Inspect existing docs tooling first, such as TypeDoc, API Extractor, React docgen, declaration rollups, or custom site generators.112- Prefer structured tooling over parsing comments with ad hoc string matching.113- Keep generated API tables/reference data separate from authored examples, guides, and conceptual copy.114- Verify comments survive the package's declaration or docs pipeline before calling the pass complete.115- If no docs tooling exists, recommend a generated-docs plan but do not add new tooling unless the user asked for implementation.116117Common split:118119- **JSDoc/TSDoc:** API tables, prop descriptions, exported type docs, callback contracts, defaults, constraints, IDE hover text.120- **Authored docs:** installation, quick starts, composition examples, design rationale, migration guidance, recipes, and screenshots.121122## Package API Workflow123124### 1. Build The Public Surface125126List symbols exposed through:127128- `package.json` `exports`129- `types`, `typings`, or declaration entrypoints130- root barrel files131- intentional subpath exports132133Useful searches:134135```sh136rg '^\s*export\b' -g '*.{ts,tsx,js,jsx,mts,cts,d.ts}'137rg '"(exports|types|typings|main|module|browser)"' -g 'package.json'138rg '^\s*(module\.exports|exports\.)' -g '*.{js,cjs,cts}'139rg '@public|@internal|@deprecated|@alpha|@beta|@remarks|@example' -g '*.{ts,tsx,js,jsx}'140```141142For each public symbol, record whether it already has useful JSDoc and whether the declaration output would preserve it.143144Use a lightweight inventory before package-wide edits:145146```markdown147| Symbol | Source file | Export path | Existing JSDoc | Decision | Reason |148| --- | --- | --- | --- | --- | --- |149```150151### 2. Decide What Needs JSDoc152153Classify each candidate:154155- add: missing useful public API documentation156- improve: existing comment is stale, vague, or type-duplicative157- leave: signature and naming are already sufficient158- skip: private/simple helper with no meaningful hidden behavior159160If the user asked for "everything", interpret that as every meaningful exported/public symbol unless they explicitly ask for exhaustive comments.161162### 3. Write The Comments163164Keep comments close to the exported declaration that consumers see. For overloads, place shared docs on the first overload or exported declaration, place distinct docs on each overload whose behavior differs, and do not rely on implementation-signature JSDoc for consumer docs.165166For React components and hooks:167168- document the component/hook purpose and key behavior169- document important props through exported prop interfaces when present170- mention controlled/uncontrolled behavior, accessibility expectations, SSR/client requirements, and side effects171- avoid documenting every visual prop when the prop name and type are enough172173For types and interfaces:174175- document the interface purpose176- document fields when users choose between them, when defaults matter, when they affect runtime behavior, or when they define callback contracts177- leave obvious structural fields undocumented178- prefer examples for complex config objects179180Also inspect exported const assertions, token maps, schemas, namespace-like objects, discriminated unions, and inferred public types when they are part of the package API.181182### 4. Validate183184Choose commands from `package.json` scripts, workspace package scripts, or existing CI/docs config. Do not invent new tooling just to validate comments.185186Run the narrowest meaningful checks:187188- typecheck for touched packages189- lint/format if comments are linted190- package build when declaration output matters191- API docs generation if the repo uses TypeDoc, API Extractor, or similar192- inspect generated `.d.ts` or docs output when publishing/IDE hover quality is the goal193194For declaration preservation, check relevant compiler/doc settings such as `removeComments`, declaration emit, generated `.d.ts` entrypoints, re-exported symbols, `stripInternal`, API Extractor rollups, and whether docs remain attached after barrel or subpath export generation.195196Report the exact commands run. If checks are unavailable or too broad, report exactly what was and was not verified.197198## Output199200When planning, provide:201202- public surface inspected203- symbols to add, improve, leave, and skip204- validation plan205206For package-wide or multi-module passes, present the candidate public surface and intended documentation density before editing when the user asked for a plan. A request to add or improve documentation already authorizes the scoped edits.207208When implementing, finish with:209210- files changed211- kinds of APIs documented212- public symbols considered, JSDoc added, JSDoc improved, and symbols left undocumented with reasons213- validation results214215## Guardrails216217- Do not create documentation theater. A comment must teach something.218- Do not add stale guesses. If behavior is unclear, read usage or tests before documenting.219- Do not write long comments that bury the useful detail. If the important point is not visible in the first sentence or two, rewrite.220- Do not document private helpers exhaustively unless complexity justifies it.221- Do not use JSDoc to hide poor names. Rename only when the user asked for refactoring or the rename is necessary and safe.222- Do not add examples that are not typechecked or at least consistent with real usage.223- Do not introduce generated docs tooling unless the user asks or the repo already uses it.224- Do not alter public API while adding JSDoc unless explicitly requested. Preserve release and deprecation tags; add or remove `@internal`, `@public`, `@alpha`, `@beta` or `@deprecated` only when that API-status change is requested. These can affect emitted declarations or consumer diagnostics.225226## Completion Check227228Before finishing, verify:229230- public exported symbols requested by the user were considered231- comments explain behavior, constraints, examples, or IDE-helpful usage232- comments are concise enough to improve hover clarity233- no comments merely restate obvious names or TypeScript types234- generated declarations/docs preserve comments when that matters235- validation ran or the gap is reported