본문으로 건너뛰기
cccskills
무료GitHub에 공개

node-conventions

Node.js backend conventions: project layout, configuration, logging, routing, and error handling patterns. Apply when implementing or modifying Node.js backend code in projects matching the nodejs stack profile. Use this skill to: - Pick conventional file/folder structure for a new module. - Wire configuration through env vars correctly. - Use the project's existing logger style. - Implement error handling that matches the framework (Express/Fastify/Koa). - Follow async/await patterns consistently. Do NOT use this skill for: - Frontend code (React/Vue/RN have their own conventions). - NestJS-specific patterns (decorators, DI, modules) — nest-plugin owns those. - Database schema design (call out as a sub-task; npm-patterns covers package management, not DB).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md6.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Node.js Backend Conventions

This skill consolidates idioms that hold across most Node.js backend projects (Express, Fastify, Koa, plain Node). Follow them when adding code; if a project's CLAUDE.md contradicts a convention here, the project wins.

Project layout

Typical layout:

project-root/
├── package.json
├── tsconfig.json              # if TypeScript
├── src/
│   ├── index.js               # entry point — start server, wire app
│   ├── app.js                 # framework instance (express(), fastify())
│   ├── config.js              # env-var reader (single source)
│   ├── routes/                # route definitions, one file per resource
│   ├── controllers/           # request handlers (or merged into routes)
│   ├── services/              # business logic, framework-agnostic
│   ├── middleware/
│   ├── lib/                   # shared utilities
│   └── db/                    # data access layer
├── test/  OR  __tests__/
└── dist/                      # build output (TS), gitignored

Mirror what exists. If the project uses a flat layout, do not introduce nested layout for one new file.

Configuration

Single config module reading from process.env:

// src/config.js
const requiredEnv = ['DATABASE_URL', 'PORT'];
for (const key of requiredEnv) {
  if (!process.env[key]) throw new Error(`Missing env var: ${key}`);
}

module.exports = {
  port: Number(process.env.PORT),
  databaseUrl: process.env.DATABASE_URL,
  logLevel: process.env.LOG_LEVEL || 'info',
};

Never read process.env from business logic. Always go through config.

Logging

Use the project's existing logger. Detection priority:

  1. pino in deps → const logger = require('pino')()
  2. winston in deps → use the configured instance
  3. bunyan in deps → use the configured instance
  4. Otherwise → console.log/console.error is acceptable

Never introduce a new logger as part of feature work without justification in DECISIONS.

Log levels: debug (verbose dev), info (normal flow), warn (recoverable), error (something failed).

Routing patterns

Express

// src/routes/health.js
const router = require('express').Router();
const { getHealth } = require('../controllers/health');

router.get('/healthz', getHealth);

module.exports = router;

Mount in src/app.js:

app.use(require('./routes/health'));

Fastify

// src/routes/health.js
async function healthRoutes(fastify) {
  fastify.get('/healthz', async () => ({ status: 'ok' }));
}
module.exports = healthRoutes;

Register in src/app.js:

fastify.register(require('./routes/health'));

Error handling

Async route handlers — never let rejections escape

Express requires explicit next(err). Two patterns:

Pattern A — wrapper:

const asyncHandler = (fn) => (req, res, next) =>
  Promise.resolve(fn(req, res, next)).catch(next);

router.get('/x', asyncHandler(async (req, res) => {
  const data = await mayThrow();
  res.json(data);
}));

Pattern B — express@5+ native (auto-forwards rejections to next).

Use whatever the project already uses. Don't introduce a wrapper if the project uses express@5.

Centralized error middleware

// src/middleware/error.js
module.exports = (err, req, res, next) => {
  logger.error({ err }, 'request failed');
  const status = err.status || 500;
  res.status(status).json({ error: err.message });
};

Always last in the middleware chain.

Fastify: setErrorHandler

fastify.setErrorHandler((err, req, reply) => {
  logger.error({ err }, 'request failed');
  reply.status(err.statusCode || 500).send({ error: err.message });
});

Validation

At the request boundary, not in business logic. Use what's installed:

  • zod → schema.parse(req.body) inside try/catch.
  • joi → schema.validate(req.body, { abortEarly: false }).
  • ajv → compiled validator instance.
  • Express → express-validator middleware on the route.

If nothing is installed and BA spec requires validation: add zod (smallest, TS-friendly) and document in DECISIONS.

Async patterns

  • Prefer async/await over .then().catch().
  • Don't mix CJS require and ESM import in one file. Detect from package.json "type" field.
  • Don't use top-level await unless "type": "module" is set.
  • For parallel work, Promise.all([a, b, c]). For settled-on-all, Promise.allSettled.

Graceful shutdown

For HTTP servers, handle SIGTERM and SIGINT:

const server = app.listen(port);

const shutdown = async () => {
  server.close(() => process.exit(0));
  setTimeout(() => process.exit(1), 10_000).unref();
};
process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);

Drain in-flight requests, close DB pool, then exit.

