Introduction

Teasim is a microkernel, plug-in based web framework.

Pronounce as /ˈtiː.sɪm/

Building on top of 3 philosophies:

  • Performance
    • You shall not worry about the underlying performance
  • Simplicity
    • Simple building blocks to create an abstraction, not repeating yourself
  • Flexibility
    • You shall be able to customize most of the library to fit your need

Designed with TypeScript in mind, you don't need to understand TypeScript to take advantage of Teasim. The library understands what you want and automatically infers the type from your code.

Take a look at this:

new Teasim().get("/id/:id", ({ params: { id } }) => id).listen(8080);

Teasim understands that you want a path parameter name id. The library then registers id as a type in params.


You can define a custom type for many things, for example, an incoming request's body.

import { Teasim, t } from "teasim";

new Teasim()
  .post("/sign-in", ({ body }) => signIn(body), {
    body: t.Object({
      username: t.String(),
      password: t.String(),
    }),
  })
  .listen(8080);

You explicitly tell Teasim that the incoming request body is expected to have a structure as you define it.

Teasim then infers the type from the code you write. Validate the body from the incoming request to ensure the type safety.

Then with plugins, Teasim can instantly generate API documentation with Swagger with a single line of code.

import { Teasim, t } from "teasim";
/* [!code ++] */ import { swagger } from "@teasim/swagger";

new Teasim()
  /* [!code ++] */ .use(swagger())
  .post("/sign-in", ({ body }) => signIn(body), {
    body: t.Object({
      username: t.String(),
      password: t.String(),
    }),
  })
  .listen(8080);

And finally, you can create a fully type-safe client for consuming Teasim API with Eden (optional).

// server.ts
import { Teasim, t } from "teasim";
import { swagger } from "@teasim/swagger";

/* [!code ++] */ const app = new Teasim()
  .use(swagger())
  .post("/sign-in", ({ body }) => signIn(body), {
    body: t.Object({
      username: t.String(),
      password: t.String(),
    }),
  })
  .listen(8080);

/* [!code ++] */ export type App = typeof app;

And on the client:

// client.ts
import { edenTreaty } from "@teasim/eden";
import type { App } from "./server";

const app = edenTreaty<App>("http://localhost:8080");

app.signIn
  .post({
    username: "teasim",
    password: 12345678,
  })
  .then(console.log);

Creating a single source of truth for your data structure, eliminating any possible type conflict between TypeScript, actual requests via validation, API documentation, and frontend client.

Ensure that nothing went wrong in development, migration, and production.