| name | typescript-standards |
| description | Guide for creating TypeScript libraries using the typescript-library-template pattern and applying its standards to existing projects. Use when setting up new npm packages, standardizing build scripts, configuring tooling (tsup, Vitest, ESLint, Prettier), or applying dual module format patterns. |
TypeScript Project Standards
Overview
This skill helps you create professional TypeScript libraries using the typescript-library-template pattern and apply these standards to existing projects. It provides a modern, production-ready setup with dual module format support, comprehensive testing, and consistent code quality tooling.
When to Use This Skill
Trigger this skill when:
- Creating a new TypeScript library or npm package
- Standardizing build scripts across TypeScript projects
- Setting up or migrating to dual module format (CommonJS + ES modules)
- Configuring modern tooling (tsup, Vitest, ESLint, Prettier)
- Applying consistent code quality standards
- Publishing packages to npm
- Migrating from older build tools (webpack, rollup, tsc alone)
Quick Start
Scenario 1: Creating a New Project
# Clone the template
git clone https://github.com/jordanburke/typescript-library-template.git my-library
cd my-library
# Remove template's git history
rm -rf .git
git init
# Install dependencies
pnpm install
# Customize (see references/template-setup.md for checklist)
# - Update package.json (name, description, repository)
# - Update README.md
# - Add your code to src/
# Validate everything works
pnpm validate
Scenario 2: Applying Standards to Existing Project
See references/standardization.md for detailed migration guide. Quick version:
- Update scripts in package.json to standardized pattern
- Install tooling: tsup, vitest, eslint, prettier
- Copy configs: tsup.config.ts, vitest.config.ts, eslint.config.mjs
- Update build outputs: Dual module format with proper exports
- Run validation:
pnpm validate
Core Standards
Script Commands
The template follows a consistent command pattern:
Main validation command:
pnpm validate # Format → Lint → Test → Build (use before commits)
Individual operations:
# Formatting
pnpm format # Write formatted code
pnpm format:check # Validate formatting only
# Linting
pnpm lint # Fix ESLint issues
pnpm lint:check # Check ESLint issues only
# Testing
pnpm test # Run tests once
pnpm test:watch # Watch mode
pnpm test:coverage # With coverage report
pnpm test:ui # Interactive UI
# Building
pnpm build # Production build (dist/)
pnpm dev # Development watch (lib/)
pnpm ts-types # Type check only
Dual Module Format
The template supports both CommonJS and ES modules:
package.json exports:
{
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
}
}
}
Build outputs:
lib/- Development builds (NODE_ENV !== "production")dist/- Production builds (NODE_ENV === "production")- Both directories published to npm
Build Configuration (tsup)
Key features:
- Environment-based output (lib/ vs dist/)
- Dual format (CJS + ESM)
- TypeScript declarations for both formats
- Source maps in development
- Minification in production
- Watch mode for development
Testing (Vitest)
Configuration highlights:
- Node.js environment
- v8 coverage provider
- Multiple reporters (text, json, html)
- Hot reload in watch mode
- UI mode available
Code Quality
ESLint:
- Flat config (eslint.config.mjs)
- TypeScript support
- Prettier integration
- Import sorting with simple-import-sort
- Strict type checking
Prettier:
- No semicolons
- Trailing commas
- Double quotes
- 120 character width
- 2 space tabs
TypeScript:
- Strict mode enabled
- Pragmatic exceptions:
noImplicitAny: falsestrictPropertyInitialization: false
- ESNext target
- Declaration files only (tsup handles transpilation)
Common Workflows
Creating a New Library
- Clone and customize (see references/template-setup.md)
- Develop with
pnpm dev(watch mode) - Test with
pnpm test:watch - Validate with
pnpm validatebefore commits - Publish with
npm publish(prepublishOnly auto-validates)
Standardizing an Existing Project
- Audit current setup - identify gaps
- Update package.json - scripts and dependencies
- Copy configurations - tsup, vitest, eslint
- Migrate build - switch to tsup with dual format
- Update exports - proper dual module support
- Test thoroughly - ensure all builds work
- Update documentation - new commands and workflows
Publishing to npm
The template includes safety checks:
{
"scripts": {
"prepublishOnly": "pnpm validate"
}
}
This ensures every publish:
- Formats code correctly
- Passes all linting
- Passes all tests
- Builds successfully
Publishing workflow:
# Update version
npm version patch # or minor, major
# Publish (prepublishOnly runs automatically)
npm publish --access public
Architecture Patterns
Environment-Based Builds
The tsup configuration (line 3 in tsup.config.ts) checks NODE_ENV:
const isDev = process.env.NODE_ENV !== "production"
export default defineConfig({
outDir: isDev ? "lib" : "dist",
minify: !isDev,
sourcemap: isDev,
// ...
})
Why two output directories?
lib/- Fast development builds, easier debuggingdist/- Optimized production builds, what npm gets
File Organization
project/
├── src/
│ ├── index.ts # Main entry point
│ └── **/*.ts # All source files
├── test/
│ └── *.spec.ts # Vitest tests
├── lib/ # Dev builds (gitignored)
├── dist/ # Prod builds (gitignored)
├── tsup.config.ts # Build config
├── vitest.config.ts # Test config
├── eslint.config.mjs # Lint config
├── .prettierrc # Format config (optional)
└── package.json # Scripts + exports
Troubleshooting
Build Issues
"Cannot find module" errors:
- Check package.json exports match build outputs
- Verify both .js and .mjs files exist in dist/
- Ensure types field points to .d.ts file
Watch mode not working:
- Check tsup.config.ts has watch: true for dev
- Verify NODE_ENV is not set to "production"
Test Issues
Tests not found:
- Check vitest.config.ts includes correct pattern
- Verify test files end in .spec.ts or .test.ts
- Ensure test/ directory exists
Coverage incomplete:
- Check coverage.include in vitest.config.ts
- Add exclude patterns for generated files
Import Issues
Dual module problems:
- Verify package.json exports use correct paths
- Check tsup generates both .js and .mjs
- Test with both
require()andimport
Type definitions missing:
- Ensure tsup config has
dts: true - Check .d.ts files generated in dist/
- Verify types field in package.json
Migration Checklist
When applying these standards to an existing project:
- Update package.json scripts to standardized pattern
- Install required devDependencies (tsup, vitest, eslint, prettier)
- Copy tsup.config.ts and adjust for your project
- Copy vitest.config.ts and adjust test patterns
- Copy eslint.config.mjs and adjust rules if needed
- Add/update .prettierrc with standard config
- Update tsconfig.json for strict mode
- Update package.json exports for dual module format
- Migrate tests to Vitest (if using different framework)
- Update GitHub Actions to use
pnpm validate - Update documentation (README, CLAUDE.md)
- Test with
pnpm validate - Verify published package works in both CJS and ESM projects
Resources
Reference Documents
- references/template-setup.md - Complete guide for using the template
- references/standardization.md - Detailed migration guide for existing projects
- references/tooling-reference.md - Configuration examples and patterns
External Links
- GitHub Template: https://github.com/jordanburke/typescript-library-template
- tsup Documentation: https://tsup.egoist.dev/
- Vitest Documentation: https://vitest.dev/
- ESLint Flat Config: https://eslint.org/docs/latest/use/configure/configuration-files
Key Files to Reference
When working with this template, these files contain the canonical configurations:
tsup.config.ts- Build configuration with environment logicvitest.config.ts- Test configuration with coverageeslint.config.mjs- Linting rules and TypeScript integrationpackage.json- Scripts, exports, and dependency versionsSTANDARDIZATION_GUIDE.md- Migration instructions
Best Practices
Development Workflow
- Always use
pnpm devduring development for fast rebuilds - Run
pnpm validatebefore committing changes - Use
pnpm test:watchwhile writing tests - Check
pnpm test:coverageto ensure adequate coverage
Code Quality
- Enable strict TypeScript - catches issues early
- Fix linting issues - don't disable rules without good reason
- Write tests - aim for high coverage on critical paths
- Format consistently - let Prettier handle style
Publishing
- Test locally - use
npm linkto test before publishing - Version semantically - follow semver (major.minor.patch)
- Update changelog - document changes for users
- Verify dual format - test in both CJS and ESM projects
Documentation
- Keep CLAUDE.md updated - helps Claude Code assist you
- Document commands - clear examples for all scripts
- Explain architecture - help future maintainers
- Link to references - point to this skill for standards