Anti-patterns

  • ❌ app.use((req, res) => res.status(500).send(err.stack)) — never expose stack traces in production responses.
  • ❌ Reading process.env.X deep inside business logic.
  • ❌ Mixing require and import in one file.
  • ❌ Swallowing errors silently (catch(() => {})).
  • ❌ Hardcoded ports / URLs / credentials.
  • ❌ Module-level mutable state (use dependency injection or factory functions).
  • ❌ eval, Function() constructor on user input.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Angular 18-21 project structure, standalone components vs NgModule, control flow (@if/@for/@switch + *ngIf/*ngFor legacy), decorators, dependency injection (inject() function), lifecycle hooks, pipes, Angular Universal SSR pointer. Use this skill to: - Detect project style (standalone vs NgModule) and apply matching patterns. - Pick correct decorators and DI approach. - Use modern control flow (@if/@for/@switch) in Angular 17+ projects. - Apply `inject()` function over constructor injection where appropriate. - Wire bootstrap correctly (bootstrapApplication for standalone, AppModule for legacy). Do NOT use this skill for: - State management (see angular-state-and-rx). - Routing (see angular-routing). - Forms (see angular-forms). - Testing (see angular-testing).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AratKruglik/claude-sdlc432026년 10월 17일 업데이트

Angular forms: Reactive Forms (preferred — typed FormGroup/FormControl since Angular 14, FormBuilder, custom + async validators, FormArray, multi-step) and Template-driven (`[(ngModel)]` + FormsModule). Validation strategies, server error mapping, accessibility. Use this skill to: - Build Reactive Forms with typed FormGroup/FormControl. - Use FormBuilder для concise syntax. - Implement custom synchronous and async validators. - Wire FormArray for dynamic field lists. - Map server errors back to form fields. - Pick Reactive vs Template-driven (prefer Reactive). Do NOT use this skill for: - General conventions (see angular-conventions). - State management beyond forms (see angular-state-and-rx). - Routing (see angular-routing). - Testing forms (see angular-testing).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AratKruglik/claude-sdlc432026년 10월 17일 업데이트

Angular Router (built-in `@angular/router`) — route configuration for standalone and NgModule projects, functional guards (Angular 14.1+), lazy loading, route resolvers, typed params via signals/observables, programmatic navigation, route data and meta. Use this skill to: - Configure routes (standalone-style or NgModule-style). - Use functional guards (canActivate as function, preferred over class-based in 17+). - Lazy-load components or feature modules. - Implement auth guards via route meta + functional guards. - Read params/queries via `inject(ActivatedRoute)` + signals or RxJS. Do NOT use this skill for: - General conventions (see angular-conventions). - State management (see angular-state-and-rx). - Forms (see angular-forms). - Testing routes (see angular-testing).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AratKruglik/claude-sdlc432026년 10월 17일 업데이트

State management for Angular 18-21: signals (signal/computed/effect), services-as-state, NgRx Store + Effects + Selectors, NgRx Component Store, NgRx Signals (newer signal-based store). RxJS essentials — operators, async pipe, takeUntilDestroyed, signal/observable interop. Use this skill to: - Pick the right state tool (signals / services / NgRx variant / vue-query equivalent). - Use signals correctly (signal/computed/effect — when each). - Build a Pinia-style service-as-state singleton. - Set up NgRx Store + Effects + Selectors. - Use RxJS without leaking subscriptions (async pipe, takeUntilDestroyed, Subject patterns). - Bridge signals ↔ observables via toSignal / toObservable. Do NOT use this skill for: - General Angular conventions (see angular-conventions). - Routing state (see angular-routing). - Form state (see angular-forms). - Testing state (see angular-testing).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AratKruglik/claude-sdlc432026년 10월 17일 업데이트

Testing Angular 18-21: TestBed, component harnesses (@angular/cdk/testing), Karma+Jasmine (default historical) vs Jest (jest-preset-angular, modern), Angular Testing Library (RTL-style). HttpClient mocking via HttpTestingController. NgRx Effects testing. Cypress / Playwright e2e. Use this skill to: - Detect runner (Karma+Jasmine vs Jest) and configure correctly. - Write component tests with TestBed. - Use component harnesses for Material / custom UI components. - Mock HttpClient via provideHttpClientTesting + HttpTestingController. - Test signal-based inputs with componentRef.setInput(). - Test NgRx Effects with provideMockActions. Do NOT use this skill for: - General Angular conventions (see angular-conventions). - Routing patterns broadly (see angular-routing — covers testing routes briefly). - Form patterns broadly (see angular-forms).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AratKruglik/claude-sdlc432026년 10월 17일 업데이트

Shared conventions for every SDLC development-phase architect agent: hard rules, code quality bar, workflow steps (superpowers invocation, spec reading, codebase exploration, verification), and the report/compact-summary contract. Architects load this skill first, then apply their stack-specific instructions on top.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AratKruglik/claude-sdlc432026년 10월 17일 업데이트

AratKruglik의 스킬 모두 보기

이 스킬의 문제 신고