Built-in APIs Best Practices
Node 24 ships most primitives backends need - default to node: modules, promise APIs, and documented security patterns before adding npm surface area.
How to Use This List
- Review during dependency PRs that add packages overlapping built-ins.
- Apply to every new service bootstrap and file I/O path.
- Security-sensitive paths (crypto, paths, child_process) are mandatory items.
- Revisit when Node release notes add new stable APIs (e.g.,
fetch,test).
A - Module Selection
- Import built-ins with
node:prefix in application code.node:fs/promises,node:crypto, etc. - Prefer promise APIs (
fs/promises,timers/promises) over callbacks. promisify only for third-party callbacks. - Use global
fetchandnode:testbefore adding node-fetch/Jest for simple cases. Fewer dependencies. - Evaluate npm package only when built-in lacks feature (retry policies, OTel SDK). Document ADR when adding overlap.
- Pin
@types/nodeto runtime major (24.x). Typings match API availability.
B - Filesystem and Streams
- Never
readFileSync/writeFileSyncon request paths. Blocks event loop. - Stream files larger than a few MB with
createReadStream+pipeline. Bounded memory. - Guard path traversal on user-influenced paths.
resolve+ prefix check under base dir. - Set unix file mode
0o600on secrets written to disk. Restrictive permissions. - Close file handles in
finallywhen usingfs.open. Prevent EMFILE leaks.
C - Crypto and URLs
- Generate tokens with
randomBytes/randomUUID, neverMath.random. CSPRNG only. - Verify webhooks with HMAC and
timingSafeEqualon equal-length digests. No plain string compare. - Hash passwords with scrypt/argon2 - not SHA256 alone. Tune cost parameters.
- Parse URLs with WHATWG
URL- not legacyurl.parse. SSRF allowlist on hostname. - Do not log secrets, full env, or signature bytes. Redact in errors.
D - Process, OS, and Timers
- Size pools with
os.availableParallelism(), not raw cpu count in containers. Correct vCPU awareness. - Validate
process.envonce at boot with Zod. Immutable config after parse. - Handle SIGTERM with HTTP drain - see processes section. Built-in
httpservers too. - Clear timers on shutdown; use
unreffor optional background ticks. Clean deploy exit. - Expose minimal host metadata in public health endpoints. No internal network enumeration.
E - Diagnostics
- Use
util.inspectlimits when logging objects - not unbounded JSON.stringify. Avoid cycles and PII dumps. - Enable
NODE_DEBUGonly in dev/staging reproduction. Not permanent in production. - Use
perf_hooksevent loop metrics in staging load tests. Correlate with user latency. - Bookmark Node 24 API docs for version-specific APIs (
parseEnv,styleText). Avoid outdated blog patterns. - Subscribe
diagnostics_channelwith cleanup in tests. No listener leaks.
FAQs
When is npm fs-extra OK?
When you need recursive copy/remove helpers not in core - otherwise fs/promises + mkdir recursive.
axios vs fetch?
fetch built-in for simple calls; axios/got when interceptors/retries/agent tuning required - ADR optional.
Is uuid package needed?
crypto.randomUUID covers most ID cases - uuid npm for non-v4 formats only.
dotenv vs --env-file?
Node --env-file for dev; production inject from platform; always Zod validate after load.
bcrypt npm vs scrypt?
Both acceptable with tuning - pick one org standard; native scrypt reduces deps.
Should health log freemem publicly?
No - internal metrics only; public health stays minimal status + version.
child_process in built-ins scope?
Yes - spawn rules in Processes Best Practices.
Web Crypto vs node:crypto?
Use subtle for AES-GCM interop; HMAC/hashing often simpler on node:crypto.
Testing without disk?
Mock fs module or use temp dir with cleanup - not sync fs in tests for speed habits.
Built-in test runner enough?
node:test for unit tests; Vitest/Jest when team needs richer DX - still built-in viable on Node 24.
Express still needed?
Built-in http sufficient for probes; Express 5/Fastify 5 for product APIs - built-ins underpin both.
Where is full fs reference?
fs and fs/promises in this section.
Related
- Built-in APIs Basics - module tour
- Node.js Fundamentals Best Practices - LTS and env
- Essential Libraries Basics - when to add npm
- Security Basics - broader security
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.