maxritter

typescript-standards

@maxritter/typescript-standards
maxritter
341
40 forks
Updated 1/7/2026
View on GitHub

TypeScript Standards: **Core Rule:** Detect and use the project's package manager. Write self-documenting TypeScript with explicit types on exports.

Installation

$skills install @maxritter/typescript-standards
Claude Code
Cursor
Copilot
Codex
Antigravity

Details

Path.claude/skills/typescript-standards/SKILL.md
Branchmain
Scoped Name@maxritter/typescript-standards

Usage

After installing, this skill will be available to your AI coding assistant.

Verify installation:

skills list

Skill Instructions

TypeScript Standards

Core Rule: Detect and use the project's package manager. Write self-documenting TypeScript with explicit types on exports.

When to use this skill

  • When installing packages or running scripts in a TypeScript project
  • When writing or modifying TypeScript code
  • When adding type annotations or organizing imports in a TypeScript project
  • When writing tests or running code quality tools in a TypeScript project

Package Manager Detection

CRITICAL: Always detect and use the project's existing package manager. NEVER mix package managers.

Check the project root for lock files:

  • bun.lockb → use bun
  • pnpm-lock.yaml → use pnpm
  • yarn.lock → use yarn
  • package-lock.json → use npm

If no lock file exists, check packageManager field in package.json, or default to npm.

Quick command mapping:

Actionnpmyarnpnpmbun
Install allnpm installyarnpnpm installbun install
Add packagenpm install pkgyarn add pkgpnpm add pkgbun add pkg
Add dev depnpm install -D pkgyarn add -D pkgpnpm add -D pkgbun add -D pkg
Run scriptnpm run scriptyarn scriptpnpm scriptbun script
Execute binarynpx cmdyarn cmdpnpm cmdbunx cmd

Type Annotations

Add explicit return types to all exported functions:

// Required for exports
export function processOrder(orderId: string, userId: number): Order {
  // implementation
}

// Required for async functions
export async function fetchUser(id: string): Promise<User> {
  // implementation
}

// Optional for internal functions (inference is fine)
function formatPrice(amount: number) {
  return `$${amount.toFixed(2)}`;
}

Prefer interfaces for object shapes, types for unions:

interface User {
  id: string;
  email: string;
  createdAt: Date;
}

type Status = 'pending' | 'active' | 'suspended';
type Handler = (req: Request, res: Response) => Promise<void>;

Code Style

Write self-documenting code. Minimize comments.

// BAD - comment explains unclear code
if (u.r === 'admin' || u.r === 'moderator') {

// GOOD - code explains itself
if (user.isAdmin() || user.isModerator()) {

Use concise one-line JSDoc for exported functions:

/** Calculate discounted price by applying rate. */
export function calculateDiscount(price: number, rate: number): number {
  return price * (1 - rate);
}

Import organization: Node built-ins → External packages → Internal modules → Relative imports

import { readFile } from 'node:fs/promises';
import express from 'express';
import { User } from '@/models/user';
import { formatPrice } from './utils';

Common Patterns

Use async/await, optional chaining, and nullish coalescing:

const email = user?.profile?.email ?? 'default@example.com';

async function fetchData(): Promise<Data> {
  const response = await fetch(url);
  return response.json();
}

Prefer node: prefix for built-in modules:

import { readFile } from 'node:fs/promises';
import path from 'node:path';

Use const assertions for literal types:

const ROLES = ['admin', 'user', 'guest'] as const;
type Role = typeof ROLES[number]; // 'admin' | 'user' | 'guest'

Don't swallow errors:

try {
  await process();
} catch (error) {
  logger.error('Processing failed', { error });
  throw error;
}

File Organization

Prefer editing existing files over creating new ones.

Before creating a new file, ask:

  1. Can this fit in an existing module?
  2. Is there a related file to extend?

Naming: kebab-case for files (user-service.ts), .test.ts or .spec.ts for tests.

Verification

Before marking work complete, always run these checks (using the detected package manager):

  1. Format code: Check package.json scripts for format or prettier. Otherwise: prettier --write . or biome format --write .
  2. Lint code: Check package.json scripts for lint. Otherwise: eslint . --fix or biome check --fix .
  3. Type check: Check package.json scripts for typecheck or tsc. Otherwise: tsc --noEmit
  4. Run tests: Check package.json scripts for test

Tip: Look at package.json scripts first — projects often have custom configurations. Use what's already defined.

Then verify:

  • All commands pass without errors
  • Explicit return types on exports
  • Lock file committed (if dependencies changed)