Runtimes
Kaito v3+ was designed to work with any runtime, including serverless runtimes like Cloudflare Workers or the Vercel Edge Runtime.
Bun
Bun is the runtime most suited for Kaito, as it has the fastest Request/Response server built in.
import {createKaitoHandler} from '@kaito-http/core';
const handle = createKaitoHandler({
// ...
});
const server = Bun.serve({
fetch: handle,
port: 3000,
});
console.log(`Listening at ${server.url}`);
Node.js
Node.js does NOT have a native Request/Response based HTTP server built in, so we built one ourselves! It’s based on uWebSockets.js
, which is a stupidly fast HTTP server written in C++ with Node.js bindings. It’s actually the same server that Bun uses, so it offers almost as good performance as Bun.
Installation
bun i @kaito-http/uws
To be super clear, @kaito-http/uws
works with Node.js only, we’re only using Bun as a package manager in the command above. You can use any other package manager like npm
or yarn
.
Usage
import {createKaitoHandler} from '@kaito-http/core';
import {KaitoServer} from '@kaito-http/uws';
const handle = createKaitoHandler({
// ...
});
const server = await KaitoServer.serve({
fetch: handle,
port: 3000,
});
console.log(`Listening at ${server.url}`);
Deno
Deno supports the Fetch API natively, so you can use Kaito with Deno without any extra work.
import {createKaitoHandler} from '@kaito-http/core';
const handle = createKaitoHandler({
// ...
});
const server = Deno.serve(
{
port: 3000,
},
handle,
);
console.log(`Listening on`, server.addr);
Cloudflare Workers
Cloudflare Workers supports the Fetch API natively, so you can use Kaito with Cloudflare Workers without any extra work.
import {createKaitoHandler} from '@kaito-http/core';
const handle = createKaitoHandler({
// ...
});
export default {
fetch: handle,
} satisfies ExportedHandler;
Environment variables
Cloudflare Workers passes environment variables to the handler function, which is a little awkward with Kaito. Our recommendation is to use AsyncLocalStorage to pass info between the handler and the router. This requires you to enable the node compatibility mode on your Cloudflare Worker.
import {AsyncLocalStorage} from 'node:async_hooks';
interface Env {
STRIPE_SECRET_KEY: string;
}
// Recommendation is to move the storage and getStore function to the context.ts file, and include the env in your context object.
const storage = new AsyncLocalStorage<{
env: Env;
cfCtx: ExecutionContext; // has .waitUntil() and .passThroughOnException()
}>();
const app = router().get('/', async ({ctx}) => {
return {
freeStripeKey: ctx.env.STRIPE_SECRET_KEY,
};
});
const handle = createKaitoHandler({
router: app,
getContext: async req => {
const store = storage.getStore()!;
return {env: store.env, cfCtx: store.cfCtx};
},
// ...
});
export default {
fetch: async (request, env, ctx) => storage.run({env, cfCtx: ctx}, () => handle(request)),
} satisfies ExportedHandler<Env>;