From harness-claude
Organizes TypeScript code with ES modules, barrel exports, path aliases, and declaration files. Helps structure import/export architecture and avoid circular dependencies.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:ts-module-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Organize TypeScript code with ES modules, barrel exports, path aliases, and declaration files
Organize TypeScript code with ES modules, barrel exports, path aliases, and declaration files
// user.ts
export interface User {
id: string;
name: string;
}
export function createUser(name: string): User {
/* ... */
}
// consumer.ts
import { User, createUser } from './user';
index.ts to create clean module boundaries:// features/auth/index.ts
export { AuthProvider } from './auth-provider';
export { useAuth } from './use-auth';
export type { AuthState, AuthAction } from './types';
// Consumer imports from the module, not internal files
import { AuthProvider, useAuth } from '@/features/auth';
tsconfig.json:{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@/db/*": ["src/db/*"],
"@/lib/*": ["src/lib/*"]
}
}
}
Mirror in your bundler config (Next.js, Vite, etc.) so runtime resolution matches TypeScript's.
export type for type-only exports — prevents runtime import of type-only modules:export type { User, Post } from './types';
export { createUser } from './user';
import type for type-only imports:import type { User } from './types';
import { createUser } from './user';
Enable verbatimModuleSyntax in tsconfig to enforce this distinction.
// legacy-module.d.ts
declare module 'legacy-module' {
export function doWork(input: string): number;
export interface Config {
verbose: boolean;
}
}
import * as Schema from '@/db/schema';
const user = Schema.users;
const post = Schema.posts;
Avoid circular imports — if module A imports from B and B imports from A:
import type when only types are needed (type imports are erased and do not cause runtime circularity)Package entry points — configure exports in package.json for library projects:
{
"exports": {
".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },
"./utils": { "types": "./dist/utils.d.ts", "import": "./dist/utils.js" }
}
}
TypeScript modules follow the ES module standard. Each file with a top-level import or export is a module; files without them are scripts (global scope).
verbatimModuleSyntax (recommended): Forces you to use import type for type-only imports and export type for type-only re-exports. This eliminates ambiguity about which imports are erased during compilation.
Barrel file trade-offs:
Path aliases require bundler sync: TypeScript's paths only affect type checking. The runtime module resolver (Node.js, Vite, webpack) must also be configured to resolve the same aliases.
moduleResolution options:
node — traditional Node.js resolution (index.ts, package.json main)node16 / nodenext — Node.js ESM resolution (requires file extensions in imports)bundler — modern bundler resolution (Vite, webpack, esbuild). Best choice for most frontend projectsTrade-offs:
verbatimModuleSyntax catches real bugs but requires existing code to be updated with import typehttps://typescriptlang.org/docs/handbook/modules.html
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeGuides TypeScript library authoring: project setup, dual CJS/ESM package exports, tsdown/unbuild config, type-safe API design, advanced type patterns, vitest testing, and npm release workflows.
Provides advanced TypeScript patterns including generics, conditional types, mapped types, decorators, and strict type safety for enterprise-grade development.
Provides advanced TypeScript/JavaScript expertise for type-level programming, performance optimization, monorepo management, migrations, and modern tooling. Analyzes projects, applies fixes, and validates with typechecks/tests.