Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions components/blog/Layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<h1 class="!text-3xl !md:text-4xl font-medium">
{{ props.title }}
</h1>
<!-- <aside class="flex gap-3 items-center mt-4">
<aside class="flex gap-3 items-center mt-4">
<img
class="w-9 h-9 rounded-full"
:src="profile"
Expand All @@ -19,8 +19,8 @@
<a :href="twitter" target="_blank">@{{ author.twitter }}</a>
</p>
</div>
</aside> -->
<img :src="props.src" :alt="props.alt" class="w-full my-6" :class="props.shadow ? 'shadow-xl' : 'border'" />
</aside>
<img :src="props.src" :alt="props.alt" class="w-full mt-6 mb-2" :class="props.shadow ? 'shadow-xl' : 'border'" />
<main id="blog-content">
<slot />
</main>
Expand Down Expand Up @@ -57,8 +57,6 @@ const twitter = `https://twitter.com/${author.twitter}`
const mutated = ['.aside', '.content', '.content-container', '.VPDocFooter']
onMounted(() => {
mutated.forEach((selector) => {
console.log(document.querySelector(selector))

document.querySelector(selector)?.classList.add('blog')
})
})
Expand Down
2 changes: 1 addition & 1 deletion components/midori/hero.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
Type Safety</span>, unified type system and outstanding developer experience. Supercharged by Bun.
</h3>
<section class="flex flex-col sm:flex-row items-start sm:items-center w-full md:w-auto gap-4 mt-10 mb-12">
<a class="text-white font-medium text-lg bg-blue-500 px-6 py-2.5 rounded-full" href="/introduction">
<a class="text-white font-medium text-lg bg-blue-500 px-6 py-2.5 rounded-full" href="/at-glance">
Get Started
</a>
<div class="relative flex flex-1 gap-3 text-blue-500">
Expand Down
1 change: 0 additions & 1 deletion components/midori/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import Community from './community.vue'
import QuickStart from './quickstart.vue'
import Sponsor from './sponsor.vue'


import '../tailwind.css'
import './midori.css'

