Elysia: A Bun-first Web Framework
Tags: webdev, bunjs, elysia, beginners
Published: 2024-02-05 07:36:58

Bun is a fast and lightweight JavaScript runtime that aims to be an alternative to Node.js. It supports features like hot reloading, file system APIs, and native modules. But what if you want to build a web application using Bun? That’s where Elysia comes in.

Elysia is a web framework for Bun that is designed to be performance-focused, simple, and flexible. It has an Express-like syntax, type inference, middleware, file uploads, and plugins for various functionalities like JWT authentication, tRPC, and more. It also claims to be one of the fastest Bun web frameworks, according to its documentation.

In this article, we will explore some of the major features of [Elysia](https://elysiajs.com/) and see how to use it to create a simple web application.

![elysia](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m3l6zijyz7y7fcq6mc1j.png)

## Getting Started
To get started with Elysia, you need to have Bun installed on your system. You can install it using npm:

```
npm install -g bun
```

Then, you can use the bun create command to generate a new project using the Elysia template:

```
bun create elysia myapp
cd myapp
```

To run the web application in development mode, you can use the bun run dev command:

```
bun dev
```

Navigate to localhost:3000 should greet you with "Hello Elysia".

## Features

- Performance - Static code analysis to generate optimized code
- Unified Type - Shared DTO runtime and compile time validation
- End-to-end Type Safety - Sync your data both client and server
- TypeScript - Extensive type system for full TypeScript experience
- JSX Template Engine - Familiar experience for frontend developer
- Ergonomic by design - Simple and familiar API for building server

## Just Function

One of the core principles of Elysia is that everything is just a function. This means that you can use plain JavaScript functions to define routes, middleware, plugins, and even the Elysia instance itself. This makes Elysia very easy to use, test, and compose.

For example, to define a simple GET route that returns a text response, you can write:

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

new Elysia()
    .get('/', () => 'Hello World')
    .get('/json', () => ({
        hello: 'world'
    }))
    .listen(3000)
```

## Type Safety

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.

```ts
import { Elysia, t } from 'elysia'

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

## Standards

Elysia adopts many standards by default, like OpenAPI, and WinterCG compliance, allowing you to integrate with most of the industry standard tools or at least easily integrate with tools you are familiar with.

For instance, as Elysia adopts OpenAPI by default, generating a documentation with Swagger is as easy as adding a one-liner:

```ts
import { Elysia, t } from 'elysia'
import { swagger } from '@elysiajs/swagger'

new Elysia()
    .use(swagger())
    .get('/id/:id', ({ params: { id } }) => id, {
        params: t.Object({
            id: t.Numeric()
        })
    })
    .listen(3000)
```
## Plugins

Elysia also supports plugins, which are functions that can extend the functionality of the Elysia instance, the request object, the reply object, or the route methods. For example JWT plugin adds support for using JWT in Elysia handler.

Install with:

```
bun add @elysiajs/jwt
```

Then use it:
```ts
import { Elysia } from 'elysia'
import { jwt } from '@elysiajs/jwt'

const app = new Elysia()
    .use(
        jwt({
            name: 'jwt',
            secret: 'Fischl von Luftschloss Narfidort'
        })
    )
    .get('/sign/:name', async ({ jwt, cookie: { auth }, params }) => {
        auth.set({
            value: await jwt.sign(params),
            httpOnly: true,
            maxAge: 7 * 86400,
            path: '/profile',
        })

        return `Sign in as ${auth.value}`
    })
    .get('/profile', async ({ jwt, set, cookie: { auth } }) => {
        const profile = await jwt.verify(auth.value)

        if (!profile) {
            set.status = 401
            return 'Unauthorized'
        }

        return `Hello ${profile.name}`
    })
    .listen(8080)
```

## Conclusion
In this article, we have seen how to use Elysia, a Bun-first web framework, to create a simple web application. We have explored some of the major features of Elysia, such as defining routes, using middleware, and using plugins. Elysia is a fast, simple, and flexible web framework that takes full advantage of Bun’s features and APIs.

I hope this article was helpful for you. If you have any feedback or questions, please let me know. 😊