Skip to content
在 AI 工具中打开 Anthropic

一览

Elysia 是一个符合人体工学的 Web 框架,用于使用 Bun 构建后端服务器。

Elysia 设计简洁且类型安全,提供了一个熟悉的 API,广泛支持 TypeScript,并针对 Bun 进行了优化。

下面是在 Elysia 中的简单 hello world 示例。

typescript
import { Elysia } from 'elysia'

new Elysia()
    .get('/', '你好 Elysia')
    .get('/user/:id', ({ params: { id }}) => id)
    .post('/form', ({ body }) => body)
    .listen(3000)

打开 localhost:3000 ,你应该会看到结果是“Hello Elysia”。

localhost

GET

TIP

将鼠标悬停在代码片段上查看类型定义。

在模拟浏览器中,点击蓝色高亮的路径可以切换路径并预览响应。

Elysia 可在浏览器中运行,所看到的结果实际上是使用 Elysia 执行的。

性能

基于 Bun 及静态代码分析等广泛优化,使 Elysia 能够动态生成优化代码。

Elysia 的性能优于当前大多数 Web 框架[1],甚至能匹配 Golang 和 Rust 框架的表现[2]

框架运行时平均普通文本动态参数JSON 数据
bunbun262,660.433326,375.76237,083.18224,522.36
elysiabun255,574.717313,073.64241,891.57211,758.94
hyper-expressnode234,395.837311,775.43249,675141,737.08
honobun203,937.883239,229.82201,663.43170,920.4
h3node96,515.027114,971.8787,935.9486,637.27
oakdeno46,569.85355,174.2448,260.3636,274.96
fastifybun65,897.04392,856.7181,604.6623,229.76
fastifynode60,322.41371,150.5762,060.2647,756.41
koanode39,594.1446,219.6440,961.7231,601.06
expressbun29,715.53739,455.4634,700.8514,990.3
expressnode15,913.15317,736.9217,128.712,873.84

TypeScript

Elysia 致力于帮助你编写更少的 TypeScript。

Elysia 的类型系统经过细致调校,实现自动从代码中推断类型,而无需显式编写 TypeScript,同时在运行时和编译时都提供类型安全,确保开发体验的人性化。

看看这个例子:

typescript
import { Elysia } from 'elysia'

new Elysia()
    .get('/user/:id', ({ params: { id } }) => id)
                        // ^?
    .listen(3000)

上面代码创建了路径参数 "id"。替代 :id 的值会在运行时和类型中传递给 params.id,无需手动声明类型。

localhost

GET

123

Elysia 的目标是帮助你写更少的 TypeScript,更多关注业务逻辑。让框架帮你处理复杂的类型。

使用 Elysia 不强制要求 TypeScript,但推荐使用。

类型完整性

更进一步,Elysia 提供了 Elysia.t —— 一个模式构建器,可以在运行时和编译时对类型和数值进行校验,形成数据类型的唯一可信来源。

我们来修改之前的代码,使其只接受数字值而非字符串。

typescript
import { Elysia, t } from 'elysia'

new Elysia()
    .get('/user/:id', ({ params: { id } }) => id, {
                                // ^?
        params: t.Object({
            id: t.Number()
        })
    })
    .listen(3000)

这段代码确保路径参数 id 在运行时和编译时(类型层面)始终是数字。

TIP

将鼠标悬停在上述代码片段中的 "id" 以查看类型定义。

借助 Elysia 的模式构建器,我们能像强类型语言一样,使用唯一数据来源确保类型安全。

标准 Schema

Elysia 支持 Standard Schema,允许你使用喜爱的验证库:

  • Zod
  • Valibot
  • ArkType
  • Effect Schema
  • Yup
  • Joi
  • 及更多
typescript
import { Elysia } from 'elysia'
import { z } from 'zod'
import * as v from 'valibot'

new Elysia()
	.get('/id/:id', ({ params: { id }, query: { name } }) => id, {
	//                           ^?
		params: z.object({
			id: z.coerce.number()
		}),
		query: v.object({
			name: v.literal('Lilith')
		})
	})
	.listen(3000)

Elysia 会自动从模式推断类型,允许你同时使用熟悉的验证库和保持类型安全。

OpenAPI

Elysia 默认采纳多种标准,如 OpenAPI、WinterTC 兼容性和 Standard Schema,方便你集成绝大多数行业标准工具,或轻松集成已有熟悉工具。

例如,因 Elysia 默认支持 OpenAPI,只需添加一行代码即可生成 API 文档:

typescript
import { Elysia, t } from 'elysia'
import { openapi } from '@elysia/openapi'

new Elysia()
    .use(openapi()) 
    .get('/user/:id', ({ params: { id } }) => id, {
        params: t.Object({
            id: t.Number()
        })
    })
    .listen(3000)

通过 OpenAPI 插件,你无需额外代码或特殊配置即可无缝生成 API 文档页面,并轻松与团队共享。

从类型生成 OpenAPI

Elysia 对 OpenAPI 提供了极佳支持,模式可用于数据验证、类型推断和 OpenAPI 注解,源于唯一数据来源。

Elysia 也支持用 一行代码直接从类型生成 OpenAPI Schema,实现完整准确的 API 文档,无需手动注解。

