Make shared data available to multiple consumers without prop-drilling
When to Use
Multiple components or modules need the same data (theme, locale, current user, feature flags)
You want to avoid threading a value through every function parameter or component prop
You need to swap implementations (e.g., test vs production) by replacing the provider
Instructions
Create a context object or module-level store that holds the shared data.
Expose a provide(value) function to register the data and a consume() / inject() function to retrieve it.
Scope the provider — a module-level variable is global; a closure-based provider can be scoped to a subtree or request.
Document what the provider exposes — callers should not need to inspect internals to use it.
// Simple module-level provider
let _theme = 'light';
export function provideTheme(theme) {
_theme = theme;
}
export function useTheme() {
return _theme;
}
In framework code (React/Vue), use the framework's native context API — do not re-implement it.
Keep providers focused — one provider per concern (theme, auth, i18n), not one mega-provider.
Details
The Provider pattern is the plain-JavaScript equivalent of what React Context and Vue's provide/inject formalize. The core idea: establish a value at one level and make it available to any consumer below that level without explicit passing.
Trade-offs:
Module-level providers are singletons — hard to reset in tests
Implicit dependencies — consumers do not declare that they depend on the provider in their signature
No automatic re-rendering — plain JS providers do not trigger UI updates when the value changes (use a framework's reactive context for that)
When NOT to use:
When only 1–2 levels of nesting exist — passing props directly is clearer
When the data changes frequently and consumers need to react — use a reactive state management solution
Read the instructions and examples in this document.
Apply the patterns to your implementation, adapting to your specific context.
Verify your implementation against the details and edge cases listed above.
Harness Integration
Type: knowledge — this skill is a reference document, not a procedural workflow.
No tools or state — consumed as context by other skills and agents.
Success Criteria
The patterns described in this document are applied correctly in the implementation.
Edge cases and anti-patterns listed in this document are avoided.
1---2name: js-provider-pattern3description: JS Provider Pattern4---5# JS Provider Pattern67> Make shared data available to multiple consumers without prop-drilling89## When to Use1011- Multiple components or modules need the same data (theme, locale, current user, feature flags)12- You want to avoid threading a value through every function parameter or component prop13- You need to swap implementations (e.g., test vs production) by replacing the provider1415## Instructions16171. Create a context object or module-level store that holds the shared data.182. Expose a `provide(value)` function to register the data and a `consume()` / `inject()` function to retrieve it.193. Scope the provider — a module-level variable is global; a closure-based provider can be scoped to a subtree or request.204. Document what the provider exposes — callers should not need to inspect internals to use it.2122```javascript23// Simple module-level provider24let _theme = 'light';2526export function provideTheme(theme) {27 _theme = theme;28}2930export function useTheme() {31 return _theme;32}33```34355. In framework code (React/Vue), use the framework's native context API — do not re-implement it.366. Keep providers focused — one provider per concern (theme, auth, i18n), not one mega-provider.3738## Details3940The Provider pattern is the plain-JavaScript equivalent of what React Context and Vue's provide/inject formalize. The core idea: establish a value at one level and make it available to any consumer below that level without explicit passing.4142**Trade-offs:**4344- Module-level providers are singletons — hard to reset in tests45- Implicit dependencies — consumers do not declare that they depend on the provider in their signature46- No automatic re-rendering — plain JS providers do not trigger UI updates when the value changes (use a framework's reactive context for that)4748**When NOT to use:**4950- When only 1–2 levels of nesting exist — passing props directly is clearer51- When the data changes frequently and consumers need to react — use a reactive state management solution5253## Source5455https://patterns.dev/javascript/provider-pattern5657## Process58591. Read the instructions and examples in this document.602. Apply the patterns to your implementation, adapting to your specific context.613. Verify your implementation against the details and edge cases listed above.6263## Harness Integration6465- **Type:** knowledge — this skill is a reference document, not a procedural workflow.66- **No tools or state** — consumed as context by other skills and agents.6768## Success Criteria6970- The patterns described in this document are applied correctly in the implementation.71- Edge cases and anti-patterns listed in this document are avoided.
Run npx skillmds@latest add intense-visions/js-provider-pattern in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
JS Provider Pattern It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
Intense-Visions (@intense-visions) published this skill. Their other Agent Skills are listed on their SkillMD profile.