DRY Refactoring With jscpd
kucherenko/jscpd
Removes copy-paste duplication found by jscpd, starting with exact clones and hotspots, then renamed and near-miss copies, using proven refactoring strategies.
Guide AI agents through TypeScript coding best practices including type safety, error handling, code organization, and architecture patterns.
$ npx skills add jwynia/agent-skills --skill typescript-best-practices -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install jwynia/agent-skills typescript-best-practices --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/jwynia/agent-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/tech/development/tooling/typescript-best-practices .claude/skills/typescript-best-practices && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "typescript-best-practices" agent skill from https://github.com/jwynia/agent-skills/tree/main/skills/tech/development/tooling/typescript-best-practices into .claude/skills/typescript-best-practices/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "typescript-best-practices", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/jwynia/agent-skills/tree/main/skills/tech/development/tooling/typescript-best-practicesType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add jwynia/agent-skills --skill typescript-best-practices -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install jwynia/agent-skills typescript-best-practices --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jwynia/agent-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/tech/development/tooling/typescript-best-practices .agents/skills/typescript-best-practices && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "typescript-best-practices" agent skill from https://github.com/jwynia/agent-skills/tree/main/skills/tech/development/tooling/typescript-best-practices into .agents/skills/typescript-best-practices/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "typescript-best-practices", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jwynia/agent-skills --skill typescript-best-practices -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install jwynia/agent-skills typescript-best-practices --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jwynia/agent-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/tech/development/tooling/typescript-best-practices .cursor/skills/typescript-best-practices && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "typescript-best-practices" agent skill from https://github.com/jwynia/agent-skills/tree/main/skills/tech/development/tooling/typescript-best-practices into .cursor/skills/typescript-best-practices/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "typescript-best-practices", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/jwynia/agent-skills.git --path skills/tech/development/tooling/typescript-best-practices--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add jwynia/agent-skills --skill typescript-best-practices -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install jwynia/agent-skills typescript-best-practices --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jwynia/agent-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/tech/development/tooling/typescript-best-practices .gemini/skills/typescript-best-practices && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "typescript-best-practices" agent skill from https://github.com/jwynia/agent-skills/tree/main/skills/tech/development/tooling/typescript-best-practices into .gemini/skills/typescript-best-practices/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "typescript-best-practices", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install jwynia/agent-skills typescript-best-practicesInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add jwynia/agent-skills --skill typescript-best-practices -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/jwynia/agent-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/tech/development/tooling/typescript-best-practices .github/skills/typescript-best-practices && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "typescript-best-practices" agent skill from https://github.com/jwynia/agent-skills/tree/main/skills/tech/development/tooling/typescript-best-practices into .github/skills/typescript-best-practices/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "typescript-best-practices", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jwynia/agent-skills --skill typescript-best-practices -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install jwynia/agent-skills typescript-best-practices --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jwynia/agent-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/tech/development/tooling/typescript-best-practices .opencode/skills/typescript-best-practices && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "typescript-best-practices" agent skill from https://github.com/jwynia/agent-skills/tree/main/skills/tech/development/tooling/typescript-best-practices into .opencode/skills/typescript-best-practices/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "typescript-best-practices", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
typescript-best-practicesGuide AI agents through TypeScript coding best practices including type safety, error handling, code organization, and architecture patterns.
Typescript Best Practices is an agent skill from jwynia/agent-skills. Guide AI agents through TypeScript coding best practices including type safety, error handling, code organization, and architecture patterns. This skill should be used when generating TypeScript code, reviewing TypeScript files, creating new TypeScript modules, refactoring JavaScript to TypeScript, or when the user asks about TypeScript patterns, types, or coding standards. Keywords: typescript, types, coding standards, best practices, type safety, generics, architecture, refactoring.
Its SKILL.md is about 2.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 26 other files, including scripts, reference files and assets (for example `assets/templates/module-template.ts.md`, `assets/templates/service-template.ts.md` and `assets/tsconfig-presets/recommended.json`). Compatibility notes: Requires Deno for analysis scripts. Applicable to any TypeScript codebase.
It sits in Development, covering Type safety, Code quality and Software architecture. It works with TypeScript and JavaScript. The licence is MIT.
4 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit e02ec7e. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 1 file in scripts/, which the agent can run.
Shell commands in SKILL.md call:
denoFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Requires Deno for analysis scripts. Applicable to any TypeScript codebase.
From compatibility in the SKILL.md frontmatter.
Typescript Best Practices loads about 2.5k tokens when it runs, and up to ~26k if it reads all its reference files. Until then it costs about 129 tokens; SKILL.md has 359 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from jwynia/agent-skills at commit e02ec7e, republished under its MIT licence (© jwynia). 359 words, ~2,490 tokens.
.claude/skills/typescript-best-practices/SKILL.md (or your agent's skills folder). This skill also uses 18 other files; get the full folder from GitHub.Guide AI agents in writing high-quality TypeScript code. This skill provides coding standards, architecture patterns, and tools for analysis and scaffolding.
Use this skill when:
Do NOT use this skill when:
Maximize compile-time error detection:
// Prefer unknown over any for unknown types
function processInput(data: unknown): string {
if (typeof data === "string") return data;
if (typeof data === "number") return String(data);
throw new Error("Unsupported type");
}
// Explicit return types for public APIs
export function calculateTotal(items: ReadonlyArray<Item>): number {
return items.reduce((sum, item) => sum + item.price, 0);
}
// Use const assertions for literal types
const CONFIG = {
mode: "production",
version: 1,
} as const;Prevent accidental mutations:
// Use readonly for object properties
interface User {
readonly id: string;
readonly email: string;
name: string; // Only mutable if intentional
}
// Use ReadonlyArray for collections
function processItems(items: ReadonlyArray<Item>): ReadonlyArray<Result> {
return items.map(transform);
}
// Prefer spreading over mutation
function updateUser(user: User, name: string): User {
return { ...user, name };
}Use the type system for error handling:
// Result type for recoverable errors
type Result<T, E = Error> =
| { success: true; value: T }
| { success: false; error: E };
// Typed error classes
class ValidationError extends Error {
constructor(
message: string,
readonly field: string,
readonly code: string
) {
super(message);
this.name = "ValidationError";
}
}
// Function with Result return type
function parseConfig(input: string): Result<Config, ValidationError> {
try {
const data = JSON.parse(input);
if (!isValidConfig(data)) {
return {
success: false,
error: new ValidationError("Invalid config", "root", "INVALID_FORMAT"),
};
}
return { success: true, value: data };
} catch {
return {
success: false,
error: new ValidationError("Parse failed", "root", "PARSE_ERROR"),
};
}
}Structure code for maintainability:
// One concept per file
// user.ts - User type and related utilities
export interface User {
readonly id: string;
readonly email: string;
readonly createdAt: Date;
}
export function createUser(email: string): User {
return {
id: crypto.randomUUID(),
email,
createdAt: new Date(),
};
}
// Explicit exports (no barrel file wildcards)
// index.ts
export { User, createUser } from "./user.ts";
export { validateEmail } from "./validation.ts";| Category | Prefer | Avoid |
|---|---|---|
| Unknown types | unknown | any |
| Collections | ReadonlyArray<T> | T[] for inputs |
| Objects | Readonly<T> | Mutable by default |
| Null checks | Optional chaining ?. | != null |
| Type narrowing | Type guards | as assertions |
| Return types | Explicit on exports | Inferred on exports |
| Enums | String literal unions | Numeric enums |
| Imports | Named imports | Default imports |
| Errors | Result types | Throwing for flow control |
| Loops | for...of, .map() | for...in on arrays |
When generating TypeScript code, follow these patterns:
/**
* Module description
* @module module-name
*/
// === Types ===
export interface ModuleOptions {
readonly setting: string;
}
export interface ModuleResult {
readonly data: unknown;
}
// === Constants ===
const DEFAULT_OPTIONS: ModuleOptions = {
setting: "default",
};
// === Implementation ===
export function processData(
input: unknown,
options: Partial<ModuleOptions> = {}
): ModuleResult {
const opts = { ...DEFAULT_OPTIONS, ...options };
// Implementation
return { data: input };
}// Pure functions preferred
function transform(input: Input): Output {
// No side effects, same input = same output
return { ...input, processed: true };
}
// Explicit parameter types
function fetchUser(id: string, options?: FetchOptions): Promise<User> {
// Implementation
}
// Use function overloads for complex signatures
function parse(input: string): ParsedData;
function parse(input: Buffer): ParsedData;
function parse(input: string | Buffer): ParsedData {
// Implementation
}// Prefer interfaces for object shapes
interface UserData {
readonly id: string;
readonly email: string;
}
// Use type for unions and intersections
type UserRole = "admin" | "user" | "guest";
type AdminUser = UserData & { readonly role: "admin" };
// Document with JSDoc
/**
* Configuration for the API client
* @property baseUrl - The base URL for API requests
* @property timeout - Request timeout in milliseconds
*/
interface ApiConfig {
readonly baseUrl: string;
readonly timeout?: number;
}Avoid these patterns when generating code:
| Anti-Pattern | Problem | Solution |
|---|---|---|
any type | Disables type checking | Use unknown and narrow |
as assertions | Runtime errors | Use type guards |
Non-null ! | Null pointer errors | Optional chaining ?. |
| Mutable params | Unexpected mutations | Readonly<T> |
| Magic strings | Typos, no autocomplete | String literal types |
| God classes | Hard to test/maintain | Single responsibility |
| Circular deps | Build/runtime issues | Dependency inversion |
| Index signatures | Lose type info | Explicit properties |
See references/anti-patterns/common-mistakes.md for detailed examples.
Analyze TypeScript code for quality issues:
deno run --allow-read scripts/analyze.ts <path> [options]
Options:
--strict Enable all checks
--json Output JSON for programmatic use
--fix-hints Show suggested fixes
Examples:
# Analyze a file
deno run --allow-read scripts/analyze.ts ./src/utils.ts
# Analyze directory with strict mode
deno run --allow-read scripts/analyze.ts ./src --strict
# JSON output for CI
deno run --allow-read scripts/analyze.ts ./src --jsonGenerate TypeScript types from JSON data:
deno run --allow-read --allow-write scripts/generate-types.ts <input> [options]
Options:
--name <name> Root type name (default: inferred)
--output <path> Output file path
--readonly Generate readonly types
--interface Use interface instead of type
Examples:
# Generate from JSON file
deno run --allow-read scripts/generate-types.ts ./data.json --name Config
# Generate readonly interface
deno run --allow-read --allow-write scripts/generate-types.ts ./api-response.json \
--interface --readonly --output ./types/api.tsCreate properly structured TypeScript modules:
deno run --allow-read --allow-write scripts/scaffold-module.ts [options]
Options:
--name <name> Module name (required)
--path <path> Target directory (default: ./src)
--type <type> Type: service, util, component
--with-tests Include test file
Examples:
# Create a utility module
deno run --allow-read --allow-write scripts/scaffold-module.ts \
--name "string-utils" --type util
# Create a service with tests
deno run --allow-read --allow-write scripts/scaffold-module.ts \
--name "user-service" --type service --with-testsreferences/type-system/advanced-types.md - Generics, conditional types, mapped typesreferences/type-system/type-guards.md - Type narrowing techniquesreferences/type-system/utility-types.md - Built-in utility typesreferences/patterns/error-handling.md - Result types, typed errorsreferences/patterns/async-patterns.md - Async/await best practicesreferences/patterns/functional-patterns.md - Immutability, compositionreferences/patterns/module-patterns.md - Exports, dependency injectionreferences/architecture/project-structure.md - Directory organizationreferences/architecture/api-design.md - Interface design, versioningassets/templates/module-template.ts.md - Module starter templateassets/templates/service-template.ts.md - Service class templateassets/tsconfig-presets/strict.json - Maximum strictness configassets/tsconfig-presets/recommended.json - Balanced defaults© jwynia, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 18 other files (scripts, references, assets) in skills/tech/development/tooling/typescript-best-practices of jwynia/agent-skills.
Open the folder on GitHubat commit e02ec7e
Typescript Best Practices next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Typescript Best Practices this skilljwynia/agent-skills | 169 | — | ~2.5k | Automated safety check: Pass | MIT | |
| DRY Refactoring With jscpdkucherenko/jscpd | 6.4k | — | ~2.1k | Automated safety check: Pass | MIT | |
| jscpd Duplicate Code Detectorkucherenko/jscpd | 6.4k | — | ~4.5k | Automated safety check: Pass | MIT | |
| Fallow Setupfallow-rs/fallow-skills | 129 | — | ~1.1k | Automated safety check: Pass | MIT | |
| Code ReviewerLeoYeAI/openclaw-master-skills | 2.2k | 1 repos | ~1.2k | Automated safety check: Pass | MIT | |
| Typescript Writeaiskillstore/marketplace | 430 | 2 repos | ~1.7k | Automated safety check: Pass | None |
kucherenko/jscpd
Removes copy-paste duplication found by jscpd, starting with exact clones and hotspots, then renamed and near-miss copies, using proven refactoring strategies.
kucherenko/jscpd
Finds duplicated code in 220+ languages with jscpd, reports exact, renamed and near-miss clones in a compact agent-friendly format and measures duplication.
fallow-rs/fallow-skills
Set up or modernize code-quality tooling for JavaScript and TypeScript projects.
LeoYeAI/openclaw-master-skills
Code review automation for TypeScript, JavaScript, Python, Go, Swift, Kotlin.
aiskillstore/marketplace
Write TypeScript and JavaScript code following Metabase coding standards and best practices.
borghei/Claude-Skills
Code review automation for TypeScript, JavaScript, Python, Go, Swift, and Kotlin.
jwynia/agent-skills
Diagnose devcontainer configuration problems and guide development environment setup.
jwynia/agent-skills
Create distinctive, production-grade frontend interfaces with high design quality.
jwynia/agent-skills
Orchestrate agile development workflows for Gitea repositories using the tea CLI.
jwynia/agent-skills
Generate game assets using AI image generation APIs (DALL-E, Replicate, fal.ai) and prepare them for Godot.
jwynia/agent-skills
Develop AI agents, tools, and workflows with Mastra v1 Beta and Hono servers.
jwynia/agent-skills
Create and manipulate PowerPoint PPTX files programmatically.
Works with
Categories
Guide AI agents through TypeScript coding best practices including type safety, error handling, code organization, and architecture patterns. Typescript Best Practices is an agent skill from jwynia/agent-skills. Guide AI agents through TypeScript coding best practices including type safety, error handling, code organization, and architecture patterns.
Typescript Best Practices fits situations like: asks about TypeScript patterns; coding standards.
Run `npx skills add jwynia/agent-skills --skill typescript-best-practices -a claude-code`. Or copy the skill folder (skills/tech/development/tooling/typescript-best-practices in jwynia/agent-skills) into .claude/skills/typescript-best-practices in your project. Claude Code loads it when a task matches its description.
Run `npx skills add jwynia/agent-skills --skill typescript-best-practices -a codex`. Or copy the skill folder (skills/tech/development/tooling/typescript-best-practices in jwynia/agent-skills) into .agents/skills/typescript-best-practices in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jwynia/agent-skills --skill typescript-best-practices -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/typescript-best-practices, .gemini/skills/typescript-best-practices, .github/skills/typescript-best-practices and .opencode/skills/typescript-best-practices in your project.
Going by SKILL.md and its folder, Typescript Best Practices needs the command-line tools its instructions call (deno). Our summary lists: Node.js. Compatibility (from SKILL.md): Requires Deno for analysis scripts. Applicable to any TypeScript codebase..
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Typescript Best Practices is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.5k tokens (SKILL.md is roughly 10k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 23k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Typescript Best Practices: DRY Refactoring With jscpd (kucherenko/jscpd, 6.4k stars), jscpd Duplicate Code Detector (kucherenko/jscpd, 6.4k stars), Fallow Setup (fallow-rs/fallow-skills, 129 stars) and Code Reviewer (LeoYeAI/openclaw-master-skills, 2.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
jwynia (a GitHub user) maintains it in jwynia/agent-skills, which has 169 GitHub stars. The repository holds 111 skills in this directory. The repository was last updated on February 24, 2026.
Source: jwynia/agent-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.