synthkernel
npx machina-cli add skill hesprs/synthkernel/skill --openclawAbout SynthKernel
SynthKernel is a TypeScript software architecture that helps you write efficient, clean and modular code.
Typical practice of SynthKernel consists a module loader class and module classes:
- The module loader class manages module lifecycles, orchestrates types, and behaves as an facade at the surface of your app logic.
- All module classes extend a
BaseModuleclass, they define APIs, execute actual logic, augment the loader class and wire each other via dependency injection. - Types are resolved via generics orchestration.
- Modules are composed to the loader to form an APP. A module loader can also be a module of a parent loader.
- It is applicable to almost all use cases, including but not limited to backend service, complex automation, CLI application, and canvas rendering engine.
File System Conventions
SynthKernel should be structured in a tree pattern.
A loader together with the base module and all its direct modules should be placed flatly in one folder:
- the file accommodating the loader should be named
index.ts - base module named
BaseModule.ts - types named
types.ts - all modules are named
(module name in PascalCase).ts - no restriction to the name of other files
It's a standard practice to turn a over-bloated module into a new loader-module structure, then simply turn the module into a folder with the same requirements above.
When to Use
- At the early stage of development, when you have clues of logic yet haven't written any code.
- You don't have a clear architecture convention.
- During refactors when you aim to split some large modules or make the project modular.
- You are adding new functionalities and considering to make a new module, wanting to understand SynthKernel.
When Not to Use
- You are not supposed to create or change the architecture.
- You are developing web UI which has its own conventions.
- You are serving for a simple project (loc < 200) where a classical monolith is more convenient.
Actions
- If you are implementing SynthKernel from scratch or refactoring existing code to adopt SynthKernel, go to start.
- If you are adding a new module or splitting modules, go to maintenance.
- You can find an example of standard practice in ./example.
Overview
SynthKernel provides a TypeScript architecture for building efficient, clean and modular code. It centers on a module loader, a BaseModule, and dependency injection to compose modules into a cohesive APP using generics for type resolution.
How This Skill Works
A module loader manages lifecycles and acts as the surface facade of your app logic. Each module extends the BaseModule, defines APIs, executes logic, augments the loader, and wires dependencies via DI. Types are resolved through generics, and modules are composed into the loader to form an APP, with the possibility of a loader acting as a module of a parent loader.
When to Use It
- At the early stage of development when you have clues of logic yet haven't written any code.
- You don't have a clear architecture convention.
- During refactors when you aim to split some large modules or make the project modular.
- You are adding new functionalities and considering to make a new module, wanting to understand SynthKernel.
- Planning or building a backend service, complex automation, CLI tool, or canvas rendering engine as a modular monolith.
Quick Start
- Step 1: Create a folder structured per conventions (index.ts for the loader, BaseModule.ts, types.ts, and (ModuleName).ts files).
- Step 2: Implement a Loader class and extend BaseModule in each module to define APIs and logic.
- Step 3: Wire modules together via dependency injection and rely on generics to resolve cross-module types; assemble modules into the loader to form the APP.
Best Practices
- Follow the file system conventions: place the loader, BaseModule, and direct modules in a single folder with index.ts for the loader and BaseModule.ts for the base class.
- Keep dependencies loosely coupled by wiring modules through dependency injection rather than direct instantiation.
- Leverage generics to resolve cross-module types instead of ad-hoc casts or manual type plumbing.
- Refactor bloated modules by turning them into a new loader-module structure, then move to a folder with the required naming conventions.
- Use the loader as the central orchestrator to surface app logic while keeping each module focused on a single API.
Example Use Cases
- A backend service implemented as a modular monolith where services are split into modules wired by a central loader.
- A complex automation workflow system where each automation step is a module and the loader sequences them.
- A CLI tool composed of modular commands, each as a BaseModule with DI-managed dependencies.
- A canvas rendering engine where rendering modules plug into a loader to orchestrate rendering passes.
- A multi-tenant data processing pipeline built from modular components that share a loader for lifecycle management.