TPT

ts-package-template

Development

Development Workflow

Recommended development workflow for the ts-package-template

The content in this page may have been generated by AI.

This guide outlines the recommended development workflow for using the ts-package-template. Following these workflows will help you maintain code quality, ensure proper testing, and streamline the publishing process.

Getting Started Workflow

Set Up the Project

  1. Clone the repository or use it as a GitHub template
  2. Install dependencies:
    pnpm install
  3. Customize package information in package.json

Initialize Git Hooks

The pre-commit hooks are automatically set up when you install dependencies:

pnpm install

This installs lefthook which sets up the Git hooks.

Verify Setup

Run the following commands to ensure everything is working:

# Check code quality
pnpm run check

# Run tests
pnpm run test

# Build the package
pnpm run build

Daily Development Workflow

Making Changes

  1. Create a feature branch:

    git checkout -b feat/your-feature-name
  2. Make your changes in the src/ directory

  3. Add corresponding tests in the test/ directory

  4. Run tests in watch mode:

    pnpm run test:watch
  5. Start development server (optional):

    pnpm run dev
  1. Create a bug fix branch:

    git checkout -b fix/your-bug-fix
  2. Reproduce the bug by adding a failing test

  3. Fix the bug in the source code

  4. Verify the fix by running the tests:

    pnpm run test
  1. Create a refactor branch:

    git checkout -b refactor/your-refactor
  2. Make refactoring changes in the source code

  3. Update tests if the refactoring affects the API

  4. Run all checks:

    pnpm run check
    pnpm run test
    pnpm run build

Committing Changes

Stage Your Changes

git add .

Or add specific files:

git add src/index.ts test/index.test.ts

Pre-commit Hooks

When you run git commit, the pre-commit hook automatically:

  1. Runs ultracite fix to format and lint your code
  2. Automatically stages any files that were fixed

The pre-commit hook runs automatically. If it fails, fix the issues and try committing again.

Write Commit Message

Use Conventional Commits format:

# For a new feature
git commit -m "feat: add new math utility function"

# For a bug fix
git commit -m "fix: correct division by zero error"

# For a refactor
git commit -m "refactor: simplify utility functions"

# For documentation
git commit -m "doc: update README with usage examples"

# For chore/maintenance
git commit -m "chore: update dependencies"

Push Changes

git push origin your-branch-name

Code Quality Workflow

Checking Code Quality

Run Linting

Check for linting and formatting issues:

pnpm run check

This runs Biome to check for code quality issues.

Fix Issues Automatically

Fix all auto-fixable issues:

pnpm run fix

This runs Biome to automatically fix linting and formatting issues.

Manual Fixes

For issues that can't be fixed automatically, manually fix them and run pnpm run check again.

Type Checking

Run TypeScript type checking:

pnpm run build

This runs tsc (TypeScript compiler) to check for type errors.

The build script runs type checking as part of the build process. You can also run tsc --noEmit for just type checking without emitting files.

Testing Workflow

Running Tests

Run all tests once:

pnpm run test

Run a specific test file:

pnpm run test src/utils.test.ts

Run tests matching a pattern:

pnpm run test -- --testNamePattern="math"

Run tests in watch mode:

pnpm run test:watch

This automatically re-runs tests when files change.

Run tests with coverage:

pnpm run test -- --coverage

This generates a coverage report showing which parts of your code are tested.

Test-Driven Development (TDD)

Write Failing Test

Write a test for the feature you want to implement:

// test/new-feature.test.ts
import { describe, test, expect } from "vitest";

describe("new feature", () => {
  test("should do something", () => {
    expect(newFeature()).toBe("expected result");
  });
});

Run Test (Should Fail)

pnpm run test

The test should fail because the feature isn't implemented yet.

Implement Feature

Implement the feature in the source code:

// src/new-feature.ts
export function newFeature(): string {
  return "expected result";
}

Run Test (Should Pass)

pnpm run test

The test should now pass.

Refactor

Refactor the code while keeping the tests passing.

Build Workflow

Building the Package

Development Build

For development with hot reload:

pnpm run dev

This watches for changes and rebuilds automatically.

Production Build

For production-ready build:

