How to deploy Elysiajs App on CloudFlare Workers
Well, another sleepless night and another tech guide. This time, i’d like to talk about how to deploy an ElysiaJS app with CloudFlare Workers. In this one, i’ll not gonna dig deep the details of ElysiaJS and CloudFlare Workers and will assume that you are already familiar with ElysiaJS and CloudFlare concept. If not, you can take a look to offical ElysiaJS and CloudFlare Workers docs.
ElysiaJS
ElysiaJS is a backend framework that works with the power of Bun. It’s 21 times faster than ExpressJS. Also, it has a much better developer experience in my opinion. It has really cool features, so please check out all the examples and official docs from here.
CloudFlare Workers
Well, everybody knows Cloudflare. You can use Workers in many different ways. For example, I've used them as a reverse proxy. In this context, we'll deploy our backend on Workers. We need to install the Wrangler package for programmatically accessing Cloudflare Workers
Hands-On
Well, let’s start from scratch and deploy a ElysiaJS — Pokémon API Endpoint with Cloudflare Workers!
Lets create an ElysiaJS project:
bun create elysia .
Well, since Elysia partially follows WinterCG compliance, it’s optimized for Bun but also openly supports other runtimes such as Cloudflare Runtime. We need to configure our app in some way. Let’s create an index.ts file and modify it like this:
// src/index.ts
import { Env } from "bun"
import { app } from "./app"
import { Context } from "elysia"
export default {
async fetch(
request: Request,
env: Env,
ctx: Context,
): Promise<Response> {
return await app.fetch(request)
},
}
With this configuration, the Cloudflare Worker will recognize our ElysiaJS app and work properly!
Now, lets create routes folder and pokemon.ts file in it.
// src/routes/pokemon.ts
import { Elysia } from 'elysia'
export const pokemonController = new Elysia({ prefix: "/pokemon" })
.get("/:pokemonName", async (context) => {
const { params: { pokemonName } } = context
const pokemonData = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonName}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
if (pokemonData.status !== 200) {
throw new Error(await pokemonData.text())
}
return new Response(JSON.stringify({ data: await pokemonData.json() }), { status: 200 })
})
Now we have our Pokémon API endpoint that works dynamically! Notice how we used “:pokemonName” for dynamic endpoints and accessed it via the const { params: { pokemonName } } = context
block. It's beautiful.
Prefix option is just one of the coolest features of ElysiaJS!
Now lets back to the src/ folder and create an app.ts file:
// src/routes/app.ts
import Elysia from "elysia";
import { pokemonController } from "./routes/pokemon";
export const app = new Elysia({ aot: false }).onError(({ code, error }) => {
console.log(code)
return new Response(JSON.stringify({ error: error.toString() ?? code }), { status: 500 })
}).use(pokemonController)
app.get('/', () => "Hello from Elysia 🦊")
Another cool feature that Elysia provides is the onError function. We don't need to write response codes for errors in each route. We can simply define a format in the app.ts file, and every endpoint will use it automatically!
Everything should work now. Lets check it locally via command of:
bun run dev
And check your localhost for results
localhost:3000/
localhost:3000/pokemon/snorlax
We are ready to deploy!!
Deployment
As i mentioned before, we need to install Wrangler package and make some configurations.
bun add wrangler
# wrangler.toml
name = "elysia-bun"
compatibility_date = "2023-12-01"
# [vars]
# MY_VAR = "my-variable"
# [[kv_namespaces]]
# binding = "MY_KV_NAMESPACE"
# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# [[r2_buckets]]
# binding = "MY_BUCKET"
# bucket_name = "my-bucket"
# [[d1_databases]]
# binding = "DB"
# database_name = "my-database"
# database_id = ""
# [ai]
# binding = "AI"
We need to create a wrangler.toml file in the root directory and define the name of our Cloudflare Worker in it. Just copy the code below and change the values accordingly:
Last but not least, we need to set a command for deploying our app.
"deploy": "wrangler deploy --minify src/index.ts"
You can place this code to the package.json file (scripts scope).
And we are done!!! Lets deploy our Elysia app
bun run deploy
If this is your first time using Wrangler, it’ll probably ask you for authentication. Just follow the instructions, and you’re good to go!
Here is the live version : https://elysia-bun.merto.workers.dev/pokemon/snorlax
Here is the github repo: https://github.com/mertthesamael/elysia-cf-worker
Here is my Website: https://www.merto.dev/
Until next time!
Do not forget to drink at least 2L of water/day.