KOIN - Kotlin simple Dependency Injection Framework for JavaScript/Browser platform
npx @tessl/cli install tessl/maven-io-insert-koin--koin-core-js@4.1.0Koin is a pragmatic lightweight dependency injection framework for Kotlin Multiplatform projects. This JavaScript implementation provides a complete DI container with DSL-based configuration, scoped instances, lazy injection, and module organization designed specifically for web applications, browser extensions, and Node.js services.
For Kotlin Multiplatform JavaScript target, imports depend on your build configuration:
// ES6 modules (if configured in your Gradle build)
import {
startKoin,
koinApplication,
module,
KoinComponent,
GlobalContext
} from "io.insert-koin.koin-core";// CommonJS (Node.js style)
const {
startKoin,
koinApplication,
module,
KoinComponent,
GlobalContext
} = require("io.insert-koin.koin-core");Note: Actual import paths may vary based on your Kotlin Multiplatform build configuration and JavaScript module system setup.
import { startKoin, koinApplication, module, named } from "io.insert-koin.koin-core";
// Define a module with dependencies
const appModule = module(false, (module) => {
// Singleton instance - created once and reused
module.single(null, false, () => new DatabaseService("localhost:5432"));
// Factory instance - new instance every time
module.factory(null, () => new ApiClient());
// Scoped instance - tied to scope lifecycle
module.scope(named("session"), (scope) => {
scope.scoped(null, () => new UserSession());
});
});
// Start Koin application
startKoin((app) => {
app.modules([appModule]);
app.printLogger();
});
// Or create application first, then start
const app = koinApplication(true, (koinApp) => {
koinApp.modules([appModule]);
koinApp.printLogger();
});
startKoin(app);Koin Core is built around several key architectural components:
KoinApplication manages the overall DI configuration and lifecycleKoin class provides runtime dependency resolution and instance managementModule classes organize related dependency definitions using a fluent DSLScope instances manage lifecycle and cleanup of scoped dependenciesKoinComponent interface provides injection capabilities to classesCore application setup functionality for initializing the Koin container, loading modules, and configuring logging.
/**
* Create a new Koin application with configuration
* @param createEagerInstances - Whether to create eager instances (default: true)
* @param appDeclaration - Application configuration function
* @returns KoinApplication instance
*/
function koinApplication(createEagerInstances?: boolean, appDeclaration?: KoinAppDeclaration): KoinApplication;
function koinApplication(appDeclaration?: KoinAppDeclaration): KoinApplication;
function koinApplication(configuration?: KoinConfiguration): KoinApplication;
/**
* Start Koin globally with application or configuration
* @param koinApplication - Pre-configured KoinApplication instance
* @returns KoinApplication instance
*/
function startKoin(koinApplication: KoinApplication): KoinApplication;
function startKoin(appDeclaration: KoinAppDeclaration): KoinApplication;
function startKoin(appConfiguration: KoinConfiguration): KoinApplication;
/**
* Stop the global Koin instance and cleanup resources
*/
function stopKoin(): void;
/**
* Load additional modules into the global Koin instance
*/
function loadKoinModules(module: Module): void;
function loadKoinModules(modules: Module[]): void;
/**
* Unload modules from the global Koin instance
*/
function unloadKoinModules(module: Module): void;
function unloadKoinModules(modules: Module[]): void;
class KoinApplication {
/** Load dependency modules into the application */
modules(modules: Module): KoinApplication;
modules(...modules: Module[]): KoinApplication;
modules(modules: Module[]): KoinApplication;
/** Set application properties */
properties(values: Map<string, any>): KoinApplication;
/** Set application options */
options(...optionValue: [KoinOption, any][]): KoinApplication;
/** Configure logging with custom logger */
logger(logger: Logger): KoinApplication;
/** Use default console logger */
printLogger(level?: Level): KoinApplication;
/** Allow definition override */
allowOverride(override: boolean): void;
/** Create eager instances */
createEagerInstances(): void;
/** Close the application and cleanup resources */
close(): void;
/** Get the underlying Koin container */
readonly koin: Koin;
}Module definition DSL for organizing and declaring dependencies with singletons, factories, and scoped instances.
/**
* Define a module with dependency definitions
* @param createdAtStart - Whether to create instances immediately (default: false)
* @param moduleDeclaration - Module configuration function
* @returns Module instance
*/
function module(
createdAtStart?: boolean,
moduleDeclaration: ModuleDeclaration
): Module;
function module(moduleDeclaration: ModuleDeclaration): Module;
/**
* Create a Koin configuration
* @param declaration - Configuration function
* @returns KoinConfiguration instance
*/
function koinConfiguration(declaration: KoinAppDeclaration): KoinConfiguration;
class Module {
/** Module unique identifier */
readonly id: string;
/** Whether module is loaded */
readonly isLoaded: boolean;
/** Define singleton instance - created once and reused */
single<T>(qualifier?: Qualifier, createdAtStart?: boolean, definition: Definition<T>): KoinDefinition<T>;
/** Define factory instance - new instance every request */
factory<T>(qualifier?: Qualifier, definition: Definition<T>): KoinDefinition<T>;
/** Define scoped instances within named scope */
scope(qualifier: Qualifier, scopeSet: (scopeDSL: ScopeDSL) => void): void;
scope<T>(scopeSet: (scopeDSL: ScopeDSL) => void): void;
/** Include other modules */
includes(...modules: Module[]): void;
includes(modules: Module[]): void;
/** Module composition operators */
plus(module: Module): Module[];
plus(modules: Module[]): Module[];
}Core dependency injection functionality for retrieving instances, lazy injection, and parameter passing.
class Koin {
/** Get instance of type T */
get<T>(qualifier?: Qualifier, parameters?: ParametersDefinition): T;
get<T>(clazz: any, qualifier?: Qualifier, parameters?: ParametersDefinition): T;
/** Get instance or null if not found */
getOrNull<T>(qualifier?: Qualifier, parameters?: ParametersDefinition): T | null;
getOrNull<T>(clazz: any, qualifier?: Qualifier, parameters?: ParametersDefinition): T | null;
/** Lazy injection - resolved on first access */
inject<T>(qualifier?: Qualifier, mode?: LazyThreadSafetyMode, parameters?: ParametersDefinition): Lazy<T>;
/** Lazy injection that can return null */
injectOrNull<T>(qualifier?: Qualifier, mode?: LazyThreadSafetyMode, parameters?: ParametersDefinition): Lazy<T | null>;
/** Get all instances of type T */
getAll<T>(): T[];
/** Declare existing instance in container */
declare<T>(instance: T, qualifier?: Qualifier, secondaryTypes?: any[], allowOverride?: boolean): void;
/** Create new scope */
createScope(scopeId: ScopeID, qualifier: Qualifier, source?: any, scopeArchetype?: TypeQualifier): Scope;
createScope<T>(scopeId: ScopeID, source?: any, scopeArchetype?: TypeQualifier): Scope;
createScope<T>(scopeId?: ScopeID): Scope;
/** Get existing scope */
getScope(scopeId: ScopeID): Scope;
getScopeOrNull(scopeId: ScopeID): Scope | null;
/** Delete scope */
deleteScope(scopeId: ScopeID): void;
/** Property management */
getProperty<T>(key: string, defaultValue: T): T;
getProperty<T>(key: string): T | null;
setProperty(key: string, value: any): void;
deleteProperty(key: string): void;
/** Module management */
loadModules(modules: Module[], allowOverride?: boolean, createEagerInstances?: boolean): void;
unloadModules(modules: Module[]): void;
createEagerInstances(): void;
/** Close and cleanup */
close(): void;
}
interface KoinComponent {
/** Get the Koin container instance */
getKoin(): Koin;
}
// KoinComponent extension functions available globally
function get<T>(component: KoinComponent, qualifier?: Qualifier, parameters?: ParametersDefinition): T;
function inject<T>(component: KoinComponent, qualifier?: Qualifier, mode?: LazyThreadSafetyMode, parameters?: ParametersDefinition): Lazy<T>;Scoped dependency management for controlling instance lifecycle and cleanup within defined boundaries.
class Scope {
/** Scope qualifier */
readonly scopeQualifier: Qualifier;
/** Scope ID */
readonly id: ScopeID;
/** Whether this is a root scope */
readonly isRoot: boolean;
/** Whether scope is closed */
readonly closed: boolean;
/** Get scoped instance */
get<T>(qualifier?: Qualifier, parameters?: ParametersDefinition): T;
getOrNull<T>(qualifier?: Qualifier, parameters?: ParametersDefinition): T | null;
getAll<T>(): T[];
/** Lazy inject from scope */
inject<T>(qualifier?: Qualifier, mode?: LazyThreadSafetyMode, parameters?: ParametersDefinition): Lazy<T>;
injectOrNull<T>(qualifier?: Qualifier, mode?: LazyThreadSafetyMode, parameters?: ParametersDefinition): Lazy<T | null>;
/** Link to parent scopes for dependency resolution */
linkTo(...scopes: Scope[]): void;
unlink(...scopes: Scope[]): void;
/** Close scope and cleanup instances */
close(): void;
/** Declare instance in scope */
declare<T>(instance: T, qualifier?: Qualifier, secondaryTypes?: any[], allowOverride?: boolean, holdInstance?: boolean): void;
/** Property access */
getProperty<T>(key: string, defaultValue: T): T;
getPropertyOrNull<T>(key: string): T | null;
getProperty<T>(key: string): T;
/** Register lifecycle callback */
registerCallback(callback: ScopeCallback): void;
}
interface KoinScopeComponent extends KoinComponent {
/** Current scope instance */
readonly scope: Scope;
}
// KoinScopeComponent extension functions
function getScopeId<T>(component: T): string;
function getScopeName<T>(component: T): TypeQualifier;
function createScope<T extends KoinScopeComponent>(component: T, scopeId?: ScopeID, source?: any, scopeArchetype?: TypeQualifier): Scope;
function getScopeOrNull<T extends KoinScopeComponent>(component: T): Scope | null;
function newScope<T extends KoinScopeComponent>(component: T): Lazy<Scope>;
function getOrCreateScope<T extends KoinScopeComponent>(component: T): Lazy<Scope>;Type-safe dependency identification and parameter injection for complex dependency graphs.
interface Qualifier {
/** Qualifier value for identification */
value: any;
}
/**
* Create named qualifier for dependency identification
* @param name - Qualifier name
* @returns Qualifier instance
*/
function named(name: string): Qualifier;
/**
* Create type-based qualifier
* @returns Qualifier instance
*/
function named<T>(): Qualifier;
class ParametersHolder {
/** Get parameter by index and type */
elementAt<T>(index: number): T;
/** Get parameter by type */
get<T>(): T;
/** Check if parameters exist */
isEmpty(): boolean;
/** Parameter count */
size(): number;
}
/**
* Create parameters for injection
* @param parameters - Parameter values
* @returns ParametersHolder instance
*/
function parametersOf(...parameters: any[]): ParametersHolder;Application-wide context management for accessing the DI container across your application.
interface KoinContext {
/** Get current Koin instance */
get(): Koin | null;
/** Start Koin with application */
startKoin(application: KoinApplication): KoinApplication;
/** Stop Koin and cleanup */
stopKoin(): void;
/** Load additional modules */
loadKoinModules(modules: Module[]): void;
/** Unload modules */
unloadKoinModules(modules: Module[]): void;
}
/** Global context singleton for JavaScript */
const GlobalContext: KoinContext;Comprehensive error handling with specific exception types for different failure scenarios.
class NoDefinitionFoundException extends Error {
/** Definition not found during resolution */
}
class InstanceCreationException extends Error {
/** Error during instance creation */
}
class ClosedScopeException extends Error {
/** Attempt to use closed scope */
}
class ScopeNotCreatedException extends Error {
/** Scope doesn't exist */
}
class ScopeAlreadyCreatedException extends Error {
/** Attempting to create an already existing scope */
}
class KoinApplicationAlreadyStartedException extends Error {
/** Attempting to start Koin when already started */
}
class DefinitionOverrideException extends Error {
/** Definition override conflict */
}
class DefinitionParameterException extends Error {
/** Parameter-related definition issues */
}
class MissingScopeValueException extends Error {
/** Missing value in scope */
}
class MissingPropertyException extends Error {
/** Property not found */
}
class NoPropertyFileFoundException extends Error {
/** Property file not found */
}
class NoParameterFoundException extends Error {
/** Parameter not found */
}
class NoScopeDefFoundException extends Error {
/** Scope definition not found */
}Configurable logging system with multiple levels and JavaScript console integration.
abstract class Logger {
/** Display log message */
abstract display(level: Level, message: string): void;
/** Debug level logging */
debug(message: string): void;
/** Info level logging */
info(message: string): void;
/** Warning level logging */
warn(message: string): void;
/** Error level logging */
error(message: string): void;
}
enum Level {
DEBUG = "DEBUG",
INFO = "INFO",
WARNING = "WARNING",
ERROR = "ERROR",
NONE = "NONE"
}
/** Console-based logger for JavaScript environments */
class PrintLogger extends Logger {
display(level: Level, message: string): void;
}/** Function type for module declarations */
type ModuleDeclaration = (module: Module) => void;
/** Function type for dependency definitions */
type Definition<T> = (scope: Scope, parameters: ParametersHolder) => T;
/** Function type for parameter definitions */
type ParametersDefinition = () => ParametersHolder;
/** Function type for application configuration */
type KoinAppDeclaration = (app: KoinApplication) => void;
/** Koin configuration type */
interface KoinConfiguration {
invoke(): KoinAppDeclaration;
}
/** Scope identifier type */
type ScopeID = string;
/** Qualifier value type */
type QualifierValue = any;
/** Type qualifier interface */
interface TypeQualifier extends Qualifier {
/** Type-based qualifier */
}
/** Message type for logging */
type MESSAGE = string | (() => string);
/** Koin option enumeration */
enum KoinOption {
// Koin configuration options
}
/** Lazy thread safety modes */
enum LazyThreadSafetyMode {
SYNCHRONIZED,
PUBLICATION,
NONE
}
/** Lazy wrapper for dependency injection */
interface Lazy<T> {
/** Get the lazily resolved value */
readonly value: T;
}
/** Bean definition with binding and lifecycle options */
interface KoinDefinition<T> {
/** Bind additional compatible types */
bind<S>(): KoinDefinition<T>;
/** Add cleanup callback */
onClose(callback: (instance: T) => void): KoinDefinition<T>;
}
/** Scope DSL for defining scoped dependencies */
class ScopeDSL {
/** Scope qualifier */
readonly scopeQualifier: Qualifier;
/** Associated module */
readonly module: Module;
/** Define scoped instance */
scoped<T>(qualifier?: Qualifier, definition: Definition<T>): KoinDefinition<T>;
/** Define factory instance in scope */
factory<T>(qualifier?: Qualifier, definition: Definition<T>): KoinDefinition<T>;
}
/** Scope lifecycle callback interface */
interface ScopeCallback {
/** Called when scope is closed */
onScopeClose(scope: Scope): void;
}