ia-nodejs-backend
Node.js backend patterns: layered architecture, TypeScript, validation, error handling, security, observability, logging, metrics, deployment. Use when building REST APIs, REST endpoints, middleware, Express/Fastify/Hono/NestJS/Koa servers, tRPC procedures, Bun servers, or server-side TypeScript. Skill: ia-nodejs-backend Owner: iliaal Summary: Node.js backend patterns: layered architecture, TypeScript, validation, error handling, security, observability, logging, metrics, deployment. Use when building REST APIs, REST endpoints, middleware, Express/Fastify/Hono/NestJS/Koa servers, tRPC procedures, Bun servers, or server-side TypeScript. Tags: latest:5.0.1 Version history: v5.0.1 | 2026-10-03T17:05:48.776Z | us
Rank
62
Safety
84
Downloads
2.5k
Updated
Oct 9, 2026
Version
5.0.1
Source
CLAWHUB
About
What it does, and when to use it.
Capability contract not published. No trust telemetry is available yet. 2.5K downloads reported by the source. Last updated 10/9/2026.
Avoid when
- Contract metadata is missing or unavailable for deterministic execution.
Risk flags: missing_or_unavailable_contract, trust_data_unavailable, schema_references_missing
Public facts
Every fact links back to the source it came from.
- Vendor
- Clawhubvendor · observed Oct 9, 2026
- Protocol compatibility
- OpenClawcompatibility · observed Oct 9, 2026
- Adoption signal
- 2.5K downloadsadoption · observed Oct 9, 2026
- Latest release
- 5.0.1release · observed Oct 3, 2026
- Handshake status
- UNKNOWNsecurity
Install and run
Setup complexity: low.
clawhub skill install s17bcar8wq0xhegs0ny6f57ypd8484bw:compound-eng-nodejs-backend- Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.
- Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data.
Contract: missing
curl -s "https://www.xpersona.co/api/v1/agents/clawhub-iliaal-compound-eng-nodejs-backend/snapshot"
Documentation
CLAWHUB
146,390 characters of source documentation, loaded on request.
Extracted files
5 files captured from the source.
SKILL.md
---
name: ia-nodejs-backend
class: language
description: >-
Node.js backend patterns: layered architecture, TypeScript, validation, error
handling, security, observability, logging, metrics, deployment. Use when building REST APIs, REST endpoints, middleware,
Express/Fastify/Hono/NestJS/Koa servers, tRPC procedures, Bun servers, or server-side TypeScript.
paths: "**/*.ts,**/*.js,**/*.mjs,**/*.cjs"
---
# Node.js Backend
**Verify before implementing**: For framework-specific APIs (Express 5, Fastify 5, Node.js 22+ built-ins), look up current, version-matched official docs before writing code. Prefer Context7 (`query-docs`) when available. Otherwise use available web tools to read the framework's official documentation, or the [Node.js API docs](https://nodejs.org/api/) for Node.js built-ins. Training data may lag current releases.
## Working rules
- Validate request and third-party data before use; keep response serialization and error envelopes explicit.
- Preserve caller-visible contracts and authorization when adding resilience or fallbacks.
- Bound concurrency, set timeouts, and avoid blocking production request paths.
- Verify actual resource identity before parsing or caching a reused client's result.
- Exercise operational telemetry and failure paths, not successful return codes alone.
## Architecture
```
src/
├── routes/ # HTTP: parse request, call service, format response
├── middleware/ # Auth, validation, rate limiting, logging
├── services/ # Business logic (no HTTP types)
├── repositories/ # Data access only (queries, ORM)
├── config/ # Env, DB pool, constants
└── types/ # Shared TypeScript interfaces
```
- Routes never contain business logic
- Services never import Request/Response
- Repositories never throw HTTP errors
- Dependencies point inward only (Clean Architecture rule): routes -> services -> repositories. Never the reverse.
- For scripts/prototypes: single file is fine; ask "will this grow?"
## TypeScript Rules
- Use `import type { }` for type-only imports; eliminates runtime overhead
- Prefer `interface` for object shapes (2-5x faster type resolution than intersections)
- Prefer `unknown` over `any`; forces explicit narrowing
- Use `z.infer<typeof Schema>` as single source of truth; never duplicate types and schemas
- Minimize `as` assertions; use type guards instead
- Add explicit return types to exported functions (faster declaration emit)
- Untyped package? `declare module 'pkg' { const v: unknown; export default v; }` in `types/ambient.d.ts`
## Discipline
- Simplicity first: every change as simple as possible, impact minimal code
- Only touch what's necessary; avoid introducing unrelated changes
- No hacky workarounds: if a fix feels wrong, step back and implement the clean solution
- Before adding a new abstraction, verify it appears in 3+ places. If not, inline it.
- If a fix requires bypassing TypeScript (`as any`, non-null assertions on untrusted data, `/_meta.json
{
"ownerId": "kn715jrbbh71q9zncr0bqdkr8n848q1a",
"slug": "compound-eng-nodejs-backend",
"version": "5.0.1",
"publishedAt": 1791047148776
}references/api-boundaries.md
# API boundaries
## Framework Selection
| Context | Choose | Why |
|---------|--------|-----|
| Edge/Serverless | Hono | Zero-dep, fastest cold starts |
| Performance API | Fastify | Higher throughput than Express, built-in schema validation |
| Enterprise/team | NestJS | DI, decorators, structured conventions |
| Legacy/ecosystem | Express | Most middleware, widest adoption |
Ask user: deployment target, cold start needs, team experience, existing codebase.
## Validation
**Zod** (TypeScript inference) or **TypeBox** (Fastify native). Validate at boundaries only: request entry, before DB ops, env vars at startup. Use `.extend()`, `.pick()`, `.omit()`, `.partial()`, `.merge()` for DRY schemas.
- **`z.coerce.boolean()` is `Boolean(v)`.** Every non-empty string is truthy, so the literal strings `"false"`, `"0"`, `"no"` and `"off"` all coerce to `true`; only `""` and a real boolean `false` yield `false`. Clients and LLM callers routinely emit booleans as JSON strings, and the advertised schema saying `type: boolean` does not stop a host that forwards arguments unvalidated. The damage concentrates exactly where it is worst: a default-true flag can be forced on but never string-off, and a destructive flag (`kill_existing`, `force`, `active`) passed `"false"` fires. Use plain `z.boolean()` where fail-loud is acceptable, or `z.preprocess` the known spellings before `z.boolean()` so unrecognized strings still reject rather than silently becoming `true`. `.optional()` short-circuits `undefined` before the preprocess, so optional params still default correctly, and JSON Schema generation still emits `{ type: "boolean" }`.
- **Zod v4 removed the single-argument `z.record(valueType)`**; it requires `z.record(keyType, valueType)`, e.g. `z.record(z.string(), z.number())`. TypeScript rejects the single-arg form immediately (`tsc`: `Expected 2-3 arguments, but got 1`). If the type error is suppressed, the lone argument becomes the KEY schema and `valueType` stays `undefined`, so the first `.parse()` on a non-empty object throws `TypeError: Cannot read properties of undefined (reading '_zod')`, a raw TypeError, not a Zod validation error.
## Error Handling
Custom error hierarchy: `AppError(message, statusCode, code, isOperational)` → `ValidationError(400)`, `NotFoundError(404)`, `UnauthorizedError(401)`, `ForbiddenError(403)`, `ConflictError(409)`
Centralized handler middleware:
- `AppError` → return `{ error: { code, message, details? } }` with `statusCode`; expose only client-safe details
- Unknown → log full stack, return 500 with `{ error: { code: 'INTERNAL_ERROR', message: 'Internal server error' } }` in production
- Async wrapper: `const asyncHandler = (fn) => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);`
For custom transport callbacks, event listeners, and subscription handlers, establish the error boundary where the callback runs. Catch synchronous parsing or serialization failures there. Handle rejected promises when threferences/api-design.md
# API Design Patterns
> When to read: when designing a REST or RPC endpoint surface: pagination, error envelopes, idempotency, versioning, contract-first vs code-first.
## Pagination
| Use case | Type | Why |
|----------|------|-----|
| Admin dashboards, <10K rows | Offset (`?page=2&limit=20`) | Users expect page numbers |
| Infinite scroll, feeds, large datasets | Cursor (`?cursor=abc&limit=20`) | Stable under concurrent writes |
| Search results | Offset | Users need "page 3 of 12" |
**Cursor implementation:**
```sql
SELECT * FROM items
WHERE id > :cursor_id
ORDER BY id ASC
LIMIT :limit + 1; -- fetch N+1 to determine has_next
```
Response: `{ data, pagination: { next_cursor, has_next } }`. Base64 encodes cursor state but supplies no integrity. Validate decoded fields and bind the cursor to the authorized tenant, filters, and sort order. When cursor state must resist modification, authenticate it with a signature/MAC or use a server-stored opaque token. Always reapply authorization independently of cursor contents.
## Filtering
Bracket notation for comparison operators:
```
?price[gte]=10&price[lte]=100
?status[in]=active,pending
?customer.country=US # dot notation for nested fields
```
Comma-separated for multi-value equality:
```
?category=electronics,clothing
```
## Sorting
Prefix `-` for descending, comma-separated for multi-field:
```
?sort=-created_at,name # newest first, then alphabetical
```
## Sparse Fieldsets
```
?fields=id,name,email # return only these fields
```
## Deprecation Protocol
1. Add `Sunset` header with retirement date: `Sunset: Sat, 01 Jan 2028 00:00:00 GMT`
2. Minimum 6-month notice before removal
3. After sunset: return `410 Gone` with migration guidance
**Breaking vs non-breaking changes:**
| Non-breaking (no new version) | Breaking (requires new version) |
|-------------------------------|--------------------------------|
| Adding optional fields/params | Removing or renaming fields |
| Adding new endpoints | Changing field types |
| Widening accepted input enum values | Removing endpoints |
| Relaxing validation | Tightening validation |
| Extending response with new keys | Changing response structure |
Adding an emitted response enum member is compatible only when existing clients demonstrably tolerate unknown members; closed validators and exhaustive switches can reject it. Verify client behavior before classifying that change as nonbreaking.
## Pre-Ship Endpoint Checklist
Before shipping any new endpoint, verify:
- [ ] Resource naming: plural nouns, max 2 nesting levels
- [ ] HTTP method matches semantics (GET reads, POST creates, etc.)
- [ ] Status codes correct (201 + Location on create, 204 on delete, 404 vs 400 distinction)
- [ ] Request validation with schema (rejects invalid input with 400 + detail)
- [ ] Response schema defined (controls serialized fields, no raw objects)
- [ ] Pagination on list endpoints (cursor or offset with has_next)
- [ ] Auth/authz enforcereferences/async-and-production.md
# Async operations and production ## Async Patterns | Pattern | Use When | |---------|----------| | `async/await` | Sequential operations | | `Promise.all` | Parallel independent ops | | `Promise.allSettled` | Parallel, some may fail | | `Promise.race` | Timeout waiting or first-wins; losing operations continue unless canceled | Never use readFileSync or other sync methods in production; use `fs.promises` or stream equivalents. Offload CPU work to worker threads (Piscina). Stream large payloads. An event-loop timer cannot interrupt synchronous CPU work. Wrapping a backtracking regex or long computation in `Promise.race` does not impose an execution deadline: the timeout callback waits for the blocked event loop. Bound input size and prefer predictable matching algorithms. When a hard CPU deadline is required, use a terminable worker or process, or an execution timeout supported by the runtime. Verify the deadline with an adversarial input under an outer bound. A runtime execution timeout alone does not make untrusted code safe. For RxJS `forkJoin`, a source that completes without emitting can complete the join without a result and unsubscribe the other sources. Use `defaultIfEmpty` with an explicit sentinel only when empty completion is a valid no-result outcome. Preserve errors and reject missing required replies. Verify that an optional empty handler does not cancel a sibling's required effect. ## Production Resilience - **Fail-fast env validation**: parse and validate all environment variables at startup with a Zod schema (`const env = envSchema.parse(process.env)`). If invalid, crash before serving traffic. Never discover a missing env var on the first request that needs it. - **Health endpoints**: expose both `/health` (shallow, always 200 if process is alive) and `/ready` (deep, verifies database, cache, and critical dependencies are reachable). Load balancers probe `/ready` for traffic routing; monitoring probes `/health` for process liveness. Don't conflate them. - **Caching**: Redis cache-aside for DB/API responses; in-memory LRU with TTL for hot paths. Always invalidate on writes. - **Cache connection attempts without caching permanent failure.** If an application-owned initialization promise rejects and no client-owned reconnect loop will recover, dispose the failed attempt and clear its cached promise so the next caller can retry. Compare the captured promise and resource with the current attempt before clearing shared state; a late rejection from attempt A must not erase replacement B. Verify concurrent callers share one attempt and a later call succeeds after rejection. Preserve clients whose SDK intentionally owns automatic reconnection. - **Load shedding**: `@fastify/under-pressure` (or equivalent): monitor event loop delay, heap, RSS; return 503 when thresholds exceeded. - **Response schemas**: In Fastify, always define response schemas; this enables `fast-json-stringify` for 2-3x faster serialization. - **Circuit breaker
AionUi
Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!
activepieces
AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents
cherry-studio
AI productivity studio with smart chat, autonomous agents, and 300+ assistants.
CopilotKit
The Frontend for Agents & Generative UI. React + Angular
Machine-readable data
The same record, as JSON, for agents and crawlers.
{
"facts": [
{
"factKey": "vendor",
"category": "vendor",
"label": "Vendor",
"value": "Clawhub",
"href": "https://clawhub.ai/iliaal/skills/compound-eng-nodejs-backend",
"sourceUrl": "https://clawhub.ai/iliaal/skills/compound-eng-nodejs-backend",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-09T13:53:10.850Z",
"isPublic": true
},
{
"factKey": "protocols",
"category": "compatibility",
"label": "Protocol compatibility",
"value": "OpenClaw",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-iliaal-compound-eng-nodejs-backend/contract",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-iliaal-compound-eng-nodejs-backend/contract",
"sourceType": "contract",
"confidence": "medium",
"observedAt": "2026-10-09T13:53:10.850Z",
"isPublic": true
},
{
"factKey": "traction",
"category": "adoption",
"label": "Adoption signal",
"value": "2.5K downloads",
"href": "https://clawhub.ai/iliaal/compound-eng-nodejs-backend",
"sourceUrl": "https://clawhub.ai/iliaal/compound-eng-nodejs-backend",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-09T13:53:10.850Z",
"isPublic": true
},
{
"factKey": "latest_release",
"category": "release",
"label": "Latest release",
"value": "5.0.1",
"href": "https://clawhub.ai/iliaal/compound-eng-nodejs-backend",
"sourceUrl": "https://clawhub.ai/iliaal/compound-eng-nodejs-backend",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-10-03T17:05:48.776Z",
"isPublic": true
},
{
"factKey": "handshake_status",
"category": "security",
"label": "Handshake status",
"value": "UNKNOWN",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-iliaal-compound-eng-nodejs-backend/trust",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-iliaal-compound-eng-nodejs-backend/trust",
"sourceType": "trust",
"confidence": "medium",
"observedAt": null,
"isPublic": true
}
],
"events": [
{
"eventType": "release",
"title": "Release 5.0.1",
"description": "v5.0.1",
"href": "https://clawhub.ai/iliaal/compound-eng-nodejs-backend",
"sourceUrl": "https://clawhub.ai/iliaal/compound-eng-nodejs-backend",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-10-03T17:05:48.776Z",
"isPublic": true
}
]
}Record generated Oct 9, 2026.
