/experience-lwc-typescript-migrate
Use when converting an existing JavaScript Lightning Web Component (.js, .html, .css) to TypeScript with full type annotations and a matching `.d.ts` file that exposes only the component's `@api` surface. TRIGGER when the user says \"convert LWC to TypeScript\", \"migrate LWC to
$ npx -y skills add forcedotcom/sf-skills --skill experience-lwc-typescript-migrate --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/experience-lwc-typescript-migrate
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when converting an existing JavaScript Lightning Web Component (.js, .html, .css) to TypeScript with full type annotations and a matching `.d.ts` file that exposes only the component's `@api` surface. TRIGGER when the user says \"convert LWC to TypeScript\", \"migrate LWC to
SKILL.md
experience-lwc-typescript-migrate.SKILL.mdname: experience-lwc-typescript-migrate
description: "Use when converting an existing JavaScript Lightning Web Component (.js, .html, .css) to TypeScript with full type annotations and a matching `.d.ts` file that exposes only the component's `@api` surface. TRIGGER when the user says \"convert LWC to TypeScript\", \"migrate LWC to TS\", \"rename .js to .ts for this component\", \"add types to my LWC\", \"generate .d.ts for this LWC\", \"type-annotate @api properties\", or \"produce declare module 'c/componentName' definitions\". DO NOT TRIGGER when the user is authoring a brand-new LWC from scratch (use experience-lwc-generate), generating Jest tests for an existing LWC (use experience-lwc-generate), or migrating an Aura component to LWC."
metadata:
version: "1.0"
relatedSkills:
- "experience-lwc-generate"
cliTools:
- tool: ["git"]
semver: ">=2.0.0"
- tool: ["jq"]
semver: ">=1.6"
- tool: ["tsc"]
semver: ">=4.0.0"<!-- adk-managed-skill -->
Converting LWC to TypeScript
Convert a Lightning Web Component bundle from JavaScript to TypeScript. The deliverable is a fully-typed `.ts` implementation **plus** a `.d.ts` file that only exposes `@api` members (the public surface other LWCs consume).
When to Use This Skill
- User wants to migrate a single component or a folder of components from
`.js` to `.ts`.
- User needs a `.d.ts` for an existing LWC so other components (or an
external TypeScript host) can import it safely.
- User is adding type annotations to an already-renamed `.ts` LWC that
hasn't been properly typed yet.
- User wants JSDoc-style type hints upgraded to real TypeScript types.
Prerequisites
- The component builds and runs correctly in JavaScript today.
- `git` is available (the rename must preserve history via `git mv`).
- A TypeScript compiler is wired into the build (either the SFDX TS
pipeline or a standalone `tsc` step).
---
Workflow
Step 1 — Read the component
Open every file in the bundle:
componentName/
├── componentName.js
├── componentName.html
├── componentName.css
└── (possibly) __tests__/, __utam__/, existing .d.ts
Understand:
- What extends `LightningElement`? What is the class name?
- Which fields and methods carry the `@api` decorator?
- Which properties/methods have existing JSDoc (use as a type hint
starting point, but validate against actual usage — JSDoc lies).
- Which parameters / return types can you infer from how the code is
called internally?
Step 2 — Rename `.js` → `.ts` using `git mv`
git mv componentName/componentName.js componentName/componentName.ts
Repeat for any helper `.js` files in the bundle (unless they're already `.ts`). **Never** plain `mv` — that loses the history link TypeScript reviewers rely on.
Step 3 — Add type annotations in the `.ts`
Apply types in this priority order so you stop as soon as the public contract is solid:
1. **`@api` properties and methods first.** Generate JSDoc if it's missing, then translate JSDoc types to TS syntax (`string`, `number`, `boolean`, `Promise<T>`). Validate each JSDoc claim against the code before trusting it. 2. **Complex shapes become `interface` or `type` aliases** — not inline shapes repeated everywhere. 3. **Optional members use `?`** only when the value is genuinely allowed to be `undefined`. Do not sprinkle `?` defensively. 4. **Private/internal state** — still type it, but don't export the types. Use `private` for members that must never be touched by consumers. 5. **Event handlers** — prefer precise DOM event types:
- `MouseEvent` for `onclick` (and other click-like handlers). `click`
is dispatched as a `MouseEvent` — including keyboard-activated clicks — so typing it as `PointerEvent` would let handlers rely on pointer-only fields (`pointerType`, `pressure`, etc.) that are undefined in those cases.
- `PointerEvent` for `onpointerdown` / `onpointerup` / `onpointermove`
and other `pointer*` handlers where pointer-specific fields are actually meaningful.
- `CustomEvent<{ detail: ... }>` for LWC custom events.
- `Event` is the last resort; document why when using it.
6. **Async methods** always return `Promise<T>` — never bare `T`. 7. **Avoid `any`.** If you genuinely can't type something, use `unknown` and narrow with a type guard.
Reference patterns
Load [[assets/type-patterns.ts|assets/type-patterns.ts]] as an inline example covering property types, method types, and event handler types.
Step 4 — Generate the `.d.ts`
Create `componentName.d.ts` next to the `.ts`. It must:
- Contain **only `@api` members** — no private state, no internal
methods, no lifecycle hooks unless they are themselves `@api`.
- Preserve `@api` JSDoc verbatim (including `@type`, `@required`,
`@default`, `@param`, `@returns` tags) directly above each declaration.
- Declare the LWC module namespace `c/componentName` (or the org's
namespace if different).
Template: load [[assets/dts-template.ts|assets/dts-template.ts]] as the starting `.d.ts` shape.
If the component has **no** `@api` members, still produce the module declaration with a comment explaining there's no public surface — don't skip the file.
Step 5 — Compile and test
- Run the TypeScript compiler (`tsc --noEmit` or the build's equivalent).
Resolve every error before calling it done; no `@ts-ignore` patches.
- Run the component's existing Jest tests. The behavior should be
identical.
- Run the bundled consumer-finder unconditionally — empty output is a
valid result, not a reason to skip. The script resolves the search paths from `sfdx-project.json`'s `packageDirectories` (or falls back to `<project-root>`), rejects any entry that escapes the project root, and performs the LWC-import search internally so the invocation is fully deterministic:
"<skill_dir>/scripts/find-consumers.sh" "<project-root>" "<componentName>"
For ea
Read more
name: experience-lwc-typescript-migrate
description: "Use when converting an existing JavaScript Lightning Web Component (.js, .html, .css) to TypeScript with full type annotations and a matching `.d.ts` file that exposes only the component's `@api` surface. TRIGGER when the user says \"convert LWC to TypeScript\", \"migrate LWC to TS\", \"rename .js to .ts for this component\", \"add types to my LWC\", \"generate .d.ts for this LWC\", \"type-annotate @api properties\", or \"produce declare module 'c/componentName' definitions\". DO NOT TRIGGER when the user is authoring a brand-new LWC from scratch (use experience-lwc-generate), generating Jest tests for an existing LWC (use experience-lwc-generate), or migrating an Aura component to LWC."
metadata:
version: "1.0"
relatedSkills:
- "experience-lwc-generate"
cliTools:
- tool: ["git"]
semver: ">=2.0.0"
- tool: ["jq"]
semver: ">=1.6"
- tool: ["tsc"]
semver: ">=4.0.0"<!-- adk-managed-skill -->
Converting LWC to TypeScript
Convert a Lightning Web Component bundle from JavaScript to TypeScript. The deliverable is a fully-typed `.ts` implementation **plus** a `.d.ts` file that only exposes `@api` members (the public surface other LWCs consume).
When to Use This Skill
- User wants to migrate a single component or a folder of components from
`.js` to `.ts`.
- User needs a `.d.ts` for an existing LWC so other components (or an
external TypeScript host) can import it safely.
- User is adding type annotations to an already-renamed `.ts` LWC that
hasn't been properly typed yet.
- User wants JSDoc-style type hints upgraded to real TypeScript types.
Prerequisites
- The component builds and runs correctly in JavaScript today.
- `git` is available (the rename must preserve history via `git mv`).
- A TypeScript compiler is wired into the build (either the SFDX TS
pipeline or a standalone `tsc` step).
---
Workflow
Step 1 — Read the component
Open every file in the bundle:
componentName/ ├── componentName.js ├── componentName.html ├── componentName.css └── (possibly) __tests__/, __utam__/, existing .d.ts
Understand:
- What extends `LightningElement`? What is the class name?
- Which fields and methods carry the `@api` decorator?
- Which properties/methods have existing JSDoc (use as a type hint
starting point, but validate against actual usage — JSDoc lies).
- Which parameters / return types can you infer from how the code is
called internally?
Step 2 — Rename `.js` → `.ts` using `git mv`
git mv componentName/componentName.js componentName/componentName.ts
Repeat for any helper `.js` files in the bundle (unless they're already `.ts`). **Never** plain `mv` — that loses the history link TypeScript reviewers rely on.
Step 3 — Add type annotations in the `.ts`
Apply types in this priority order so you stop as soon as the public contract is solid:
1. **`@api` properties and methods first.** Generate JSDoc if it's missing, then translate JSDoc types to TS syntax (`string`, `number`, `boolean`, `Promise<T>`). Validate each JSDoc claim against the code before trusting it. 2. **Complex shapes become `interface` or `type` aliases** — not inline shapes repeated everywhere. 3. **Optional members use `?`** only when the value is genuinely allowed to be `undefined`. Do not sprinkle `?` defensively. 4. **Private/internal state** — still type it, but don't export the types. Use `private` for members that must never be touched by consumers. 5. **Event handlers** — prefer precise DOM event types:
- `MouseEvent` for `onclick` (and other click-like handlers). `click`
is dispatched as a `MouseEvent` — including keyboard-activated clicks — so typing it as `PointerEvent` would let handlers rely on pointer-only fields (`pointerType`, `pressure`, etc.) that are undefined in those cases.
- `PointerEvent` for `onpointerdown` / `onpointerup` / `onpointermove`
and other `pointer*` handlers where pointer-specific fields are actually meaningful.
- `CustomEvent<{ detail: ... }>` for LWC custom events.
- `Event` is the last resort; document why when using it.
6. **Async methods** always return `Promise<T>` — never bare `T`. 7. **Avoid `any`.** If you genuinely can't type something, use `unknown` and narrow with a type guard.
Reference patterns
Load [[assets/type-patterns.ts|assets/type-patterns.ts]] as an inline example covering property types, method types, and event handler types.
Step 4 — Generate the `.d.ts`
Create `componentName.d.ts` next to the `.ts`. It must:
- Contain **only `@api` members** — no private state, no internal
methods, no lifecycle hooks unless they are themselves `@api`.
- Preserve `@api` JSDoc verbatim (including `@type`, `@required`,
`@default`, `@param`, `@returns` tags) directly above each declaration.
- Declare the LWC module namespace `c/componentName` (or the org's
namespace if different).
Template: load [[assets/dts-template.ts|assets/dts-template.ts]] as the starting `.d.ts` shape.
If the component has **no** `@api` members, still produce the module declaration with a comment explaining there's no public surface — don't skip the file.
Step 5 — Compile and test
- Run the TypeScript compiler (`tsc --noEmit` or the build's equivalent).
Resolve every error before calling it done; no `@ts-ignore` patches.
- Run the component's existing Jest tests. The behavior should be
identical.
- Run the bundled consumer-finder unconditionally — empty output is a
valid result, not a reason to skip. The script resolves the search paths from `sfdx-project.json`'s `packageDirectories` (or falls back to `<project-root>`), rejects any entry that escapes the project root, and performs the LWC-import search internally so the invocation is fully deterministic:
"<skill_dir>/scripts/find-consumers.sh" "<project-root>" "<componentName>"
For ea
This repository provides a curated collection of Salesforce agent skills for building applications.
Repo: forcedotcom/sf-skills
Other skills on sf-skills.
- /agentforce-generate
Build, modify, optimize, debug, and deploy agents with Agentforce Agent Script. TRIGGER when: user creates, modifies, optimizes, or asks about .agent files or aiAuthoringBundle metadata; changes agent behavior, responses, or conversation logic; designs agent actions, tools,
Open skill - /agentforce-observe
Analyze production Agentforce agent behavior using session traces and Data Cloud. TRIGGER when: user queries STDM session data or Data Cloud trace records; investigates production agent failures, regressions, or performance issues; asks about session traces, conversation logs,
Open skill - /agentforce-test
Write, run, and analyze structured test suites for Agentforce agents — functional AND security. TRIGGER when: user writes or modifies test spec YAML (AiEvaluationDefinition); runs sf agent test create, run, run-eval, or results commands; asks about test coverage strategy, metric
Open skill - /automation-flow-generate
Generate Salesforce Flows using the MCP tool execute_metadata_action. Use when the user asks to create, build, or generate a flow — including Screen, Autolaunched, Record-Triggered (before/after-save), Scheduled. Also trigger for flow-like requests such as \"when a record is
Open skill - /dx-code-analyzer-configure
Set up, configure, and troubleshoot Salesforce Code Analyzer for any project. Handles installation, prerequisite checks, diagnosing broken setups, creating and editing code-analyzer.yml overrides, engine-specific settings, ignore patterns, severity overrides, and CI/CD pipeline
Open skill - /dx-code-analyzer-custom-rule-create
Create custom Code Analyzer rules for Regex (pattern matching), PMD (XPath/AST for Apex and metadata XML), and ESLint (LWC/JavaScript/TypeScript). Use when users want to enforce coding standards, ban patterns, detect hardcoded values, govern metadata, or add rules not in the
Open skill

