Skip to content

upgrade: context package upgrade for Solid 2.0#907

Draft
davedbase wants to merge 2 commits into
solidjs-community:nextfrom
davedbase:update/v2/context
Draft

upgrade: context package upgrade for Solid 2.0#907
davedbase wants to merge 2 commits into
solidjs-community:nextfrom
davedbase:update/v2/context

Conversation

@davedbase
Copy link
Copy Markdown
Member

Migrates @solid-primitives/context to Solid.js 2.0 (beta.13) and adds three quality-of-life additions to the API.


Solid 2.0 migration (breaking)

  • Context.Provider removed — In Solid 2.0, the Context object itself is the provider component. createContextProvider and MultiProvider updated; <MyCtx.Provider value={...}> becomes <MyCtx value={...}>.
  • ContextProviderComponent import fixed — Previously imported from an internal node_modules path; now a proper export from solid-js.
  • JSX.ElementElement — Public API types now use Element from solid-js (renderer-neutral), matching the Solid 2.0 type model.
  • MultiProvider cleanup — Removed the .Provider fallback branch; Context is always a function in Solid 2.0.
  • Peer deps: solid-js@^2.0.0-beta.13 and @solidjs/web@^2.0.0-beta.13 required.
  • Version bumped to 1.0.0 (major).

Noteworthy Solid 2.0 behaviour: context providers now wrap children in a lazy memo (children(() => props.children)). Tests that previously used bare createRoot(() => { <Provider/>; }) never forced child evaluation. The MultiProvider browser test was updated to use render() so the DOM renderer drives evaluation of the lazy memo chain.


New exports

createStrictContextProvider

Like createContextProvider without defaults, but with the contract made explicit in types: the hook returns T (never T | undefined), and Solid throws ContextNotFoundError at runtime when called outside a provider. Accepts an optional { name } for DevTools labeling.

const [AuthProvider, useAuth] = createStrictContextProvider(
  () => {
    const [user, setUser] = createSignal<User | null>(null);
    return { user, setUser };
  },
  { name: "Auth" },
);

// No `!` needed — type is T, throws if no provider
const { user } = useAuth();

createLayeredContext

Each provider extends the parent context value rather than replacing it. The factory receives (props, parent) where parent is the nearest enclosing provider's value (falling back to defaults at the root). You control the merge strategy.

const [ThemeProvider, useTheme] = createLayeredContext(
  (props: { primary?: string }, parent) => ({
    ...parent,
    primary: props.primary ?? parent.primary,
  }),
  { primary: "blue", secondary: "gray" },
);

<ThemeProvider primary="red">            // { primary: "red",   secondary: "gray" }
  <ThemeProvider primary="green">        // { primary: "green", secondary: "gray" }
    <App />
  </ThemeProvider>
</ThemeProvider>

Useful for themes, permission layers, i18n patches, and any context where child providers should inherit what they don't explicitly override.

ContextProviderOptions + name on createContextProvider

All three primitives accept { name?: string } for the Solid DevTools Symbol label. On createContextProvider it's the third argument (with-defaults overload only):

createContextProvider(factory, defaultTheme, { name: "Theme" })

@davedbase davedbase added this to the Solid 2.0 Migration milestone May 21, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 21, 2026

🦋 Changeset detected

Latest commit: 943027f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@solid-primitives/context Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant