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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@karinjs/express

v1.1.4

Published

Fast, unopinionated, minimalist web framework

Readme

@karinjs/express

NPM Version License Node Version

基于 TypeScript 重写的 Express 5.x 框架

快速、极简、无约束的 Web 框架

English | 简体中文

📖 项目简介

这是一个完全使用 TypeScript 重写的 Express 5.x 框架,旨在提供更好的类型安全性和开发体验,同时保持与原版 Express 的 API 兼容性。

🎯 项目初衷

本项目专为 github.com/karinjs/karin 优化而开发,针对其特定使用场景进行了深度定制和性能优化。

⚠️ 特别声明

[!WARNING] 本项目未经生产环境充分验证,不建议非专业用户使用。

  • 🔴 本项目仍在积极开发中
  • 🔴 未经过大规模生产环境的长期验证
  • 🔴 建议仅在开发和测试环境中使用
  • 🔴 生产环境使用需自行承担风险

📋 免责声明

  • 本项目按 "原样" 提供,不提供任何明示或暗示的保证
  • 使用本项目所产生的任何直接或间接损失,开发者不承担责任
  • 本项目基于 Express 5.x 进行重写,但与官方 Express 项目无关
  • 在生产环境使用前,请进行充分的测试和评估
  • 对于关键业务系统,建议使用经过验证的稳定版本(如官方 Express)

✨ 主要特性

  • 🎯 完整的 TypeScript 重写:核心代码全部使用 TypeScript 编写
  • 🔒 类型安全:提供完整的类型定义,享受更好的 IDE 智能提示
  • 📦 Monorepo 架构:使用 pnpm workspace 管理多个相关包
  • 🚀 现代化构建:使用 tsdown 进行高效打包
  • ESM 优先:原生支持 ES Modules
  • 🔄 API 兼容:保持与 Express 5.x 的 API 兼容性
  • 🧪 完整测试:包含大量单元测试和集成测试

🏗️ 项目架构

Monorepo 结构

本项目采用 pnpm workspace 管理,包含以下子包:

packages:
  - "packages/path-to-regexp"   # 路径匹配和参数提取
  - "packages/send"              # 文件发送类型定义
  - "packages/connect"           # Connect 中间件类型定义
  - "packages/serve-static"      # 静态文件服务

核心模块

src/
├── application.ts          # Application 类 - 核心应用逻辑
├── express.ts             # Express 工厂函数和导出
├── request.ts             # Request 类 - 扩展的请求对象
├── response.ts            # Response 类 - 扩展的响应对象
├── view.ts                # 视图渲染系统
├── utils.ts               # 工具函数
├── router/                # 路由系统
│   ├── index.ts          # Router 类
│   ├── layer.ts          # 路由层
│   └── route.ts          # Route 类
├── body-parser/           # 请求体解析器
│   └── src/
└── serve-static/          # 静态文件服务实现
    └── index.ts

🔄 与原版 Express 的主要区别

1. 完全的 TypeScript 实现

  • 原版:JavaScript 实现,通过 @types/express 提供类型
  • 本项目:TypeScript 原生实现,类型定义即源码
// 更好的类型推导
const app = express()
app.get('/user/:id', (req, res) => {
  // req.params 自动推导类型
  const id = req.params.id // string
  res.json({ id })
})

2. 模块化架构

  • 原版:依赖外部 npm 包(如 path-to-regexpsend 等)
  • 本项目:将核心依赖纳入 monorepo,便于维护和定制

3. 现代化的构建系统

  • 原版:传统的 CommonJS 模块
  • 本项目
    • 使用 tsdown 构建,生成 ESM 格式
    • 支持 Tree-shaking
    • 更小的包体积
// tsdown.config.ts
export default defineConfig({
  entry: ['./src/index.ts'],
  format: ['esm'],
  dts: { resolve: true, build: true },
  target: 'node18',
  platform: 'node',
})

4. 增强的类型系统

  • Application 类:完整的类型定义,包括所有 HTTP 方法
  • Request/Response:泛型支持,更精确的类型推导
  • 路由系统:路径参数、查询参数的类型安全
// 泛型支持示例
class Request<
  P = ParamsDictionary,      // 路径参数类型
  ResBody = any,             // 响应体类型
  ReqBody = any,             // 请求体类型
  ReqQuery = ParsedQs,       // 查询参数类型
  LocalsObj = Record<string, any>  // 本地变量类型
> extends IncomingMessage

5. 内置模块重写

Router 模块

  • 完全 TypeScript 重写
  • 更好的路由匹配性能
  • 类型安全的中间件链

Body Parser

  • 集成到核心,无需单独安装
  • TypeScript 原生实现
  • 支持 JSON、URL-encoded、Raw、Text 等格式

Serve Static

  • 静态文件服务的 TypeScript 实现
  • 更好的错误处理
  • 内置安全特性

6. 改进的错误处理

// Application.status() - 更严格的状态码验证
status(code: StatusCode): this {
  if (!Number.isInteger(code)) {
    throw new TypeError(`Invalid status code: ${JSON.stringify(code)}`)
  }
  if (code < 100 || code > 999) {
    throw new RangeError(`Invalid status code: ${JSON.stringify(code)}`)
  }
  this.statusCode = code
  return this
}

7. 优化的开发体验

  • 路径别名配置
{
  "paths": {
    "router": ["./src/router/index.ts"],
    "body-parser": ["./src/body-parser/src/index.ts"],
    "serve-static": ["./src/serve-static/index.ts"]
  }
}
  • 统一的测试框架:所有模块使用 Mocha + TypeScript
  • 现代化的工具链:ESLint、TypeScript 5.x

📦 安装

npm install @karinjs/express
# 或
pnpm add @karinjs/express
# 或
yarn add @karinjs/express

🚀 快速开始

import express from '@karinjs/express'

const app = express()

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000')
})

💡 核心改进点

1. 类型安全的中间件

import { RequestHandler } from '@karinjs/express'

const authMiddleware: RequestHandler = (req, res, next) => {
  // 完整的类型提示
  const token = req.get('Authorization')
  if (!token) {
    return res.status(401).json({ error: 'Unauthorized' })
  }
  next()
}

2. 泛型路由处理

interface UserParams {
  id: string
}

interface UserBody {
  name: string
  email: string
}

app.post<UserParams, any, UserBody>('/user/:id', (req, res) => {
  const { id } = req.params  // 类型: { id: string }
  const { name, email } = req.body  // 类型: { name: string, email: string }
  res.json({ id, name, email })
})

3. 内置 Body Parser

// 无需额外安装 body-parser
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

app.post('/api/data', (req, res) => {
  console.log(req.body)  // 自动解析
  res.json({ received: true })
})

4. 静态文件服务

// 使用内置的 serve-static
app.use(express.static('public'))
app.use('/static', express.static('assets'))

📚 API 文档

本项目保持与 Express 5.x 的 API 兼容性。主要的 API 包括:

Application

  • app.get(path, ...handlers)
  • app.post(path, ...handlers)
  • app.put(path, ...handlers)
  • app.delete(path, ...handlers)
  • app.use([path], ...middleware)
  • app.listen(port, [callback])
  • app.set(setting, value)
  • app.engine(ext, callback)
  • app.render(view, [locals], callback)

Request

  • req.params - 路径参数
  • req.query - 查询参数
  • req.body - 请求体
  • req.get(field) - 获取请求头
  • req.accepts(types) - 内容协商
  • req.is(type) - 检查 Content-Type

Response

  • res.status(code) - 设置状态码
  • res.send(body) - 发送响应
  • res.json(obj) - 发送 JSON
  • res.redirect([status], url) - 重定向
  • res.render(view, [locals], [callback]) - 渲染视图
  • res.sendFile(path, [options], [callback]) - 发送文件

