Type-safe module composable.
Compose modules like building blocks, nest them, and share them across projects. Clean, simple, type safe and scalable.
Quick Start
import start, { defineModule, type ContextOf, type ContextWriterOf, type SetOf } from "tsdkarc"; // interface ConfigSlice { // config: { port: number }; // } // const configModule = defineModule<ConfigSlice>()({ const configModule = defineModule()({ name: "config", boot: () => ({ config: { port: 3000, }, }), }); // Get the module's context type(include the dependencies modules) export type ConfigModuleCtx = ContextOf<typeof configModule>; // same as `ConfigSlice` // Get the `set` type of the module type ConfigModuleSet = ContextWriterOf<typeof configModule>["set"]; // or type ConfigModuleSet2 = SetOf<typeof configModule> function test(set: ConfigModuleSet) { // type safe here set("config", { port: 200 }); } interface ServerSlice { server: { listen: () => void }; } const serverModule = defineModule<ServerSlice>()({ name: "server", modules: [configModule] as const, // ๐ Declares dependency boot(ctx) { return { server: { listen: () => { console.log(`Running on ${ctx.config.port}`); // ๐ Fully typed }, }, }; // Or: /* ctx.set("server", { listen: () => { console.log(`Running on ${ctx.config.port}`); // ๐ Fully typed }, }); */ }, }); // Launch ๐ const app = await start([serverModule], { afterBoot() { console.log("The app is running"); }, onError(error, ctx, mod) { console.log(`${mod.name} error`, error.message); // throw error; }, }); app.ctx.server.listen(); // Running on 3000
Why TsdkArc?
Fully Type-Safe Context
The merged union of all slices is fully typed at each module's boundary. Autocomplete works exactly as you'd expect, everywhere.
Auto Resolution
Declare your dependencies. start() resolves the graph.
Composable
Build small modules. Complex wiring becomes just a simple chain.
Robust Lifecycle
Granular control over setup and teardown. From beforeBoot to afterShutdown.
Ideal Use Cases
Bun / Node.js Custom Frameworks
Wire up config, databases, caches, HTTP servers and Business modules in the exact right order without brittle, manual setup.
Shared Library Modules
Publish reusable infrastructure (like logging or auth or others business modules) that other projects can drop in effortlessly.
Background Workers
Safely orchestrate queue consumers and cron jobs, ensuring automatic resource cleanup via shutdown hooks.
Isolated Testing
Swap out a real database module for an in-memory mock simply by replacing a single dependency.
What it is NOT
A Web Framework
No routing, no HTTP handling, no middleware pipeline (though you can register those as context values).
A Runtime DI Container
No decorators, no reflection. Dependencies are declared statically at definition time.
A State Management Library
The context is boot-time wiring, not reactive application state (not Redux, Zustand, etc.).
A Task Runner / Build Tool
Not a replacement for task runners or build tools like Grunt, Gulp, or Make.
A Process Manager
Not a replacement for process managers like PM2, Docker, or systemd.
An ORM or Data Layer
It can hold a DB pool, but it knows absolutely nothing about databases itself.
A Config Loader
You bring your own config reading logic; it just helps you share it safely across modules.
