Using <Context> Instead of .Provider
In this tutorial, you will learn how React 19 modernizes Context usage by letting you use <Context> directly instead of <Context.Provider>.
This change removes boilerplate, improves readability, and aligns Context with how React wants you to structure applications going forward.
What We Will Learn
- Why
.Provideris no longer the preferred pattern - How
<Context>works in React 19 - How to create and consume Context correctly
- How this improves composition and readability
- Best practices for real world apps
By the end, you will confidently use Context the modern way.
The Problem with .Provider
Before React 19, Context usage looked like this:
<UserContext.Provider value={user}>
<App />
</UserContext.Provider>This introduced a few issues:
- Extra nesting
- Visual noise in JSX
- Harder to scan layouts
- Repeated
.Providereverywhere
It worked, but it was not ergonomic.
The React 19 Improvement
React 19 lets you use the Context object itself as a component.
Instead of:
<ThemeContext.Provider value="dark">
{children}
</ThemeContext.Provider>You now write:
<ThemeContext value="dark">
{children}
</ThemeContext>Same behavior. Less ceremony.
Creating a Context
Creating Context does not change.
// contexts/theme-context.ts
import { createContext } from "react"
export const ThemeContext = createContext<"light" | "dark">("light")The difference is how you provide the value.
Providing Context with <Context>
// app/layout.tsx
import { ThemeContext } from "../contexts/theme-context"
export default function RootLayout({
children
}: {
children: React.ReactNode
}) {
return (
<>
<title>Context Example</title>
<meta name="description" content="React 19 Context tutorial" />
<ThemeContext value="dark">
{children}
</ThemeContext>
</>
)
}This reads more like normal JSX and less like an API call.
Consuming Context
Context consumption does not change.
You still use the new use API.
// components/theme-label.tsx
import { use } from "react"
import { ThemeContext } from "../contexts/theme-context"
export function ThemeLabel() {
const theme = use(ThemeContext)
return <p>Current theme: {theme}</p>
}No useContext.
No hooks clutter.
Just read the value.
Why This Is Better
Cleaner JSX
<AuthContext value={user}>
<ThemeContext value="dark">
<App />
</ThemeContext>
</AuthContext>This is easier to read than stacked .Provider components.
Better Mental Model
Think of Context as:
A value flowing through a subtree
Using <Context> makes that idea explicit.
Multiple Contexts Together
// app/layout.tsx
<AuthContext value={user}>
<ThemeContext value="dark">
{children}
</ThemeContext>
</AuthContext>This pattern scales cleanly without becoming unreadable.
What Did Not Change
- Context is still global to a subtree
- Updates still cause re-renders where consumed
- Context should still be used sparingly
React did not change what Context is. It changed how you express it.
Common Mistakes
Mixing Old and New Styles
Do not do this:
<ThemeContext.Provider value="dark">
<ThemeContext value="light">
{children}
</ThemeContext>
</ThemeContext.Provider>Pick one style. In React 19, use <Context>.
Using Context for Everything
Context is for:
- Global app state
- Theme
- Auth
- Locale
Not for:
- Local component state
- Frequently changing values
- Performance critical updates
When You Should Use <Context>
Use it when:
- Sharing global data
- Avoiding prop drilling
- Building layouts and app shells
Avoid it when simple props are enough.
Mental Model
Think of <Context> like a pipe:
- You pour a value in at the top
- Every component below can read it
- You never pass it manually
The new syntax makes this feel natural.
Conclusion
React 19’s <Context> syntax removes unnecessary ceremony and makes Context usage clearer and more readable.
You get:
- Less boilerplate
- Cleaner layouts
- Easier reasoning about data flow
If you are writing modern React, stop reaching for .Provider.
Use <Context> and let your JSX stay simple and expressive.