
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
A modern, fast web framework for TypeScript with authentication, RBAC, GraphQL, WebSockets, and response caching
Inspired by FastAPI, Built on Hono.js
Veloce (Italian for "fast") brings the elegance of Python's FastAPI to TypeScript with decorators, automatic validation, and blazing-fast performance.
🚀 Performance FirstBuilt on Hono.js - 10x faster than Express
🎯 Type SafetyFull TypeScript with inference
✨ Developer ExperienceClean, intuitive API
|
🔌 Dependency InjectionBuilt-in DI container
🌐 Multi-RuntimeWrite once, run anywhere
🔧 ExtensiblePlugin ecosystem
⚡ Performance (v0.3.0)Response caching
🔍 Observability (v0.3.0)Request tracing
|
# Using Bun (recommended)
bun add veloce-ts zod
# Using npm
npm install veloce-ts zod
# Using pnpm
pnpm add veloce-ts zod
CLI Tool (optional)
npm install -g veloce-ts
Create your first API in under 2 minutes:
import { Veloce, Controller, Get, Post, Body, Param, Query } from 'veloce-ts';
import { z } from 'zod';
// Define validation schemas
const CreateUserSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
age: z.number().min(18).optional(),
});
const QuerySchema = z.object({
page: z.string().transform(Number).default('1'),
limit: z.string().transform(Number).default('10'),
});
@Controller('/users')
class UserController {
@Get('/')
async listUsers(@Query(QuerySchema) query: z.infer<typeof QuerySchema>) {
return {
users: [{ id: 1, name: 'John', email: 'john@example.com' }],
page: query.page,
limit: query.limit,
};
}
@Get('/:id')
async getUser(@Param('id') id: string) {
return { id, name: 'John', email: 'john@example.com' };
}
@Post('/')
async createUser(@Body(CreateUserSchema) user: z.infer<typeof CreateUserSchema>) {
return { id: 2, ...user, createdAt: new Date() };
}
}
const app = new Veloce({
title: 'My API',
version: '1.0.0',
description: 'A sample API built with Veloce',
});
app.include(UserController);
app.listen(3000, () => {
console.log('🚀 Server running on http://localhost:3000');
console.log('📚 Docs available at http://localhost:3000/docs');
});
That's it! 🎉 Your API is now running with:
/docsimport { Veloce } from 'veloce-ts';
import { z } from 'zod';
const app = new Veloce();
const UserSchema = z.object({
name: z.string(),
email: z.string().email(),
});
app.get('/users', {
handler: async (c) => {
return [{ id: 1, name: 'John' }];
},
});
app.post('/users', {
body: UserSchema,
handler: async (c) => {
const user = await c.req.json();
return { id: 2, ...user };
},
});
app.listen(3000);
import { Veloce, Controller, Get, Depends } from 'veloce-ts';
class DatabaseService {
async getUsers() {
return [{ id: 1, name: 'John' }];
}
}
@Controller('/users')
class UserController {
@Get('/')
async getUsers(@Depends(DatabaseService) db: DatabaseService) {
return await db.getUsers();
}
}
const app = new Veloce();
app.getContainer().register(DatabaseService, { scope: 'singleton' });
app.include(UserController);
app.listen(3000);
import { WebSocket, OnConnect, OnMessage, OnDisconnect } from 'veloce-ts';
import { z } from 'zod';
const MessageSchema = z.object({
type: z.string(),
content: z.string(),
});
@WebSocket('/chat')
class ChatHandler {
@OnConnect()
handleConnect(client: WebSocketConnection) {
client.join('lobby');
client.send({ type: 'welcome', message: 'Hello!' });
}
@OnMessage(MessageSchema)
handleMessage(client: WebSocketConnection, message: z.infer<typeof MessageSchema>) {
client.broadcast(message, 'lobby');
}
@OnDisconnect()
handleDisconnect(client: WebSocketConnection) {
console.log('Client disconnected');
}
}
import { Resolver, Query, Mutation, Arg } from 'veloce-ts';
import { z } from 'zod';
const CreateUserInput = z.object({
name: z.string(),
email: z.string().email(),
});
@Resolver()
class UserResolver {
@Query()
async users() {
return [{ id: 1, name: 'John' }];
}
@Mutation()
async createUser(@Arg('input', CreateUserInput) input: z.infer<typeof CreateUserInput>) {
return { id: 2, ...input };
}
}
import { Controller, Get, Post, Cache, CacheInvalidate, Param, Body } from 'veloce-ts';
@Controller('/products')
class ProductController {
// Cache responses for 5 minutes
@Get('/')
@Cache({ ttl: '5m', key: 'products:list' })
async listProducts() {
return await db.products.findMany();
}
// Cache with dynamic key based on ID
@Get('/:id')
@Cache({ ttl: '10m', key: 'product:{id}' })
async getProduct(@Param('id') id: string) {
return await db.products.findOne(id);
}
// Invalidate cache patterns on mutation
@Post('/')
@CacheInvalidate(['products:*'])
async createProduct(@Body(ProductSchema) data: any) {
return await db.products.create(data);
}
}
// Or use Redis for distributed caching
import { RedisCacheStore } from 'veloce-ts/cache';
const redisCache = new RedisCacheStore({
host: 'localhost',
port: 6379,
});
app.use(createCacheMiddleware({ store: redisCache }));
import { Controller, Get, RequestId, AbortSignal } from 'veloce-ts';
import { createRequestContextMiddleware } from 'veloce-ts';
// Enable request context middleware
app.use(createRequestContextMiddleware({
timeout: 30000, // 30 second timeout
logging: true // Auto-log all requests
}));
@Controller('/data')
class DataController {
// Get unique request ID for tracing
@Get('/process')
async processData(@RequestId() requestId: string) {
logger.info({ requestId }, 'Processing started');
// Request ID is automatically included in all logs
await performHeavyTask();
logger.info({ requestId }, 'Processing completed');
return { requestId, status: 'done' };
}
// Use AbortSignal for cancellation
@Get('/long-running')
async longRunning(@AbortSignal() signal: AbortSignal) {
// Check if request was cancelled
if (signal.aborted) {
throw new Error('Request cancelled');
}
// Listen for cancellation
signal.addEventListener('abort', () => {
console.log('Request cancelled by client');
});
return await performLongTask();
}
}
// Request ID is automatically added to response headers as X-Request-ID
// Example log output:
// [2025-10-29 10:23:45] [req-id: abc-123-def-456] INFO: Request started GET /data/process
// [2025-10-29 10:23:45] [req-id: abc-123-def-456] INFO: Processing started
// [2025-10-29 10:23:46] [req-id: abc-123-def-456] INFO: Processing completed
# Create a new project
veloce-ts new my-api --template rest
# Start development server
veloce-ts dev
# Build for production
veloce-ts build
# Generate OpenAPI spec
veloce-ts generate openapi
# Generate TypeScript client
veloce-ts generate client
Available Templates:
rest - REST API with examplesgraphql - GraphQL APIwebsocket - WebSocket serverfullstack - All features combinedimport { z } from 'zod';
const UserSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
age: z.number().min(18).optional(),
});
type User = z.infer<typeof UserSchema>; // Automatic type inference
// Global middleware
app.use(async (c, next) => {
console.log(`${c.req.method} ${c.req.url}`);
await next();
});
// Built-in middleware
app.useCors({ origin: '*' });
app.useRateLimit({ windowMs: 15 * 60 * 1000, max: 100 });
app.useCompression();
// Request context with tracing (v0.3.0)
import { createRequestContextMiddleware } from 'veloce-ts';
app.use(createRequestContextMiddleware({
timeout: 30000,
logging: true
}));
// Response caching (v0.3.0)
import { createCacheMiddleware, InMemoryCacheStore } from 'veloce-ts';
app.use(createCacheMiddleware({
store: new InMemoryCacheStore({ maxSize: 1000 })
}));
import { HTTPException } from 'veloce-ts';
@Get('/:id')
async getUser(@Param('id') id: string) {
const user = await findUser(id);
if (!user) {
throw new HTTPException(404, 'User not found');
}
return user;
}
import { Veloce, OpenAPIPlugin, GraphQLPlugin } from 'veloce-ts';
const app = new Veloce();
// OpenAPI documentation
app.usePlugin(new OpenAPIPlugin({
path: '/openapi.json',
docsPath: '/docs',
}));
// GraphQL support
app.usePlugin(new GraphQLPlugin({
path: '/graphql',
playground: true,
}));
| Runtime | Status | Notes |
|---|---|---|
| Bun | ✅ Recommended | Best performance |
| Node.js | ✅ Supported | v18+ required |
| Deno | ✅ Supported | Use npm:veloce |
| Cloudflare Workers | ✅ Supported | Edge-ready |
// Same code works everywhere!
import { Veloce } from 'veloce-ts';
const app = new Veloce();
app.listen(3000);
| Resource | Description |
|---|---|
| 📚 Full Documentation | Complete guides and API reference |
| 💡 Examples & Guides | Tutorials and code examples |
| 🔧 API Reference | Detailed API documentation |
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler"
}
}
@ExcessHawk - "Building fast, type-safe web frameworks that developers love to use."
@AlfredoMejia3001 - Project founder and maintainer
Contributions are welcome! Please feel free to submit a Pull Request. See our Contributors Guide for more details.
MIT © 2025 Veloce Contributors
Built with ❤️ using:
⭐ Star us on GitHub • 📖 Read the Docs • 💬 Join Discussions
Made with ⚡ by the Veloce team
FAQs
A modern, fast web framework for TypeScript with authentication, RBAC, GraphQL, WebSockets, and response caching
We found that veloce-ts demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.