name: node-style
path: package.json
description: Use when writing or reviewing code in a Node.js or TypeScript project.
Node Coding Style
Rules distilled from TigerBeetle's TigerStyle, Node.js, and V8 internals.
Current APIs, defaults, and numbers: references/canonical.md.
Goals
Safety before performance before developer experience, in that order.
Wrong but fast is worthless.
Design first
Sketch before code: network, disk, memory, CPU, each by bandwidth and latency.
Attack the slowest resource first, weighted by how often it is used.
Design-phase wins are 1000x. Post-profile wins are 10x.
Rules
Put a limit on everything: loops, queues, batches, request sizes, input lengths.
Batch everything: IO, requests, parsing, allocation. Fixed costs pay for many items.
Bound work per tick. The event loop is the fairness scheduler, one callback is one small turn.
Never block the loop: no sync fs, crypto, zlib, child_process in servers. No giant JSON on the loop. No unproven regex on input.
Respect backpressure: write() === false means stop until drain. Compose streams with pipeline().
Keep shapes stable: same properties, same order, every time. Never delete. Hot call sites stay monomorphic.
Bytes in Buffer or TypedArray: bulk data never rides through strings. Share memory instead of copying.
Allocation rate is the lever: when GC runs, your code does not.
Chunk or offload CPU work: yield per chunk on the loop, or use a bounded worker pool. Transfer buffers, never clone.
Validate at boundaries, handle every error path, fail fast.
Drain queues at your own pace: work per tick, not work per event.
Small functions: pure leaves, control flow centralized in one place.
Say why: comments carry rationale, not narration.
Never
Unbounded anything, even temporarily.
O(n) work over attacker-sized input on the loop.
Performance work without an envelope sketch.
Trading correctness for latency.
---
name: node-style
path: package.json
description: Use when writing or reviewing code in a Node.js or TypeScript project.
---
# Node Coding Style
Rules distilled from TigerBeetle's TigerStyle, Node.js, and V8 internals.
Current APIs, defaults, and numbers: [references/canonical.md](references/canonical.md).
## Goals
Safety before performance before developer experience, in that order.
Wrong but fast is worthless.
## Design first
Sketch before code: network, disk, memory, CPU, each by bandwidth and latency.
Attack the slowest resource first, weighted by how often it is used.
Design-phase wins are 1000x. Post-profile wins are 10x.
## Rules
- Put a limit on everything: loops, queues, batches, request sizes, input lengths.
- Batch everything: IO, requests, parsing, allocation. Fixed costs pay for many items.
- Bound work per tick. The event loop is the fairness scheduler, one callback is one small turn.
- Never block the loop: no sync fs, crypto, zlib, child_process in servers. No giant JSON on the loop. No unproven regex on input.
- Respect backpressure: `write() === false` means stop until `drain`. Compose streams with `pipeline()`.
- Keep shapes stable: same properties, same order, every time. Never `delete`. Hot call sites stay monomorphic.
- Bytes in Buffer or TypedArray: bulk data never rides through strings. Share memory instead of copying.
- Allocation rate is the lever: when GC runs, your code does not.
- Chunk or offload CPU work: yield per chunk on the loop, or use a bounded worker pool. Transfer buffers, never clone.
- Validate at boundaries, handle every error path, fail fast.
- Drain queues at your own pace: work per tick, not work per event.
- Small functions: pure leaves, control flow centralized in one place.
- Say why: comments carry rationale, not narration.
## Never
- Unbounded anything, even temporarily.
- O(n) work over attacker-sized input on the loop.
- Performance work without an envelope sketch.
- Trading correctness for latency.