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:
PascalCasesingular 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:
camelCasepara body,kebab-casepara 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.mddo projeto.