npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mariodebono/di-config

v3.4.0

Published

DI system configuration module

Readme

@mariodebono/di-config

Typed configuration module for applications built on @mariodebono/di.

This package provides a DI-friendly configuration system with synchronous and async root setup, namespaced config slices, typed injection tokens, validation, and dot-path lookups through ConfigService.

Install

npm install @mariodebono/di-config @mariodebono/di reflect-metadata

Requirements

  • Node.js 24 or newer
  • @mariodebono/di as a peer dependency
  • reflect-metadata loaded before decorated classes are imported or instantiated
  • The same ESM and decorator setup required by @mariodebono/di

This package publishes ESM .mjs files and .d.mts declarations. CommonJS require() is not a supported entry point.

What It Solves

  • Bootstraps application config from defaults, process.env, factories, and injected providers
  • Provides named config slices with registerAs()
  • Makes config values injectable through DI tokens
  • Supports typed dot-path reads through ConfigService
  • Allows validation or transformation at module startup

Root Configuration

Use ConfigModule.forRoot() to assemble application config.

import { Module } from "@mariodebono/di";
import { ConfigModule } from "@mariodebono/di-config";

@Module({
    imports: [
        ConfigModule.forRoot({
            defaults: {
                appName: "Desktop App",
            },
            load: [
                () => ({
                    appVersion: "1.0.0",
                }),
            ],
            isGlobal: true,
        }),
    ],
})
class AppModule {}

ConfigModule.forRoot() merges defaults, process.env by default, and each load factory before the module is initialized.

Root options:

  • loadProcessEnv?: boolean controls whether process.env is merged, defaulting to true
  • ignoreEnvVars?: boolean is an alias for disabling environment loading
  • defaults?: Record<string, unknown> supplies baseline values
  • load?: ConfigFactory[] adds factory-produced values
  • validate?: (config) => TConfig transforms or validates the final object
  • validationSchema?: ValidationSchema<TConfig> supports parse(), safeParse(), or Joi-style validate()
  • validationOptions?: Record<string, unknown> passes options to Joi-style schemas
  • cache?: boolean caches computed lookups, defaulting to true
  • isGlobal?: boolean makes config providers globally visible

Async Root Setup

Use ConfigModule.forRootAsync() when config depends on other providers.

import { Injectable, Module } from "@mariodebono/di";
import { ConfigModule } from "@mariodebono/di-config";

@Injectable()
class SettingsProvider {
    getAppVersion(): string {
        return "1.0.0";
    }
}

@Module({
    providers: [SettingsProvider],
    exports: [SettingsProvider],
})
class SettingsModule {}

@Module({
    imports: [
        SettingsModule,
        ConfigModule.forRootAsync({
            imports: [SettingsModule],
            inject: [SettingsProvider],
            useFactory: async (settings: SettingsProvider) => ({
                load: [
                    () => ({
                        appVersion: settings.getAppVersion(),
                    }),
                ],
            }),
        }),
    ],
})
class AppModule {}

Namespaced Config

Use registerAs() to define a namespaced slice. The returned KEY supports path lookups, while the returned TOKEN supports DI injection.

import { Inject, Injectable, Module } from "@mariodebono/di";
import { ConfigModule, ConfigType, registerAs } from "@mariodebono/di-config";

const databaseConfig = registerAs("database", () => ({
    url: "file:./app.db",
    pool: {
        maxConnections: 10,
    },
}));

@Injectable()
class DatabaseClient {
    constructor(
        @Inject(databaseConfig.TOKEN)
        readonly database: ConfigType<typeof databaseConfig>,
    ) {}
}

@Module({
    imports: [
        ConfigModule.forRoot({
            load: [databaseConfig],
        }),
        ConfigModule.forFeature([databaseConfig]),
    ],
    providers: [DatabaseClient],
})
class AppModule {}

ConfigModule.forFeature() should be used only after a root config module has been imported somewhere in the application graph.

ConfigService

ConfigService supports top-level keys and nested dot-path access with typed return values.

import { ConfigService } from "@mariodebono/di-config";

type AppConfig = {
    database: {
        url: string;
        pool: {
            maxConnections: number;
        };
    };
};

declare const configService: ConfigService<AppConfig>;

const url = configService.getOrThrow("database.url");
const maxConnections = configService.get("database.pool.maxConnections");

With a typed ConfigService<AppConfig>, url resolves as string and maxConnections as number | undefined.

Common methods:

  • get(path, options?) returns the value or undefined
  • getOrThrow(path, options?) throws when the path is missing
  • getAll() returns the assembled config object

Validation

Root config can be transformed or validated with a custom validate() function or a schema object that exposes parse(), safeParse(), or Joi-style validate().

The custom validate callback takes priority. For schemas, safeParse() is preferred, followed by parse(), then Joi-style validate(). This supports Zod schemas that also expose a boolean-returning validate() method while preserving parsed values, defaults and transforms. Validation failures are thrown during configuration loading.

ConfigModule.forRoot({
    load: [databaseConfig],
    validate: (config) => {
        if (typeof config.database !== "object" || config.database === null) {
            throw new Error("database config is required");
        }

        return config as {
            database: {
                url: string;
            };
        };
    },
});

Notes

  • The package does not load .env files for you. Use your preferred dotenv loader before bootstrapping the app if needed.
  • Environment variables are merged as top-level keys from process.env.
  • ConfigService is intended for application code that needs typed access to the assembled config graph.

Public API

  • ConfigModule
  • ConfigService
  • registerAs()
  • CONFIG_OPTIONS_TOKEN
  • ConfigType
  • ConfigFactory
  • ConfigFactoryKeyHost
  • ConfigModuleOptions
  • ConfigModuleAsyncOptions
  • ConfigServiceOptions
  • ConfigGetOptions
  • ValidationSchema
  • ConfigPath and ConfigPathValue

Changelog

See CHANGELOG.md.

License

This package is licensed under MPL-2.0.