Skip to content

Discussion draft: ConfigProvider to help with drop-ins.#300

Draft
rektide wants to merge 5 commits intounjs:mainfrom
rektide:provider
Draft

Discussion draft: ConfigProvider to help with drop-ins.#300
rektide wants to merge 5 commits intounjs:mainfrom
rektide:provider

Conversation

@rektide
Copy link

@rektide rektide commented Feb 10, 2026

Used Opus to try to work on something for #298. This takes the bespokely purposefully built loader.ts and creates a ConfigProvider that each configuration type provides. It then runs each ConfigProvider to produce the output.

The work here is deeply impactful to the architecture and needs much more attention & regard. It is provided now as an early draft, and as a baseline to show how drop-in might work, which is a further stacked draft-PR (to follow very shortly).

This draft is 1 of 2 PRs that could be done to implement drop-in config. rektide#1 shows the remainder of the work, with an implementation of a ConfigProvider that can do configDir. Also note: merging this PR would expose a providers option that I could use to implement drop-in configuration in my own library or app, without needing to add that code directly into c12.

Questions

  • Currently ConfigProvider#load is the only capability of a ConfigProvider right now. What if anything might we provide to support watchConfig too; provide a list of paths we want watched? There's nothing done for magicast support in this PR either; would we want some kind of updateConfig support in this PR?

rektide added 5 commits February 9, 2026 21:29
- doc/discovery/config-sourcing.md: Complete analysis of c12's configuration pipeline, showing how defu merges configs from multiple sources with mermaid diagrams
- doc/discovery/dynamic-configs.md: Exploration of dynamic configuration sources including drop-in directories, provider pattern design, and layering provenance
Refactors c12's config loading to use a provider-based architecture:

- Add ConfigProvider interface with name, priority, and load() method
- Built-in providers: overrides, main, rc, packageJson, defaultConfig
- Providers sorted by priority (lower = higher precedence)
- New options.providers allows custom/replacement providers
- Providers can access previously loaded configs via context
- Backward compatible: loadConfig() works unchanged without providers
- Exports: getDefaultProviders, sortProviders, create*Provider helpers

This enables users to:
- Inject custom config sources (env vars, remote config, vault)
- Reorder or remove default sources
- Build configs that depend on other loaded configs
Add comprehensive documentation for the implemented provider system:
- Architecture overview with mermaid diagram
- Core types (ConfigProvider, ProviderContext, ProviderResult)
- Built-in providers table
- Usage examples (custom, replacing, reordering, dependencies, remote)
- How the provider system works (step-by-step)
- Impact on existing c12 users (zero breaking changes)
- Minor differences noted (error message path resolution)
- Future enhancements roadmap
- Files changed summary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant