From harness-claude
Organizes TypeScript code with ES modules, barrel exports, path aliases, declaration files, named exports, type-only imports, and strategies to avoid circular dependencies.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Organize TypeScript code with ES modules, barrel exports, path aliases, and declaration files
Guides TypeScript library/npm package authoring: project setup, package.json exports, tsdown/unbuild builds, API design patterns, type inference, vitest testing, CI/CD, and npm publishing.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
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