Provide and inject pass a value down a component tree without prop drilling, and they hide the dependency from everything that reads the component in isolation.
// the parent
provide('theme', readonly(theme))
// forty levels down
const theme = inject('theme')
// what makes this bearable:
// - a Symbol key, not a string, so it cannot collide
// - readonly, so a child cannot write to it
// - a default, so the component works standalone
const theme = inject(themeKey, defaultTheme)
The string key is the version that goes wrong: two libraries providing "store" collide silently and the closer one wins. A Symbol exported from a module makes the key importable and unambiguous, and in TypeScript an InjectionKey<T> carries the type with it. Wrapping the provided value in readonly is what stops this becoming a mutable global that anything in the subtree can write to, which is the state it drifts towards otherwise.