DEV Community

Zaqueu Nilton
Zaqueu Nilton

Posted on

Beyond Containers: Building Globally Distributed APIs with Bun, Elysia, and Turso.

I love performance. If you, just like me, love it as well and want to leverage your application with blazing performance, today I bring a new approach to guide you through the process of understanding the Cloudflare Workers Universe.

First of all, I would like to justify the stack.

Bun is 17x faster than pnpm, 29x faster than npm and 33x faster than yarn

It is a complete runtime environment for the performance addicted.
ElysiaJS is a backend stack built on Bun, and focuses on a very smooth developer experience. It is just cozy to build with it and my backend just gets faster than any Express around the globe.

Turso is an blazing fast SQLite revival, focused on low latency and performance.

Cloudflare workers is something I have discovered recently, and has since been my go-to when it comes to deploying a server or front-end applications.
Unlike Railway or Render which put your code to sleep and brings the user to your code, Cloudflare workers bring the code to your user, since it has thousands of servers around the world.

Said that, I would like to introduce you to Cloudflare workers, since I have not seen any detailed documentation on how to do it on this context.

Now, you will have to set up your backend with ElysiaJS and your database with Turso. Once done that, there are a few things to configure before deploying your server.

1. Install Wrangler

What on earth is it? The name is scary but it works just as cozy.
It is the CLI tool that you use to deploy your server.
Run this:
bun add -g wrangler

2. Configure your wrangler.toml

This file is the heart of your deployment. It tells Cloudflare who you are and what resources your app needs. Create a wrangler.toml in your server root:

name = "my-awesome-api"
main = "src/index.ts"
compatibility_date = "2026-01-29"
compatibility_flags = [ "nodejs_compat" ]

[vars]
DATABASE_URL = "libsql://your-db-name.turso.io"
# Note: Use 'wrangler secret put AUTH_TOKEN' for your database token!

Enter fullscreen mode Exit fullscreen mode

3. The "No-Eval" Rule: Disabling AOT

Elysia is incredibly fast because it uses AOT (Ahead-of-Time compilation) to generate optimized code. However, Cloudflare Workers has a strict security policy that disallows generating code from strings (no eval or new Function()).

To make it work, simply pass aot: false to your Elysia constructor. Don't worry, it's still faster than most frameworks out there!

const app = new Elysia({ aot: false })
Enter fullscreen mode Exit fullscreen mode

4. Respect the Global Scope (The Snapshot Rule)

This is where most devs get stuck. Cloudflare Workers use V8 Isolates. They take a "snapshot" of your code's memory to make it boot in under 5ms.

Because of this, you cannot open a database connection in the global scope (at the top of your file). If you do, the deploy will fail because you can't "take a photo" of a live network connection.

The Solution? Lazy Initialization. Create a function that only connects to the database when a request actually hits your server:

// db.ts
export const getDb = (env: Env) => {
  const client = createClient({
    url: env.DATABASE_URL,
    authToken: env.AUTH_TOKEN,
  });
  return drizzle(client);
};
Enter fullscreen mode Exit fullscreen mode

5. Exporting for the Edge

Forget app.listen(3000). In the Workers universe, Cloudflare is the one in charge. You need to export your app so Cloudflare can call its fetch handler whenever a user knocks on your door.

instead of export default app, do this:

export default {
  fetch: (request: Request) => {
    return app.fetch(request);
  },
};
Enter fullscreen mode Exit fullscreen mode

This way, Cloudflare will pass the url through the fetch function of ElysiaJS and ✨

6. Forget .env

As mentioned earlier, you can put your environment variables in your wrangler.toml. If you did that, you can do wrangler types and it will generate a file called "worker-configuration.d.ts". This file contains what Typescript needs to stop screaming at you.

Abstract: You won't use process.env anymore. Instead, do this:

import { env } from "cloudflare:workers";
Enter fullscreen mode Exit fullscreen mode

But with a detail... your tsconfig.json, wherever you import it, has to include this:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "bundler", // Crucial para pacotes que usam subcaminhos como /cloudflare
    "strict": true,
    "skipLibCheck": true,
    "noEmit": true,
    "types": ["@cloudflare/workers-types"]
  },
  "include": ["index.ts", "..path/to/your/worker-configuration.d.ts"]
}
Enter fullscreen mode Exit fullscreen mode

7. The Grand Finale: Deployment

Now, the magic moment. Run the following command and watch your code being replicated to over 300 cities across the globe:

bunx wrangler deploy

Within seconds, you'll receive a .workers.dev URL. Congratulations! You just deployed a globally distributed, performance-addicted backend.

Conclusion

Building on the Edge is not just about speed; it's about a smarter way to handle resources. By using Bun, Elysia, and Turso inside Cloudflare Workers, you are skipping the heavy "cold starts" of Docker containers and bringing your data as close to your user as possible.

It's cozy, it's fast, and it's the future of the web. 🚀

Top comments (0)