DEV Community

Zastinian
Zastinian

Posted on

The TypeScript Framework for APIs at Lightspeed ⚡

Introduction

Are you tired of the "validation gap" between your server and client? Are you fed up with writing complex integration tests for simple routes?

Meet Hedystia, a next-gen TypeScript framework designed for developers who value performance, type safety, and an elite developer experience. Built natively for Bun (but compatible with Node.js and Deno), Hedystia bridges the gap between your backend logic and your frontend consuming it.


🚀 The "Killer Feature": Built-in Route Testing

Most frameworks require you to spin up a separate testing suite and mock a bunch of dependencies just to test a simple endpoint. In Hedystia, testing is a first-class citizen of the route definition.

import { Hedystia, h } from "hedystia";

const app = new Hedystia()
  .get("/users/:id", ({ params }) => ({ id: params.id, name: "John" }), {
    params: h.object({ id: h.number().coerce() }),
    response: h.object({ id: h.number(), name: h.string() }),
    // Test right next to your code!
    test: async ({ createRequest, expect }) => {
      const { response, statusCode } = await createRequest({
        params: { id: 123 },
      });
      expect(statusCode).toBe(200);
      expect(response.id).toBe(123);
    },
  })
  .listen(3000);

// Run all route tests with a single command
const results = await app.runTests();
console.log(results.report);
Enter fullscreen mode Exit fullscreen mode

This isn't just a gimmick—it's a paradigm shift. Your documentation, implementation, and tests live together in harmony.


🔒 End-to-End Type Safety

Hedystia doesn't just "support" TypeScript; it embraces it. When you define a route, Hedystia infers the types for the body, query, params, and response.

Pair it with the @hedystia/client, and you get a fully-typed HTTP client with zero effort.

Server Side

.post("/users", (ctx) => { ... }, {
  body: h.object({
    email: h.string().email(),
    age: h.number()
  })
})
Enter fullscreen mode Exit fullscreen mode

Client Side (Autocompleted!)

import { createClient } from "@hedystia/client";

const client = createClient<typeof app>("http://localhost:3000");

// Fully typed! If you miss a field or use the wrong type, TypeScript will yell at you.
const { data, error } = await client.users.post({
  body: {
    email: "dev@hedystia.com",
    age: 26
  }
});
Enter fullscreen mode Exit fullscreen mode

🧩 Dynamic Routing with .if()

Need to toggle features or register routes based on environment variables or configuration? Hedystia's .if() method makes dynamic API design clean and intuitive.

const app = new Hedystia()
  .if((app) => {
    if (process.env.ENABLE_BETA_FEATURES) {
      return app.get("/beta", () => ({ status: "experimental" }));
    }
  })
  .listen(3000);
Enter fullscreen mode Exit fullscreen mode

📡 Real-Time WebSockets

Type safety shouldn't stop at REST. Hedystia provides a powerful, type-safe WebSocket implementation with a client that supports auto-reconnection and event-based handlers.

const app = new Hedystia()
  .ws("/chat", {
    message: (ws, message) => {
      ws.send(`Echo: ${message}`);
    },
  })
  .listen(3000);

// Client-side
client.chat.ws((ws) => {
  ws.onConnect(() => ws.send("Hello!"));
  ws.onMessage((msg) => console.log(msg));
});
Enter fullscreen mode Exit fullscreen mode

🌟 Why Use Hedystia?

  • Bun-Native Performance: Optimized for the fastest JS runtime.
  • Multi-Runtime: Works on Deno, Node.js, Cloudflare Workers, and more.
  • Validation Built-in: Uses a high-performance validation system compatible with Standard Schema (Zod, Arktype, etc.).
  • Framework-Agnostic Types: Use Hedystia's typing system even with Express, Hono, or Fastify.

Get Started Today

Hedystia is open-source and ready for you to build something amazing.

What do you think about built-in route testing? Let us know in the comments! 👇

Top comments (0)