npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

veloce-ts

v0.4.15

Published

A modern, fast web framework for TypeScript with authentication, RBAC, GraphQL, WebSockets, and response caching

Readme


Modern, Fast Web Framework for TypeScript

Inspired by FastAPI, Built on Hono.js

npm version License: MIT TypeScript Bun Documentation

DocumentationExamplesAPI Reference


Veloce (Italian for "fast") brings the elegance of Python's FastAPI to TypeScript with decorators, automatic validation, and blazing-fast performance.

✨ Features

🚀 Performance First

Built on Hono.js - 10x faster than Express

  • Optimized routing
  • Minimal overhead
  • Edge-ready

🎯 Type Safety

Full TypeScript with inference

  • Zod schema validation
  • Automatic type generation
  • Zero runtime surprises

Developer Experience

Clean, intuitive API

  • Decorator-based routing
  • Auto-generated docs
  • Hot reload support

🔌 Dependency Injection

Built-in DI container

  • Singleton, Request, Transient scopes
  • Constructor injection
  • Easy testing

🌐 Multi-Runtime

Write once, run anywhere

  • Bun (recommended)
  • Node.js 18+
  • Deno
  • Cloudflare Workers

🔧 Extensible

Plugin ecosystem

  • OpenAPI/Swagger
  • GraphQL
  • WebSocket
  • Custom plugins

Performance (v0.3.0)

Response caching

  • In-memory & Redis stores
  • Pattern invalidation
  • TTL configuration
  • Auto cache headers

🔍 Observability (v0.3.0)

Request tracing

  • Auto UUID tracking
  • Request cancellation
  • Timeout management
  • Structured logging

📦 Installation

# 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

🚀 Quick Start

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: '[email protected]' }],
      page: query.page,
      limit: query.limit,
    };
  }

  @Get('/:id')
  async getUser(@Param('id') id: string) {
    return { id, name: 'John', email: '[email protected]' };
  }

  @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:

  • ✅ Automatic validation
  • ✅ Type safety
  • ✅ OpenAPI docs at /docs
  • ✅ Swagger UI ready

💡 More Examples

import { 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

🛠️ CLI Commands

# 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 examples
  • graphql - GraphQL API
  • websocket - WebSocket server
  • fullstack - All features combined

📚 Core Concepts

Validation with Zod

import { 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

Middleware

// 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 })
}));

Error Handling

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;
}

🔌 Plugin System

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,
}));

🌐 Multi-Runtime Support

| Runtime | Status | Notes | |---------|--------|-------| | Bun | ✅ Recommended | Best performance | | Node.js | ✅ Supported | v18+ required | | Deno | ✅ Supported | Use npm:veloce | | Cloudflare Workers | ✅ Supported | Edge-ready |

WebSockets: HTTP → WS upgrade is supported on Bun and Deno. On Node.js the built-in WebSocket plugin still returns 501 until a Node upgrade path lands (see Current limitations below).

// Core HTTP routing works on all runtimes; WebSocket upgrades — check Bun/Deno vs Node.
import { Veloce } from 'veloce-ts';
const app = new Veloce();
app.listen(3000);

⚠️ Current limitations

These are known gaps today so you can choose Veloce-TS with clear expectations:

| Area | Limitation | |------|------------| | WebSockets on Node.js | The built-in WebSocket plugin responds with 501 on Node.js. WebSocket upgrades are supported on Bun and Deno; Node support is not wired up yet (e.g. no ws/HTTP upgrade bridge in core). | | GraphQL | The GraphQL plugin and decorators are still maturing. Treat them as experimental for production unless you have validated your use case. | | ORM integrations | First-class Drizzle helpers exist for the DI container (registerDrizzle, @InjectDB). Prisma and TypeORM are not yet at the same level of documented, built-in integration—use them directly in your services today. | | Pre-1.0 | APIs may change between minor versions. Check the CHANGELOG before upgrading. |

🔭 Planned updates (roadmap)

Directional priorities—not a release calendar. Items may ship in a different order.

  1. ORM choice — Make Drizzle, Prisma, and TypeORM practical first-class options: clear patterns, docs, and (where it helps) small helpers so teams can pick one ORM without fighting the framework.
  2. WebSockets on Node.js — Remove the Node 501 path by integrating a real upgrade path (e.g. ws or runtime-appropriate APIs) so the same decorator API works on Node as on Bun/Deno.
  3. CLI scaffolding — Lightweight code generation (e.g. controller + route + test skeleton), similar in spirit to Feathers’ generate service, kept maintainable and optional.
  4. GraphQL — Improve stability and docs after REST, caching, WebSockets-on-Node, and ORM stories are in better shape (lower priority than the items above).

For the latest shipped changes, see CHANGELOG. Discussion and proposals: GitHub Discussions.

📖 Documentation

| Resource | Description | |----------|-------------| | 📚 Full Documentation | Complete guides and API reference | | ⚠️ Limitations & roadmap | Known gaps and planned direction | | 💡 Examples & Guides | Tutorials and code examples | | 🔧 API Reference | Detailed API documentation |

⚙️ Requirements

  • Runtime: Bun >= 1.0.0 (recommended) or Node.js >= 18.0.0
  • TypeScript: >= 5.0.0
  • Zod: >= 3.22.0

TypeScript Configuration

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler"
  }
}

👥 Core Team

ExcessHawk - Lead Developer & Framework Architect

@ExcessHawk - "Building fast, type-safe web frameworks that developers love to use."

  • 🏗️ Core framework architecture and design
  • ⚡ Performance optimizations and benchmarking
  • 🛠️ Developer experience and tooling
  • 🔌 Plugin system and extensibility

Alfredo Mejia - Project Founder

@AlfredoMejia3001 - Project founder and maintainer


🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. See our Contributors Guide for more details.

📄 License

MIT © 2025 Veloce Contributors

🙏 Acknowledgments

Built with ❤️ using:


⭐ Star us on GitHub📖 Read the Docs💬 Join Discussions

Made with ⚡ by the Veloce team