🟢 Node.js Stack

Backend Stacks

IA Guidelines / Backend Stacks / Node.js Stack
⬇️ Download .md

Stack Node.js — InfoWhere

Template de stack para projetos Node.js
Última atualização: 25/01/2026
Nível de experiência: ⭐⭐ Básico


1. Visão Geral

Stack para ferramentas, scripts, APIs leves e aplicações real-time.


2. Versões

Componente Versão Notas
Node.js 22.x (LTS) Sempre LTS
TypeScript 5.x Sempre usar TypeScript
Express 4.x Framework principal
pnpm Última Gerenciador de pacotes

3. Dependências Core

3.1 API Framework

{
  "dependencies": {
    "express": "^4.21.0",
    "cors": "^2.8.5",
    "helmet": "^8.0.0",
    "compression": "^1.7.4"
  },
  "devDependencies": {
    "typescript": "^5.6.0",
    "@types/node": "^22.0.0",
    "@types/express": "^4.17.21",
    "tsx": "^4.19.0",
    "tsup": "^8.3.0"
  }
}

3.2 Validação

{
  "dependencies": {
    "zod": "^3.23.0"
  }
}

3.3 Database

{
  "dependencies": {
    "prisma": "^5.22.0",
    "@prisma/client": "^5.22.0"
  }
}

3.4 Autenticação

{
  "dependencies": {
    "jsonwebtoken": "^9.0.0",
    "jwks-rsa": "^3.1.0"
  },
  "devDependencies": {
    "@types/jsonwebtoken": "^9.0.0"
  }
}

3.5 Utilitários

{
  "dependencies": {
    "dotenv": "^16.4.0",
    "pino": "^9.5.0",
    "pino-pretty": "^11.3.0",
    "uuid": "^11.0.0"
  }
}

4. Testes

{
  "devDependencies": {
    "vitest": "^2.1.0",
    "@vitest/coverage-v8": "^2.1.0",
    "supertest": "^7.0.0",
    "@types/supertest": "^6.0.0"
  }
}

Cobertura mínima: 80%


5. Autenticação / Autorização

Componente Escolha
Identity Provider Keycloak
Protocolo OAuth2 + JWT
Lib jsonwebtoken + jwks-rsa

Configuração típica

import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
import { Request, Response, NextFunction } from 'express';

const client = jwksClient({
  jwksUri: `${process.env.KEYCLOAK_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/certs`
});

function getKey(header: jwt.JwtHeader, callback: jwt.SigningKeyCallback) {
  client.getSigningKey(header.kid, (err, key) => {
    const signingKey = key?.getPublicKey();
    callback(err, signingKey);
  });
}

export const authMiddleware = (req: Request, res: Response, next: NextFunction) => {
  const token = req.headers.authorization?.split(' ')[1];
  
  if (!token) {
    return res.status(401).json({ error: 'No token provided' });
  }

  jwt.verify(token, getKey, { algorithms: ['RS256'] }, (err, decoded) => {
    if (err) {
      return res.status(401).json({ error: 'Invalid token' });
    }
    req.user = decoded;
    next();
  });
};

6. Database

Componente Escolha Notas
Database PostgreSQL Neon.tech para cloud
ORM Prisma Type-safe, migrations incluídas

Convenções

  • Tabelas: PascalCase singular no Prisma (User, Invoice)
  • Colunas: camelCase (createdAt, userId)
  • DB real: Prisma converte para snake_case

Prisma Schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        String   @id @default(uuid())
  email     String   @unique
  name      String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

7. Estrutura do Projeto

Nível Script (ferramentas, CLIs, scripts)

{projeto}/
├── src/
│   └── index.ts         # Tudo junto
├── package.json
├── tsconfig.json
└── README.md

Ou se precisar separar minimamente:

{projeto}/
├── src/
│   ├── index.ts         # Entry point
│   ├── services.ts      # Lógica de negócio
│   └── types.ts         # TypeScript types
├── package.json
├── tsconfig.json
└── README.md

Quando usar: Scripts, CLIs, ferramentas pequenas.

Nível Médio (APIs que podem crescer)

{projeto}/
├── src/
│   ├── index.ts              # Entry point
│   ├── app.ts                # Express app
│   ├── config/
│   │   └── env.ts
│   ├── routes/               # Endpoints
│   │   ├── index.ts
│   │   └── users.route.ts
│   ├── services/             # Lógica de negócio + acesso a dados
│   │   └── user.service.ts
│   ├── schemas/              # Zod DTOs
│   │   └── user.schema.ts
│   ├── middlewares/
│   │   ├── auth.middleware.ts
│   │   └── error.middleware.ts
│   └── types/
│       └── index.ts
├── prisma/
│   └── schema.prisma
├── tests/
│   └── user.test.ts
├── package.json
├── tsconfig.json
├── Dockerfile
└── README.md

Quando usar: APIs que podem crescer, projetos com múltiplos endpoints.

Nota: Sem Repository separado — Service acessa Prisma direto.


8. Padrões e Convenções

8.1 API REST

  • Versionamento: /api/v1/
  • Formato: JSON
  • Naming: camelCase para body, kebab-case para URLs
  • Docs: Swagger com @asteasolutions/zod-to-openapi

8.2 Schemas (Zod)

import { z } from 'zod';

// Request
export const createUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(2),
});

// Response
export const userResponseSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string(),
  createdAt: z.date(),
});

// Types
export type CreateUserRequest = z.infer<typeof createUserSchema>;
export type UserResponse = z.infer<typeof userResponseSchema>;

8.3 Error Handling

// Custom error
export class AppError extends Error {
  constructor(
    public message: string,
    public statusCode: number = 500
  ) {
    super(message);
  }
}

// Middleware
export const errorMiddleware = (
  err: Error,
  req: Request,
  res: Response,
  next: NextFunction
) => {
  if (err instanceof AppError) {
    return res.status(err.statusCode).json({ error: err.message });
  }
  
  logger.error(err);
  return res.status(500).json({ error: 'Internal server error' });
};

8.4 Logs

  • Framework: Pino
  • Formato: JSON em produção
import pino from 'pino';

export const logger = pino({
  level: process.env.LOG_LEVEL || 'info',
  transport: process.env.NODE_ENV !== 'production' 
    ? { target: 'pino-pretty' } 
    : undefined,
});

9. Infraestrutura

Componente Escolha
Containerização Docker
Orquestração Kubernetes
CI/CD GitHub Actions
Registry Docker Hub
Cloud DB Neon.tech

Dockerfile típico

FROM node:22-alpine AS builder

WORKDIR /app
RUN npm install -g pnpm

COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

COPY . .
RUN pnpm build
RUN pnpm prune --prod

FROM node:22-alpine

WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules

EXPOSE 3000

CMD ["node", "dist/index.js"]

10. O que NÃO usar

Tecnologia Motivo
JavaScript puro Sempre TypeScript
npm Preferir pnpm (mais rápido, menos espaço)
Sequelize Preferir Prisma (type-safe)
CommonJS Preferir ESM
Node < 22 Sempre LTS atual
NestJS Overkill para APIs simples

11. Checklist de Novo Projeto

  • Criar projeto com pnpm init
  • Configurar TypeScript (tsconfig.json)
  • Instalar dependências base
  • Criar estrutura de pastas
  • Configurar Prisma
  • Configurar autenticação JWT/Keycloak
  • Configurar error handling
  • Criar Dockerfile
  • Criar docker-compose.yml para dev
  • Configurar Vitest
  • Criar README.md com instruções

12. Links de Referência


Nota: Este template é a base. Cada projeto pode ter ajustes específicos documentados no technical_context.md do projeto.