🧪 测试

# 运行所有测试
pnpm test

# 运行特定模块测试
pnpm test:router
pnpm test:body-parser
pnpm test:serve-static

# 运行验收测试
pnpm test:acceptance

# 生成覆盖率报告
pnpm test-cov

🛠️ 开发

# 克隆仓库
git clone https://github.com/sj817/express.git
cd express

# 安装依赖
pnpm install

# 构建项目
pnpm build

# 运行 Lint
pnpm lint

# 修复 Lint 问题
pnpm lint:fix

📋 为什么要重写?

1. 类型安全

原版 Express 的类型定义存在于 @types/express,与实现分离,容易出现类型不匹配的问题。TypeScript 原生实现可以确保类型与代码完全一致。

2. 更好的维护性

Monorepo 架构使得核心依赖都在一个仓库中,便于整体维护和优化,减少版本不兼容的风险。

3. 现代化特性

  • 原生 ESM 支持
  • 更小的包体积(Tree-shaking)
  • 更好的构建性能(tsdown)

4. 学习和定制

完全掌握代码实现,方便根据项目需求进行定制和优化。

5. 性能优化

  • 减少依赖层级
  • 优化的路由匹配算法
  • 更高效的类型推导

🎯 项目目标

  • ✅ 完整的 TypeScript 重写
  • ✅ 保持 API 兼容性
  • ✅ Monorepo 架构
  • ✅ 完整的测试覆盖
  • ✅ 现代化构建系统
  • 🚧 性能优化
  • 🚧 更多示例和文档

📄 许可证

MIT

🤝 贡献

欢迎提交 Issue 和 Pull Request!

📦 打包产物

本项目使用 tsdown 进行打包,最终产物为零依赖的纯 ESM 模块:

✨ 打包产物信息:
ℹ dist/index.mjs   904.62 kB │ gzip: 278.74 kB
ℹ dist/index.d.ts   75.65 kB │ gzip:  20.25 kB
ℹ 2 files, total: 980.27 kB

📊 对比数据:
源包大小: 2.2MB / 65 packages (数据来源: https://pkg-size.dev/express)
打包后: 980.27 kB / 0 dependencies ⚡

🎯 零依赖优势

打包后的代码完全独立运行,无需安装任何额外依赖:

  • 部署简单:无需担心依赖版本冲突
  • 体积更小:打包后仅 980 KB(压缩后 278 KB)
  • 安全可靠:减少供应链攻击风险
  • 性能优化:减少模块加载开销

🚀 ESM 现代化

由于采用 ESM 格式,代码可完全参与任何现代化打包器的优化:

  • 🌲 Tree-shaking:自动移除未使用的代码
  • 📦 打包器友好:完美支持 Vite、Rollup、esbuild、webpack 等
  • 🔒 类型完整:包含完整的 TypeScript 类型定义
  • 按需加载:支持动态 import 和代码分割

妈妈再也不用担心打包器无法处理 Express 啦! 🎉

🙏 致谢

本项目基于 Express 进行重写,感谢 Express 团队及所有贡献者的杰出工作。

上游核心依赖

本项目将以下核心依赖整合到 Monorepo 中,并进行了 TypeScript 重写:

路由与中间件

静态文件服务

请求体解析

  • body-parser - 请求体解析器(已整合重写)
    • JSON 解析
    • URL-encoded 解析
    • Raw 解析
    • Text 解析

运行时依赖库

以下依赖库在打包时被内联,最终产物为零依赖:

HTTP 工具

工具库

开发工具

构建与类型

  • TypeScript (v5.9.3) - TypeScript 编译器
  • tsdown (v0.16.7) - 高性能 TypeScript 打包工具
  • tsx - TypeScript 执行器

测试框架

代码质量

特别感谢

📮 联系方式


如果这个项目对你有帮助,请给一个 ⭐️ Star 支持一下!