pnpm run build

This runs type checking and bundling to create optimized output in the dist directory.

Verify Build Output

Check the dist directory to ensure the build output is correct:

ls -la dist/

Release Workflow

Preparing a Release

Update Version

Update the version in package.json:

# Patch version (x.x.1)
npm version patch

# Minor version (x.1.x)
npm version minor

# Major version (1.x.x)
npm version major

This automatically:

  1. Updates the version in package.json
  2. Creates a git tag
  3. Runs the postversion script (which updates the changelog)

Update Changelog Manually (Optional)

If you want to manually update the changelog:

pnpm run changelog

The changelog is automatically updated by the postversion script when you use npm version.

Build the Package

pnpm run build

Run Final Checks

# Run tests
pnpm run test

# Check code quality
pnpm run check

# Build again to ensure everything is correct
pnpm run build

Publishing the Package

Publish manually:

pnpm run publish

This runs np which guides you through the publishing process.

Build and publish in one command:

pnpm run publish:all

This runs the build and then publishes the package.

For CI/CD environments:

# Set npm token
npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}

# Build and publish
pnpm run build
pnpm run publish -- --yes

Continuous Integration Workflow

GitHub Actions Example

Here's an example GitHub Actions workflow for the template:

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'
      
      - name: Install pnpm
        run: npm install -g pnpm
      
      - name: Install dependencies
        run: pnpm install --frozen-lockfile
      
      - name: Check code quality
        run: pnpm run check
      
      - name: Run tests
        run: pnpm run test
      
      - name: Build package
        run: pnpm run build

  publish:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'
      
      - name: Install pnpm
        run: npm install -g pnpm
      
      - name: Install dependencies
        run: pnpm install --frozen-lockfile
      
      - name: Build package
        run: pnpm run build
      
      - name: Publish to npm
        run: pnpm run publish -- --yes
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Troubleshooting Workflow

Common Issues

IssueSolution
Tests failingRun pnpm run test to identify failing tests
Linting errorsRun pnpm run fix to fix issues automatically
Type errorsRun pnpm run build to identify type errors
Build failingCheck the error message and fix the issue
Hooks not runningEnsure lefthook is installed and hooks are set up

Debugging

Enable debug mode for various tools:

# Debug pnpm
DEBUG=pnpm* pnpm install

# Debug tsdown/Rolldown
DEBUG=tsdown pnpm run build

# Debug Vitest
DEBUG=vitest pnpm run test

# Debug Biome
DEBUG=biome pnpm run check

Best Practices

Commit Messages

  • Use Conventional Commits format
  • Keep commit messages clear and descriptive
  • Use the imperative mood ("add" not "added")
  • Reference issues when applicable

Branch Naming

  • Use descriptive branch names
  • Use the commit type as a prefix (feat/, fix/, refactor/, etc.)
  • Keep branch names short but meaningful

Code Quality

  • Run pnpm run check before committing
  • Run pnpm run fix to automatically fix issues
  • Keep your code formatted consistently
  • Follow the project's linting rules

Testing

  • Write tests for all new features
  • Write tests for bug fixes
  • Keep tests fast and reliable
  • Run tests before pushing changes

Documentation

  • Update documentation when adding new features
  • Keep the README.md up to date
  • Document breaking changes in the CHANGELOG.md

Dependencies

  • Keep dependencies up to date
  • Use pnpm up to update dependencies
  • Check for security vulnerabilities regularly
  • Remove unused dependencies

Project Structure Maintenance

Adding New Files

When adding new files:

  1. Source files: Add to /src/ directory
  2. Test files: Add to /test/ directory with .test.ts suffix
  3. Configuration files: Add to root or appropriate subdirectories
  4. Update tsconfig.json: Ensure new TypeScript files are included

Organizing Code

  • Keep related code together
  • Use clear and consistent naming
  • Follow the existing project structure
  • Use path aliases for cleaner imports

Cleaning Up

Regularly clean up your project:

# Remove node_modules and reinstall
rm -rf node_modules pnpm-lock.yaml
pnpm install

# Clean up build output
rm -rf dist

# Clean up pnpm store (optional)
pnpm store prune

Resources

On this page