---
title: Avoid Prop Drilling - Use Provide/Inject for Deep Component Trees
impact: MEDIUM
impactDescription: Passing props through many layers creates maintenance burden and tight coupling between intermediate components
type: best-practice
tags: [vue3, props, provide-inject, component-design, state-management, architecture]
---
# Avoid Prop Drilling - Use Provide/Inject for Deep Component Trees
**Impact: MEDIUM** - Prop drilling occurs when you pass props through multiple component layers just to reach a deeply nested child. This creates tight coupling, makes refactoring difficult, and clutters intermediate components with props they don't use.
Vue's provide/inject API allows ancestor components to share data with any descendant, regardless of nesting depth.
## Task Checklist
- [ ] Identify when props pass through 2+ intermediate components unchanged
- [ ] Use provide/inject for data needed by deeply nested descendants
- [ ] Use Pinia for global state shared across unrelated component trees
- [ ] Keep props for direct parent-child relationships
- [ ] Document provided values at the provider level
## The Problem: Prop Drilling
```vue
```
```vue
```
```vue
```
```vue
{{ user.name }}
```
**Problems:**
1. `MainLayout` and `Sidebar` are cluttered with props they don't use
2. Adding a new shared value requires updating every component in the chain
3. Removing a deeply nested component requires updating all ancestors
4. Difficult to trace where data originates
## Solution: Provide/Inject
**Correct - Provider (ancestor):**
```vue
```
**Correct - Intermediate components are now clean:**
```vue
```
```vue
```
**Correct - Consumer (descendant):**
```vue
{{ user.name }}
```
```vue
```
## Best Practices for Provide/Inject
### 1. Use Symbol Keys for Large Apps
Avoid string key collisions with symbols:
```js
// keys.js
export const UserKey = Symbol('user')
export const ThemeKey = Symbol('theme')
```
```vue
```
```vue
```
### 2. Provide Default Values
Handle cases where no ancestor provides the value:
```vue
```
### 3. Use Readonly for Data Safety
Prevent descendants from mutating provided data:
```vue
```
### 4. Provide Computed Values for Reactivity
```vue
```
## When to Use What
| Scenario | Solution |
|----------|----------|
| Direct parent-child | Props |
| 1-2 levels deep | Props (drilling is acceptable) |
| Deep nesting, same component tree | Provide/Inject |
| Unrelated component trees | Pinia (state management) |
| Cross-app global state | Pinia |
| Plugin configuration | Provide/Inject from plugin install |
## Provide/Inject vs Pinia
**Provide/Inject:**
- Scoped to component subtree
- Great for component library internals
- No DevTools support
- Ancestor-descendant relationships only
**Pinia:**
- Global, accessible anywhere
- Excellent DevTools integration
- Better for application state
- Works across unrelated components
## Reference
- [Vue.js Provide/Inject](https://vuejs.org/guide/components/provide-inject.html)
- [Vue.js - Prop Drilling](https://vuejs.org/guide/components/provide-inject.html#prop-drilling)
- [Pinia Documentation](https://pinia.vuejs.org/)