Expand Down
6 changes: 3 additions & 3 deletions components/midori/quickstart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@
<aside class="flex gap-4">
<a
class="text-white font-medium text-lg bg-blue-500 px-6 py-2.5 rounded-full"
href="/introduction"
href="/at-glance"
>
Introduction
</a>
<a
class="text-blue-500 font-medium text-lg px-6 py-2.5 rounded-full hover:bg-blue-200/25 dark:hover:bg-blue-500/20 transition-colors"
href="/at-glance"
href="/quick-start"
>
At glance
Quick Start
</a>
</aside>
</section>
Expand Down
4 changes: 2 additions & 2 deletions components/midori/sponsor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@
'[Private]'
}}
</p>
<p
<!-- <p
v-if="sponsor.tier.monthlyPriceInDollars"
class="text-3xl text-gray-400 bg-clip-text text-transparent bg-gradient-to-tl font-medium from-fuchsia-500 to-blue-500 mt-3 mb-1"
>
${{ sponsor.tier.monthlyPriceInDollars }}
</p>
</p> -->
<p className="text-sm text-gray-500 dark:text-gray-400 my-0">
{{
dayjs()
Expand Down
52 changes: 41 additions & 11 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,13 @@ export default defineConfig({
text: '👋 Getting Started',
items: [
{
text: 'Introduction',
link: '/introduction'
text: 'At Glance',
link: '/at-glance'
},
{
text: 'Quick Start',
link: '/quick-start'
},
{
text: 'At Glance',
link: '/at-glance'
},
{
text: 'Table of Content',
link: '/table-of-content'
Expand Down Expand Up @@ -298,6 +294,10 @@ export default defineConfig({
{
text: 'Macro',
link: '/patterns/macro'
},
{
text: 'MVC model',
link: '/patterns/mvc'
}
]
},
Expand All @@ -315,16 +315,42 @@ export default defineConfig({
},
{
text: 'Eden Treaty',
link: '/eden/treaty.md'
collapsed: false,
items: [
{
text: 'Overview',
link: '/eden/treaty/overview'
},
{
text: 'Parameters',
link: '/eden/treaty/parameters'
},
{
text: 'Response',
link: '/eden/treaty/response'
},
{
text: 'Web Socket',
link: '/eden/treaty/websocket'
},
{
text: 'Config',
link: '/eden/treaty/config'
},
{
text: 'Unit Test',
link: '/eden/treaty/unit-test'
},
{
text: 'Legacy (Treaty 1)',
link: '/eden/treaty/legacy.md'
}
]
},
{
text: 'Eden Fetch',
link: '/eden/fetch.md'
},
{
text: 'Test',
link: '/eden/test.md'
}
]
},
{
Expand Down Expand Up @@ -410,6 +436,10 @@ export default defineConfig({
{
text: 'SvelteKit',
link: '/integrations/sveltekit'
},
{
text: 'Drizzle',
link: '/integrations/drizzle'
}
// {
// text: 'Cheat Sheet',
Expand Down
24 changes: 24 additions & 0 deletions docs/.vitepress/theme/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,30 @@ button.copy::after {
background-color: var(--vp-c-brand-nav-active);
}
}

& > .VPSidebarItem {
@apply pl-4 mb-0.5 dark:border-l-gray-600 rounded-lg;

& > div {
& > div {
@apply pl-2 mb-0.5 dark:border-l-gray-600 rounded-lg -translate-x-2;

&:hover, &:focus {
background-color: var(--vp-c-brand-nav-active);
}

&.is-active.has-active {
background-color: var(--vp-c-brand-nav-active);
}
}

& > .caret {
&:hover, &:focus {
background-color: transparent;
}
}
}
}
}
}
}
Expand Down
83 changes: 56 additions & 27 deletions docs/at-glance.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,26 @@ head:
content: Designed with ergonomic design, extensive support for TypeScript, modern JavaScript API, optimized for Bun. Offers a unique experience unified type, and end-to-end type safety while maintaining excellent performance.
---

<script setup>
import Card from '../components/nearl/card.vue'
import Deck from '../components/nearl/card-deck.vue'
</script>

# At glance
Elysia is an ergonomic web framework for building backend servers with Bun.

Elysia is designed with familiar API from Express and Fastify with extensive support for TypeScript, modern JavaScript API, and optimized for Bun.
Designed with simplicity and type safety in mind with familiar API with extensive support for TypeScript, optimized for Bun.

Here's a simple hello world in Elysia.

```typescript
import { Elysia } from 'elysia'

new Elysia()
.get('/', () => 'Hello Elysia')
.listen(3000)
.get('/', () => 'hi')
.get('/user/:id', ({ params: { id }}) => id)
.post('/form', ({ body }) => body)
.listen(8080)
```

Navigate to [localhost:3000](http://localhost:3000/) and it should show 'Hello Elysia' as a result.
Expand All @@ -38,39 +46,40 @@ Elysia can outperform most of the web frameworks available today<a href="#ref-1"

| Framework | Runtime | Average | Plain Text | Dynamic Parameters | JSON Body |
| ------------- | ------- | ----------- | ---------- | ------------------ | ---------- |
| Elysia | bun | 275,063.507 | 326,868.9 | 261,729.3 | 236,592.32 |
| Bun | bun | 273,634.127 | 322,071.07 | 251,679.46 | 247,151.85 |
| Hono | bun | 257,532.08 | 320,757.07 | 233,769.22 | 218,069.95 |
| Web Standard | bun | 242,838.703 | 288,692.76 | 226,591.45 | 213,231.9 |
| Hyper Express | node | 242,045.913 | 354,697.63 | 277,109.51 | 94,330.6 |
| h3 | node | 112,677.263 | 137,556.49 | 101,431.5 | 99,043.8 |
| Fastify | node | 64,145.95 | 74,631.46 | 66,235.48 | 51,570.91 |
| Koa | node | 38,696.13 | 44,741.88 | 39,790.11 | 31,556.4 |
| Hapi | node | 28,170.763 | 42,780.44 | 15,350.06 | 26,381.79 |
| Adonis | node | 23,367.073 | 22,673.54 | 21,442.97 | 25,984.71 |
| Express | node | 16,301.823 | 17,974.35 | 17,090.62 | 13,840.5 |
| Nest | node | 14,978.863 | 16,926.01 | 15,507.62 | 12,502.96 |
| bun | bun | 262,660.433 | 326,375.76 | 237,083.18 | 224,522.36 |
| elysia | bun | 255,574.717 | 313,073.64 | 241,891.57 | 211,758.94 |
| hyper-express | node | 234,395.837 | 311,775.43 | 249,675 | 141,737.08 |
| hono | bun | 203,937.883 | 239,229.82 | 201,663.43 | 170,920.4 |
| h3 | node | 96,515.027 | 114,971.87 | 87,935.94 | 86,637.27 |
| oak | deno | 46,569.853 | 55,174.24 | 48,260.36 | 36,274.96 |
| fastify | bun | 65,897.043 | 92,856.71 | 81,604.66 | 23,229.76 |
| fastify | node | 60,322.413 | 71,150.57 | 62,060.26 | 47,756.41 |
| koa | node | 39,594.14 | 46,219.64 | 40,961.72 | 31,601.06 |
| express | bun | 29,715.537 | 39,455.46 | 34,700.85 | 14,990.3 |
| express | node | 15,913.153 | 17,736.92 | 17,128.7 | 12,873.84 |

## TypeScript

Elysia is built with a complex type system trying to infer every possible detail from simple path parameters to full-blown recursive instance deep merge to provide you the most out of TypeScript.
Elysia is designed to help you write less TypeScript.

Elysia's Type System is fine-tuned to infer your code into type automatically without needing to write explicit TypeScript while providing type-safety for both runtime and compile time to provide you with the most ergonomic developer experience.

Take a look at this example:

```typescript
import { Elysia } from 'elysia'

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

The above code allows you to create a path parameter with the name of id, the value that passes after `/id/` will be reflected in `params.id`.

In most framework, you need to provide a generic type to the **id** parameter while Elysia understand that `params.id` will always be available and type as **string**. Elysia then infers this type without any manual type reference needed.
The above code create a path parameter "id", the value that replace `:id` will be passed to `params.id` both in runtime and type without manual type declaration.

Elysia's goal is to help you write less TypeScript and focus more on Business logic. Let the complex type be handled by the framework.

TypeScript is not needed to use Elysia, but it's recommended to use Elysia with TypeScript.

## Unified Type

To take a step further, Elysia provide **Elysia.t**, a schema builder to validate type and value in both runtime and compile-time to create a single source of truth for your data-type. Elysia refers this term as **Unified Type**.
Expand All @@ -81,7 +90,7 @@ Let's modify the previous code to accept only a numeric value instead of a strin
import { Elysia, t } from 'elysia'

new Elysia()
.get('/id/:id', ({ params: { id } }) => id, {
.get('/user/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Numeric()
})
Expand All @@ -105,7 +114,7 @@ import { swagger } from '@elysiajs/swagger'

new Elysia()
.use(swagger())
.get('/id/:id', ({ params: { id } }) => id, {
.get('/user/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Numeric()
})
Expand All @@ -127,7 +136,7 @@ import { swagger } from '@elysiajs/swagger'

const app = new Elysia()
.use(swagger())
.get('/id/:id', ({ params: { id } }) => id, {
.get('/user/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Numeric()
})
Expand All @@ -141,19 +150,39 @@ And on your client-side:

```typescript
// client.ts
import { edenTreaty } from '@elysiajs/eden'
import { treaty } from '@elysiajs/eden'
import type { App } from './server'

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

// data is typed as number
const { data } = await app.id['177013'].get()
// Get data from /user/617
const { data } = await app.user({ id: 617 }).get()
```

With Eden, you can use the existing Elysia type to query Elysia server **without code generation** and synchronize type for both frontend and backend automatically.

Elysia is not only about helping you to create a confident backend but for all that is beautiful in this world.

## Platform Agnostic

Elysia was designed but was **not limited to Bun**. Being [WinterCG compliant](https://wintercg.org/) allows you to deploy the Elysia server on Cloudflare Worker, Vercel Edge Function, and most other runtimes that support Web Standard Request.

## Our Community

If you have questions or get stuck about Elysia, feel free to ask our community on GitHub Discussions, Discord, and Twitter.

<Deck>
<Card title="Discord" href="https://discord.gg/eaFJ2KDJck">
Official ElysiaJS discord community server
</Card>
<Card title="Twitter" href="https://twitter.com/elysiajs">
Track update and status of Elysia
</Card>
<Card title="GitHub" href="https://github.com/elysiajs">
Source code and development
</Card>
</Deck>

---

<small id="ref-1">1. Measure in requests/second. The benchmark for parsing query, path parameter and set response header on Debian 11, Intel i7-13700K tested on Bun 0.7.2 on 6 Aug 2023. See the benchmark condition [here](https://github.com/SaltyAom/bun-http-framework-benchmark/tree/c7e26fe3f1bfee7ffbd721dbade10ad72a0a14ab#results).</small>
Expand Down
6 changes: 3 additions & 3 deletions docs/blog.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ head:
<Blogs
:blogs="[
{
title: 'Introducing support for Scalar - Elysia',
href: '/blog/elysia-scalar',
detail: 'We are changing API documentation provider to Scalar instead of Swagger UI by default. Scalar is a modern, beautiful API references for OpenAPI compatible, and customizable built on-top of Vue. Elysia now ship @elysia/swagger package by using Scalar as a default provider, with option to switch back to Swagger UI if need.'
title: 'Elysia 1.0 - Lament of the Fallen',
href: '/blog/elysia-10',
detail: 'Introducing Sucrose, a better static code analysis engine, improved starts up time up to 14x, remove 40 routes/instance limitation, faster type inference up to ~3.8x, Eden Treaty 2, Hook type (breaking change), and inline error for strict type check.'
},
{
title: 'Introducing Elysia 0.8 - Gate of Steiner',
Expand Down
Loading