Ordinary async code.One clear application.
Compose TypeScript services with explicit plugin dependencies and one shared lifecycle. Start on Bun. Add only what your application needs.
Open source on GitHubA small application. A real lifecycle.
app.tsimport { defineApp, definePlugin, startApp } from "@lenso/core";
const notes = definePlugin({
id: "notes",
setup() {
return {
async list() {
return [];
},
};
},
});
const app = await startApp(defineApp({ plugins: [notes] }));
try {
console.log(await app.get(notes).list());
} finally {
await app.stop();
}- 01Define a service
Plain objects. Ordinary async methods.
- 02Compose explicitly
Each plugin declares its exact dependencies.
- 03Own the lifecycle
Initialize once. Release resources in reverse order.
This example uses the published @lenso/core@0.2.0 API.
Add capabilities. Keep your choices.
Use the plugins your application needs. Keep the underlying services and platform boundaries visible.
Web & Fetch
Typed procedures or native requests. Choose the boundary.
Auth
Identity and sessions. Your application owns authorization.
Drizzle & databases
Multiple database instances, with migrations you control.
Files & storage
Separate file records from object storage ownership.
Tasks
Background work with explicit queue and worker lifecycles.
Logs & telemetry
Application logging and platform-aware observability.
Plugin guides use the verified TypeScript 0.2 package matrix. Check compatibility before choosing packages.
Bun first.
Run regular async services locally. Inspect, call, develop, and build with the Lenso CLI.
Bun deploymentWorkers, deliberately.
Use the Workers adapter with request-scoped platform bindings. Understand the runtime and resource limits before deploying.
Workers guide