Um framework web moderno para Node.js, inspirado no Express mas com TypeScript e ES Modules nativos.
LikeExpress combina a familiaridade da API do Express com recursos modernos do Node.js e TypeScript. Ideal para desenvolvedores que querem a simplicidade do Express com a segurança de tipos do TypeScript e as melhores práticas de segurança incluídas por padrão.
- Familiar: Se você já usa Express, a transição é instantânea
- Moderno: ES Modules nativos, TypeScript-first, Node.js 18+
- Seguro: CORS, Helmet, Rate Limiting configurados e prontos
- Produtivo: Validação com Zod, schemas reutilizáveis, autocomplete perfeito
- Zero Config: Funciona out-of-the-box, customize quando necessário
LikeExpress leva o "TypeScript-First" a sério. Ao definir schemas de validação com Zod, sua aplicação não apenas valida os dados de entrada, mas também infere automaticamente os tipos corretos para req.body, req.params e req.query nos seus handlers. Isso significa:
- Segurança Total: Seus dados de entrada sempre corresponderão aos seus tipos.
- DX Imbatível: Autocomplete instantâneo e feedback de erros em tempo de desenvolvimento.
- Menos Boileplate: Diga adeus às tipagens manuais de
reqeres.
Exemplo Mágico de Inferência de Tipos:
import { createApp, z } from 'like-express-node-typescript';
const app = createApp();
const getUserSchema = {
params: z.object({
id: z.string().uuid(),
}),
query: z.object({
include: z.enum(['profile', 'posts']).optional(),
}),
} as const; // Crucial para a inferência de tipos!
app.get('/users/:id', (req, res) => {
// ✨ req.params é automaticamente inferido como: { id: string }
const userId = req.params.id; // Autocomplete completo!
// ✨ req.query é automaticamente inferido como: { include?: "profile" | "posts" }
const includeData = req.query.include; // Tipagem precisa!
res.json({ userId, includeData });
}, { schema: getUserSchema });
app.listen().then(() => console.log('Servidor rodando com tipagem mágica! ✨'));Com LikeExpress, seus handlers são sempre tipados e seguros, sem esforço extra!
- ⚡ ES Modules Nativos: Arquitetura moderna do Node.js
- 🔋 Baterias Inclusas: Validação, segurança, logging built-in
- 🎯 API Familiar: Se você conhece Express, já sabe usar
- 🛡️ Seguro por Padrão: CORS, Helmet, Rate Limiting inclusos
- 🔍 Developer Experience: Erros claros, debugging fácil
- Node.js 18+ (para suporte a ES Modules, fetch nativo, e node:test)
- npm ou yarn
- TypeScript 5.9+
# Clone o repositório
git clone <repository-url>
cd like-express-node-typescript
# Instale as dependências
npm install
# Execute o exemplo
npm run dev
# Compile o projeto
npm run buildnpm install like-express-node-typescriptimport { createApp, z, validate } from 'like-express-node-typescript';
const app = createApp();
// Rota simples
app.get('/', (req, res) => {
res.json({ message: 'Hello World!' });
});
// Rota com validação
app.post('/users', {
middleware: [validate({
body: z.object({
name: z.string(),
email: z.string().email()
})
})]
}, (req, res) => {
res.json({ user: req.body });
});
app.listen(3000);→ Ver API.md - Documentação Completa de Todas as Features
A documentação completa inclui:
- Todos os métodos de Application, Router, Request, Response
- Middleware utilities e composition helpers
- Sistema de Context (AsyncLocalStorage)
- Validação completa com Zod
- Segurança (CORS, Helmet, Rate Limiting) com todos os presets
- Sistema de Plugins
- Error Handling completo
- Logger e utilities
- Types e constantes
| Categoria | Features Principais | Documentação |
|---|---|---|
| Application | listen(), close(), use(), plugin(), HTTP methods shortcuts |
API.md#application |
| Router | Pattern matching, wildcards, params, match(), find-my-way |
API.md#router |
| Request | parseBody(), get(), ip(), hostname(), fullUrl(), query/params |
API.md#request |
| Response | json(), text(), html(), send(), redirect(), cookie(), status/headers |
API.md#response |
| Middleware | compose(), conditional(), onlyMethods(), onlyPaths(), MiddlewareChain |
API.md#middleware |
| Context | getRequest(), getResponse(), getRequestId(), set(), get(), AsyncLocalStorage |
API.md#context |
| Validation | validate(), Zod schemas, body(), params(), query(), commonSchemas |
API.md#validation |
| CORS | Origin validation, credentials, presets (development, production, publicApi) | API.md#cors |
| Helmet | Security headers, CSP, HSTS, presets (default, strict, development, minimal) | API.md#helmet |
| Rate Limiting | IP-based, user-based, route-based, presets (strict, moderate, relaxed, auth, create) | API.md#rate-limiting |
| Plugins | createPlugin(), logging, security, healthCheck, metrics, bodyParser |
API.md#plugins |
| Error Handling | HttpError, createError.*, asyncHandler(), error handlers |
API.md#error-handling |
| Logger | debug(), info(), warn(), error(), requestLogger(), performanceLogger() |
API.md#logger |
| JSON | stringify() with HTML escaping, XSS protection |
API.md#json-utilities |
| Types | HttpStatus, HttpMethod, all interfaces and types | API.md#types--constants |
- 140+ APIs públicas documentadas
- 15 categorias de funcionalidades
- 8 schemas comuns pré-construídos
- 12 presets de segurança (CORS, Helmet, Rate Limiting)
- 5 plugins built-in prontos para uso
- 13 helpers de error handling
- 18 constantes de HTTP status
- 100% type-safe com TypeScript
import { createApp } from 'like-express-node-typescript';
const app = createApp({
port: 3000,
host: 'localhost',
debug: true, // Logs detalhados
trustProxy: false // Headers X-Forwarded-*
});// Métodos HTTP
app.get('/path', handler);
app.post('/path', handler);
app.put('/path', handler);
app.patch('/path', handler);
app.delete('/path', handler);
app.head('/path', handler);
app.options('/path', handler);
// Parâmetros de rota
app.get('/users/:id', (req, res) => {
const { id } = req.params;
res.json({ userId: id });
});
// Query parameters
app.get('/search', (req, res) => {
const { q, page } = req.query;
res.json({ query: q, page });
});import { z, validate } from 'like-express-node-typescript';
const userSchema = {
body: z.object({
name: z.string().min(2),
email: z.string().email(),
age: z.number().int().positive().optional()
}),
params: z.object({
id: z.string().uuid()
}),
query: z.object({
page: z.coerce.number().default(1),
limit: z.coerce.number().default(10)
})
};
app.post('/users/:id', {
middleware: [validate(userSchema)]
}, (req, res) => {
// req.body, req.params, req.query já validados e tipados!
res.json({ user: req.body });
});import { cors, helmet, rateLimit } from 'like-express-node-typescript';
// Middleware global
app.use(cors());
app.use(helmet());
app.use(rateLimit({ max: 100, windowMs: 60000 }));
// Middleware customizado
app.use((req, res, next) => {
console.log(`${req.method} ${req.path}`);
next();
});
// Middleware em rotas específicas
app.post('/api', {
middleware: [
rateLimit({ max: 10, windowMs: 60000 })
]
}, handler);import { cors, corsPresets } from 'like-express-node-typescript';
// Desenvolvimento - permite tudo
app.use(corsPresets.development());
// Produção - apenas origins específicas
app.use(corsPresets.production(['https://example.com']));
// Customizado
app.use(cors({
origin: '*',
methods: ['GET', 'POST'],
credentials: true,
maxAge: 86400
}));import { helmet, helmetPresets } from 'like-express-node-typescript';
// Padrão recomendado
app.use(helmetPresets.default());
// Estrito para produção
app.use(helmetPresets.strict());
// Customizado
app.use(helmet({
contentSecurityPolicy: {
directives: {
'default-src': ["'self'"],
'script-src': ["'self'", 'trusted.com']
}
}
}));import { rateLimit, rateLimitPresets } from 'like-express-node-typescript';
// Limite global
app.use(rateLimitPresets.moderate());
// Limite para autenticação
app.post('/login', {
middleware: [rateLimitPresets.auth()]
}, handler);
// Customizado
app.use(rateLimit({
max: 100, // 100 requests
windowMs: 15 * 60 * 1000, // por 15 minutos
message: 'Too many requests'
}));import { HttpError, createError } from 'like-express-node-typescript';
// Lançar erros HTTP
app.get('/not-found', () => {
throw createError.notFound('Resource not found');
});
// Error handler customizado
const app = createApp({
errorHandler: (error, req, res) => {
console.error(error);
res.status(500).json({ error: error.message });
}
});import { logger, requestLogger, LogLevel } from 'like-express-node-typescript';
// Logger global
logger.info('Server started');
logger.warn('Warning message');
logger.error('Error message');
logger.debug('Debug info');
// Request logging middleware
app.use(requestLogger({
includeHeaders: true,
includeBody: false
}));
// Configurar nível de log
logger.setLevel(LogLevel.DEBUG);import { plugins } from 'like-express-node-typescript';
// Plugin de logging completo
await app.plugin(plugins.logging({
includeHeaders: false,
performanceThreshold: 1000
}));
// Plugin de segurança (CORS + Helmet + Rate Limit)
await app.plugin(plugins.security());
// Health check endpoint
await app.plugin(plugins.healthCheck({
path: '/health'
}));
// Métricas básicas
await app.plugin(plugins.metrics({
path: '/metrics'
}));🔐 Segurança: Todas as respostas JSON têm escape automático de HTML (
<,>,&) para prevenir ataques XSS quando o JSON é embutido em páginas HTML.
app.get('/api', (req, res) => {
// JSON (com escape automático de HTML para prevenir XSS)
res.json({ data: 'value' });
// Text
res.text('Hello World');
// HTML
res.html('<h1>Hello</h1>');
// Status code
res.status(201).json({ created: true });
// Redirect
res.redirect('/new-path');
// Headers
res.header('X-Custom', 'value');
res.setHeaders({
'X-Custom-1': 'value1',
'X-Custom-2': 'value2'
});
// Cookies
res.cookie('session', 'abc123', {
httpOnly: true,
secure: true,
maxAge: 86400
});
// Send auto-detect
res.send({ auto: 'detected' }); // JSON
res.send('<html>...</html>'); // HTML
res.send(Buffer.from('data')); // Binary
});app.post('/api', async (req, res) => {
// Body parsing automático
const body = req.body;
// Headers
const auth = req.get('authorization');
const hasAuth = req.has('authorization');
// Content type
if (req.isJson()) {
// Handle JSON
}
if (req.accepts('application/json')) {
// Client accepts JSON
}
// Client info
const ip = req.ip();
const host = req.hostname();
const protocol = req.protocol();
const fullUrl = req.fullUrl();
// Seguro (HTTPS)?
if (req.secure()) {
// HTTPS connection
}
});import { context } from 'like-express-node-typescript';
// Acesse request/response de qualquer lugar
function someDeepFunction() {
const req = context.getRequest();
const res = context.getResponse();
const requestId = context.getRequestId();
const elapsed = context.getElapsedTime();
// Custom metadata
context.set('userId', '123');
const userId = context.get<string>('userId');
}import { commonSchemas } from 'like-express-node-typescript';
// ID numérico
app.get('/users/:id', {
middleware: [validate({ params: commonSchemas.numericId })]
}, handler);
// UUID
app.get('/posts/:id', {
middleware: [validate({ params: commonSchemas.uuidId })]
}, handler);
// Paginação
app.get('/items', {
middleware: [validate({ query: commonSchemas.pagination })]
}, (req, res) => {
const { page, limit } = req.query; // tipados e validados
});
// Ordenação
app.get('/items', {
middleware: [validate({ query: commonSchemas.sorting })]
}, handler);Para uso avançado de serialização JSON:
import { stringify, type StringifyOptions } from 'like-express-node-typescript';
// Com formatação
const json = stringify({ foo: 'bar' }, {
space: 2,
escapeHtml: true
});
// Com replacer customizado
const json = stringify(data, {
replacer: (key, value) => {
if (key === 'password') return undefined; // Remove senhas
return value;
},
escapeHtml: true
});
// Segurança: caracteres HTML são escapados
const unsafe = { html: '<script>alert("XSS")</script>' };
stringify(unsafe, { escapeHtml: true });
// Resultado: {"html":"\u003cscript\u003ealert(\"XSS\")\u003c/script\u003e"}import { createErrorHandler, createHtmlErrorHandler } from 'like-express-node-typescript';
const app = createApp({
errorHandler: createErrorHandler({
debug: process.env.NODE_ENV === 'development',
logger: (error, req) => {
// Custom logging
myLogger.error(error, {
method: req.method,
path: req.path
});
}
})
});import { Router } from 'like-express-node-typescript';
const router = new Router();
router.get('/users', handler);
router.post('/users', handler);
// Use com Application
const app = createApp();
app.use((req, res, next) => {
// Middleware que usa router
const match = router.match(req.method, req.path);
if (match) {
match.route.handler(req, res);
} else {
next();
}
});# Desenvolvimento
npm run dev # Executa examples/basic.ts com hot reload
npm run dev:watch # Watch mode para desenvolvimento
# Build
npm run build # Compila TypeScript para dist/
npm run build:clean # Build limpo (remove dist/ primeiro)
# Qualidade de Código
npm run test # Executa testes com node:test
npm run lint # Verifica código com Biome
npm run format # Formata código com Biome
npm run typecheck # Verifica tipos TypeScript
# Verificação Completa
npm run check # Executa lint + typecheck + testExecute o exemplo incluído no projeto:
npm run devO arquivo examples/basic.ts demonstra:
- Criação de aplicação com configuração
- Rotas HTTP (GET, POST, PUT, DELETE)
- Validação com Zod
- Middleware de segurança (CORS, Helmet, Rate Limiting)
- Plugins (logging, security, health check, metrics)
- Error handling
- Async context
Crie um arquivo my-app.ts:
import { createApp, type RequestContext, type ResponseContext } from './src/index.js';
const app = createApp({
port: 3000,
debug: true
});
app.get('/', (req: RequestContext, res: ResponseContext) => {
res.json({ message: 'Minha aplicação LikeExpress!' });
});
await app.listen();Execute com:
npx tsx my-app.tssrc/
├── core/ # Core do framework
│ ├── application.ts # Classe principal
│ ├── router.ts # Sistema de rotas
│ ├── request.ts # Request wrapper
│ ├── response.ts # Response wrapper
│ ├── middleware.ts # Sistema de middleware
│ └── context.ts # Async context
├── validation/ # Validação com Zod
├── security/ # Middleware de segurança
│ ├── cors.ts
│ ├── helmet.ts
│ └── rate-limit.ts
├── utils/ # Utilitários
│ ├── types.ts
│ ├── logger.ts
│ └── error-handler.ts
└── plugins/ # Sistema de plugins
| Componente | Tecnologia | Versão |
|---|---|---|
| Runtime | Node.js | 18+ |
| Linguagem | TypeScript | 5.9+ |
| Module System | ES Modules | Nativo |
| Router | find-my-way | 9.3+ |
| Validação | Zod | 3.24+ |
| Test Runner | node:test | Nativo |
| Linter/Formatter | Biome | Latest |
| Build Tool | TSC | 5.9+ |
- TypeScript-First: Toda a API é projetada para máxima inferência de tipos
- Mínimas Dependencies: Apenas Zod (validação) e find-my-way (routing de alta performance)
- Express-Compatible: API familiar para fácil migração
- Modern Node.js: Aproveita recursos nativos (fetch, test runner, AsyncLocalStorage)
- Seguro por Padrão: Segurança não é opcional, é built-in
- Alta Performance: Router Radix Tree (find-my-way) com O(log n) lookup
- ✅ Sistema de roteamento com pattern matching
- ✅ Middleware chain com suporte async
- ✅ Request/Response wrappers type-safe
- ✅ Validação com Zod
- ✅ CORS middleware com presets
- ✅ Helmet (security headers) com presets
- ✅ Rate limiting in-memory
- ✅ Sistema de plugins
- ✅ Async context (AsyncLocalStorage)
- ✅ Logger com níveis
- ✅ Error handling customizável
- ✅ Common schemas (pagination, UUID, etc.)
- 🔲 Upload de arquivos (multipart/form-data)
- 🔲 WebSocket support
- 🔲 Template engines
- 🔲 Geração de OpenAPI/Swagger
- 🔲 Rate limit com stores externos (Redis)
- 🔲 Clustering support
- 🔲 Compression middleware
- 🔲 Static file serving
- 🔲 Suite de testes completa
Contribuições são bem-vindas!
Se você é desenvolvedor e quer contribuir:
- Leia o CLAUDE.md - Guia completo da arquitetura e convenções do código
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/amazing) - Faça suas alterações seguindo as convenções do projeto
- Execute os checks:
npm run check - Commit suas mudanças usando Conventional Commits:
feat:- Nova funcionalidadefix:- Correção de bugdocs:- Documentaçãorefactor:- Refatoraçãotest:- Testeschore:- Manutenção
- Push para a branch (
git push origin feature/amazing) - Abra um Pull Request
Se você é uma instância de Claude Code ou outro assistente de IA trabalhando neste projeto:
📘 Leia primeiro o arquivo CLAUDE.md - Ele contém informações essenciais sobre:
- Arquitetura do framework
- Padrões de código
- Problemas comuns e soluções
- Convenções de nomenclatura
- TypeScript strict mode gotchas
- Fluxo de desenvolvimento
- TypeScript Strict: Mantenha o modo strict ativado
- ES Modules: Use imports com extensão
.js - Formatação: Use Biome (
npm run format) - Testes: Adicione testes para novas features
- Documentação: Atualize README.md e CLAUDE.md se necessário
Inspirado por:
- Express.js - API familiar e robusta
- Fastify - Performance e arquitetura moderna
- Hono - Simplicidade e leveza
- NestJS - TypeScript e estrutura
Este framework está em estágio inicial de desenvolvimento e não deve ser usado em ambientes de produção. Muitas funcionalidades essenciais ainda estão em construção, e a API pode mudar significativamente. Use-o apenas para aprendizado e experimentação por enquanto.