typescript
import { Elysia, t } from 'elysia'
import { openapi, fromTypes } from '@elysia/openapi'

export const app = new Elysia()
    .use(openapi({
    	references: fromTypes() 
    }))
    .get('/user/:id', ({ params: { id } }) => id, {
        params: t.Object({
            id: t.Number()
        })
    })
    .listen(3000)

这是 Elysia 的一个 独特功能,使你能够直接从代码中获得完整且准确的 API 文档,无需任何手动注解。

端到端类型安全

利用 Elysia,类型安全不限于服务端。

借助 Elysia 和其客户端库 “Eden”,你可以像 tRPC 一样自动同步类型给前端团队。

typescript
import { Elysia, t } from 'elysia'
import { openapi, fromTypes } from '@elysia/openapi'

export const app = new Elysia()
    .use(openapi({
    	references: fromTypes()
    }))
    .get('/user/:id', ({ params: { id } }) => id, {
        params: t.Object({
            id: t.Number()
        })
    })
    .listen(3000)

export type App = typeof app 

在你的客户端代码中:

typescript
// @filename: server.ts
import { Elysia, t } from 'elysia'

const app = new Elysia()
    .get('/user/:id', ({ params: { id } }) => id, {
        params: t.Object({
            id: t.Number()
        })
    })
    .listen(3000)

export type App = typeof app

// @filename: client.ts
// ---cut---
// client.ts
import { treaty } from '@elysia/eden'
import type { App } from './server'

const app = treaty<App>('localhost:3000')

// 从 /user/617 获取数据
const { data } = await app.user({ id: 617 }).get()
      // ^?

console.log(data)

使用 Eden,你可以使用已有的 Elysia 类型查询 Elysia 服务器,无需代码生成,并自动同步前后端类型。

Elysia 不仅帮助你构建可靠后端,也致力于这个世界上美好的事物。

类型严谨性

大多数具有端到端类型安全的框架通常只涵盖“理想情况”,将错误处理和边缘情况排除在类型系统之外。

然而,Elysia 可以推断 API 的所有可能结果,包括生命周期事件和代码库中任何部分的宏。

typescript
// @filename: server.ts
import { Elysia, t } from 'elysia'

const plugin = new Elysia()
	.macro({
		auth: {
			cookie: t.Object({
				session: t.String()
			}),
			beforeHandle({ cookie: { session }, status }) {
				if(session.value !== 'valid')
					return status(401)
			}
		}
	})

const app = new Elysia()
	.use(plugin)
    .get('/user/:id', ({ params: { id }, status }) => {
    	if(Math.random() > 0.1)
     		return status(420)
       
       return id
    }, {
    	auth: true,
        params: t.Object({
            id: t.Number()
        })
    })
    .listen(3000)

export type App = typeof app

// @filename: client.ts
// ---cut---
// client.ts
import { treaty } from '@elysia/eden'
import type { App } from './server'

const app = treaty<App>('localhost:3000')

// 从 /user/617 获取数据
const { data, error } = await app.user({ id: 617 }).get()
            // ^?

console.log(data)
typescript
import { Elysia, t } from 'elysia'

const plugin = new Elysia()
	.macro({
		auth: {
			cookie: t.Object({
				session: t.String()
			}),
			beforeHandle({ cookie: { session }, status }) {
				if(session.value !== 'valid')
					return status(401)
			}
		}
	})

const app = new Elysia()
	.use(plugin)
    .get('/user/:id', ({ params: { id }, status }) => {
    	if(Math.random() > 0.1)
     		return status(420)
       
       return id
    }, {
    	auth: true,
        params: t.Object({
            id: t.Number()
        })
    })
    .listen(3000)
    
export type App = typeof app

这是 Elysia 多年来在类型系统投资带来的 独特优势 之一。

跨平台性

Elysia 为 Bun 设计并优化了原生功能,但不限于 Bun

遵循 WinterTC 标准 允许你将 Elysia 部署到:

以及更多!请查看侧边栏中的 集成 部分,了解更多支持的运行时环境。

我们的社区

我们希望为每个人创建一个友好且欢迎的社区,采用可爱且富有活力的设计,包括我们的动漫吉祥物 Elysia 酱。

我们相信技术可以既可爱又有趣,而非一成不变的严肃,这能为人们的生活带来乐趣。

即使如此,我们仍然非常认真对待 Elysia,确保它是一个可靠的、高性能的生产级框架,可以信赖于你的下一个项目。

Elysia 已被全球众多公司和项目投入生产使用,包括 X农业与农业合作银行CluelyCS.MoneyAbacate Pay,并被 GitHub 上超过 10,000 个(开源)项目使用。自 2022 年以来持续活跃开发和维护,拥有来自社区的众多常驻贡献者。

Elysia 是构建你的下一个后端服务器的可靠且生产就绪的选择。

以下是社区资源,助你快速入门:


1. 请求/秒的测量。基于 Debian 11 上的基准测试,涉及查询、路径参数解析和响应头设置,使用 Intel i7-13700K,测试时间为 2023 年 8 月 6 日,基于 Bun 0.7.2。详细基准测试条件见 此处

2. 基于 TechEmpower 基准测试第 22 轮