observerw/project-skills · Archived

typescript-project

Comprehensive guide for TypeScript and JavaScript repositories with a Biome-first toolchain.

First seen Mar 5, 2026

Installation

$ npx skills add observerw/project-skills --skill typescript-project

Summary

  • Comprehensive guide for TypeScript and JavaScript repositories with a Biome-first toolchain.
  • This skill MUST be consulted before writing, reviewing, or refactoring code in TS/JS projects to enforce consistent linting, formatting, type safety, and delivery checks.
  • Use when working on .ts/.tsx/.mts/.cts/.js/.jsx files, tsconfig, package scripts, or tooling in Node.js and frontend projects.

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from observerw/project-skills.

npx skills add observerw/project-skills

Browse all from observerw/project-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,672 B
  • docs SUMMARY.md 416 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 3 installs

SKILL.md

TypeScript Programming Guide

Toolchain

  • Use Bun as the only package manager and runtime.
  • Use the following defaults when scripts are missing:

- Install deps: bun install - Type check: bun run tsc --noEmit - Lint + fix: bunx biome check --write <FILEPATH> - Format only: bunx biome format --write <FILEPATH> - Tests: bun test

  • Run both Biome and type checks before finishing.
  • Avoid introducing ESLint + Prettier in repositories that already use Biome.
  • NEVER use npm, pnpm, yarn, npx, or pnpx.

References

Read these files before deep modifications:

  • references/biome.md - before editing Biome config, lint rules, or formatting behavior
  • references/typescript-conventions.md - before changing API types, async flows, or error handling

Missing vs Empty Policy

  • undefined means missing; null means empty.
  • Do not manually create undefined (= undefined, return undefined, { key: undefined }).
  • Represent missing by omitting keys.

Code Standards

You MUST follow all rules and anti-patterns in the example below before writing code.

import type { IncomingHttpHeaders } from "node:http";
import { randomUUID } from "node:crypto";

// RULE: Prefer `type` for unions/intersections and function signatures.
type UserId = string & { readonly __brand: "UserId" };

interface UserRecord {
  id: UserId;
  email: string;
  headers: IncomingHttpHeaders;
  createdAt: Date;
}

// RULE: Model fallible operations with discriminated unions.
type LoadUserResult = { ok: true; user: UserRecord } | { ok: false; reason: "not_found" | "timeout" };

async function loadUser(id: UserId): Promise<LoadUserResult> {
  if (id.length === 0) {
    return { ok: false, reason: "not_found" };
  }

  return {
    ok: true,
    user: {
      id,
      email: "[email protected]",
      headers: {},
      createdAt: new Date(),
    },
  };
}

// RULE: Accept external input as `unknown`, then narrow.
function parsePort(value: unknown): number {
  if (typeof value !== "string") {
    return 3000;
  }

  const port = Number(value);
  if (!Number.isInteger(port) || port <= 0) {
    return 3000;
  }

  return port;
}

// RULE: Use `satisfies` to validate object shape without widening.
const DEFAULT_CONFIG = {
  timeoutMs: 5_000,
  retry: 2,
} satisfies {
  timeoutMs: number;
  retry: number;
};

function formatResult(result: LoadUserResult): string {
  // RULE: Use exhaustive checks for discriminated unions.
  switch (result.ok) {
    case true:
      return `ok:${result.user.email}`;
    case false:
      return `error:${result.reason}`;
    default: {
      const unreachable: never = result;
      return unreachable;
    }
  }
}

// RULE: Keep indentation shallow with guard clauses.
async function handle(rawId: unknown): Promise<string> {
  if (typeof rawId !== "string" || rawId.length === 0) {
    return "invalid_user_id";
  }

  const result = await loadUser(rawId as UserId);
  return formatResult(result);
}

// RULE: Throw typed errors with actionable context.
class ServiceError extends Error {
  constructor(
    message: string,
    public readonly code: "timeout" | "internal",
  ) {
    super(message);
    this.name = "ServiceError";
  }
}

// ANTI-PATTERN: Use `any` as a default escape hatch.
// function parseBad(x: any): any { ... }

// ANTI-PATTERN: Return tuples for complex multi-field results.
// function loadBad(): Promise<[UserRecord | null, string | null]> { ... }

// ANTI-PATTERN: Throw plain strings.
// throw "something failed";

// ANTI-PATTERN: Mix unrelated behavior with boolean control flags.
// function buildReport(data: Item[], debug: boolean, skipCache: boolean) { ... }

// ANTI-PATTERN: Manually manufacture undefined.
// const badPatch = { nickname: undefined };

Delivery Checklist

Before finishing:

  • Ensure Biome checks pass on touched files.
  • Ensure tsc --noEmit passes.
  • Ensure commands were executed with bun / bunx only.
  • Ensure missing/empty semantics are correct (undefined=missing, null=empty).
  • Ensure exported APIs have explicit, stable types.
  • Ensure async code handles failure paths (timeout, cancellation, transport errors).
  • Ensure tests are added or updated for behavior changes.