New to Claude Skills? Learn how to install them →

Nmcollina on GitHub

Node.js Best Practices

Free

Master Node.js development with TypeScript best practices.

by mcollina1.9k stars on mcollina/skills
1 views
Updated Aug 3, 2026
Get this skill

Free · Opens the source repo

What Node.js Best Practices does

The Node.js Best Practices skill provides a comprehensive set of guidelines and patterns specifically designed for developing robust applications using Node.js and TypeScript. This skill is particularly useful for developers looking to leverage the latest features of Node.js, such as type stripping introduced in version 22.6+. By following the best practices outlined in this skill, developers can ensure that their applications are not only maintainable but also performant.

This skill covers a variety of essential topics, including error handling, graceful shutdown procedures, logging strategies, and performance optimization techniques. Each topic is accompanied by detailed rules and examples, allowing users to implement these practices seamlessly in their projects. For instance, it emphasizes the importance of using import type for type-only imports and provides a clear path for configuring TypeScript without the need for a build step, which can significantly streamline the development process.

In addition to foundational practices, the skill also addresses common challenges developers face, such as diagnosing flaky tests and managing stuck processes. With practical workflows and diagnostic strategies, users can quickly troubleshoot issues and maintain high code quality throughout the development lifecycle. The skill is structured to guide users through multi-step processes, ensuring that they can apply best practices effectively across different scenarios.

Overall, this skill is an invaluable resource for any Node.js developer looking to enhance their TypeScript development capabilities and build applications that are robust, efficient, and easy to maintain.

When to use it

Use this skill when starting a new Node.js project with TypeScript or when needing guidance on specific development challenges.

When not to use it

This skill may not be suitable for projects that do not utilize Node.js or TypeScript, or for developers looking for generic JavaScript practices.

What you can build with it

Setting up a new Node.js project

Use this skill to configure a new Node.js project with TypeScript, ensuring best practices are followed from the start.

Improving application performance

Leverage the performance optimization techniques outlined in this skill to enhance the efficiency of your Node.js applications.

Troubleshooting stuck processes

Consult the troubleshooting guidelines for diagnosing and resolving issues with stuck Node.js processes or tests.

How to install Node.js Best Practices

View source

1. Install with the skills CLI

npx skills add mcollina/skills/node --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by mcollina

When to use

Use this skill whenever you are dealing with Node.js code to obtain domain-specific knowledge for building robust, performant, and maintainable Node.js applications.

TypeScript with Type Stripping

When writing TypeScript for Node.js, use type stripping (Node.js 22.6+) instead of build tools like ts-node or tsx. Type stripping runs TypeScript directly by removing type annotations at runtime without transpilation.

Key requirements for type stripping compatibility:

  • Use import type for type-only imports
  • Use const objects instead of enums
  • Avoid namespaces and parameter properties
  • Use .ts extensions in imports

Minimal example — a valid type-stripped TypeScript file:

// greet.ts
import type { IncomingMessage } from 'node:http';

const greet = (name: string): string => `Hello, ${name}!`;
console.log(greet('world'));

Run directly with:

node greet.ts

See rules/typescript.md for complete configuration and examples.

Common Workflows

For multi-step processes, follow these high-level sequences before consulting the relevant rule file:

Graceful shutdown: Register signal handlers (SIGTERM/SIGINT) → stop accepting new work → drain in-flight requests → close external connections (DB, cache) → exit with appropriate code. See rules/graceful-shutdown.md.

Error handling: Define a shared error base class → classify errors (operational vs programmer) → add async boundary handlers (process.on('unhandledRejection')) → propagate typed errors through the call stack → log with context before responding or crashing. See rules/error-handling.md.

Diagnosing flaky tests: Isolate the test with --test-only → check for shared state or timer dependencies → inspect async teardown order → add retry logic as a temporary diagnostic step → fix root cause. See rules/flaky-tests.md.

Diagnosing stuck processes/tests (node --test hangs, "process did not exit", CI timeout, open handles): isolate file/test → run with explicit timeout/reporter → inspect handles via why-is-node-running (SIGUSR1) → patch deterministic teardown in resource-creation scope → rerun isolated + full suite until stable. See rules/stuck-processes-and-tests.md.

Profiling a slow path: Reproduce under realistic load → capture a CPU profile with --cpu-prof → identify hot functions → check for stream backpressure or unnecessary serialisation → validate improvement with a benchmark. See rules/profiling.md and rules/performance.md.

High-priority activation checklist (streams + caching)

When the task mentions CSV, ETL, ingestion pipelines, large file processing, backpressure, repeated lookups, or deduplicating concurrent async calls, explicitly apply this checklist:

  1. Use await pipeline(...) from node:stream/promises (prefer this over chained .pipe() in guidance/code).
  2. Include at least one explicit async function* transform when data is being transformed in-stream.
  3. Choose a cache strategy when repeated work appears:
    • lru-cache for bounded in-memory reuse in a single process.
    • async-cache-dedupe for async request deduplication / stale-while-revalidate behavior.
  4. Show where backpressure is handled (implicitly via pipeline() or explicitly via drain).

Integrated example pattern (CSV/ETL)

For CSV/ETL-style prompts, prefer an answer structure like:

  • createReadStream(input)
  • async function* parser/transform
  • optional cached enrichment lookup (async-cache-dedupe or lru-cache)
  • await pipeline(...) to a writable destination

Link relevant rules directly in explanations so models can retrieve details:

How to use

Read individual rule files for detailed explanations and code examples:

Frequently asked questions about Node.js Best Practices

Similar skills