-
Notifications
You must be signed in to change notification settings - Fork 59
Wrappers Detection
Drift detects framework wrapper patterns β custom abstractions built on top of framework primitives like React hooks, Express middleware, and database clients.
Wrappers are functions that wrap framework primitives to add custom behavior:
// This is a wrapper around React's useState
function useLocalStorage<T>(key: string, initial: T) {
const [value, setValue] = useState<T>(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initial;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue] as const;
}Drift identifies these patterns and clusters similar wrappers together.
# Scan for wrappers
drift wrappers
# Include test files
drift wrappers --include-tests
# Filter by category
drift wrappers --category state-management
# JSON output
drift wrappers --json
# Verbose output
drift wrappers --verbosedrift wrappers [options]| Option | Description | Default |
|---|---|---|
-d, --dir <path> |
Project directory | . |
-j, --json |
Output as JSON | false |
-v, --verbose |
Show detailed output | false |
--include-tests |
Include test files | false |
--min-confidence <n> |
Minimum cluster confidence (0-1) | 0.5 |
--min-cluster-size <n> |
Minimum wrappers per cluster | 2 |
--max-depth <n> |
Maximum wrapper depth | 10 |
--category <cat> |
Filter by category | all |
π Wrapper Analysis Summary
Files scanned: 234
Functions found: 1,847
Wrappers detected: 45
Clusters found: 12
Duration: 1,234ms
π§ Frameworks Detected
react - 156 primitives
express - 23 primitives
prisma - 18 primitives
π¦ Wrapper Clusters
useAuth Hooks (state-management) 92%
Custom authentication state management hooks
Primitives: useState, useEffect, useContext +2 more
8 wrappers, avg depth 2.3, 156 usages
API Client Wrappers (data-fetching) 87%
Wrappers around fetch/axios for API calls
Primitives: fetch, axios.get, axios.post
5 wrappers, avg depth 1.8, 89 usages
Database Helpers (data-access) 85%
Prisma client wrappers with error handling
Primitives: prisma.user.findMany, prisma.user.create
6 wrappers, avg depth 2.1, 67 usages
π Wrappers by Category
state-management ββββββββββββββββββββ 15
data-fetching ββββββββββββββββ 12
data-access ββββββββββ 8
authentication ββββββββ 6
error-handling ββββ 4
| Category | Description | Examples |
|---|---|---|
state-management |
State hooks and stores | useLocalStorage, useReducer wrappers |
data-fetching |
API and data fetching | useFetch, useQuery wrappers |
side-effects |
Effect management | useDebounce, useInterval |
authentication |
Auth state and logic | useAuth, useSession |
authorization |
Permission checking | usePermissions, useRoles |
validation |
Input validation | useForm, useValidation |
dependency-injection |
DI patterns | useService, useRepository |
middleware |
Request/response middleware | withAuth, withLogging |
testing |
Test utilities | renderWithProviders |
logging |
Logging wrappers | useLogger, withTelemetry |
caching |
Cache management | useCachedQuery, withCache |
error-handling |
Error boundaries | useErrorBoundary, withErrorHandler |
async-utilities |
Async helpers | useAsync, usePromise |
form-handling |
Form state | useFormField, useFormSubmit |
routing |
Navigation wrappers | useTypedRouter, useQueryParams |
factory |
Factory patterns | createService, createRepository |
decorator |
Decorator patterns | @Cached, @Logged |
utility |
General utilities | usePrevious, useToggle |
drift_wrappers({
category?: string, // Filter by category
includeTests?: boolean, // Include test files (default: false)
limit?: number, // Max clusters to return (default: 20)
minConfidence?: number, // Min cluster confidence 0-1 (default: 0.5)
minClusterSize?: number, // Min wrappers per cluster (default: 2)
maxDepth?: number // Max wrapper depth (default: 10)
})Categories:
-
state-management,data-fetching,side-effects,authentication -
authorization,validation,dependency-injection,middleware -
testing,logging,caching,error-handling,async-utilities -
form-handling,routing,factory,decorator,utility,other
Returns:
{
"clusters": [
{
"name": "useAuth Hooks",
"category": "state-management",
"confidence": 0.92,
"description": "Custom authentication state management hooks",
"primitiveSignature": ["useState", "useEffect", "useContext"],
"wrappers": [
{
"name": "useAuth",
"file": "src/hooks/useAuth.ts",
"line": 12,
"depth": 2,
"calledBy": ["LoginForm", "Dashboard", "ProfilePage"]
}
],
"avgDepth": 2.3,
"totalUsages": 156
}
],
"frameworks": [
{ "name": "react", "primitiveCount": 156 }
],
"summary": {
"totalWrappers": 45,
"totalClusters": 12,
"wrappersByCategory": {
"state-management": 15,
"data-fetching": 12
}
}
}Wrapper depth indicates how many layers of abstraction exist:
// Depth 1: Direct wrapper
function useToggle(initial: boolean) {
const [value, setValue] = useState(initial); // Wraps useState
return [value, () => setValue(v => !v)];
}
// Depth 2: Wrapper of wrapper
function useDarkMode() {
const [isDark, toggle] = useToggle(false); // Wraps useToggle
useEffect(() => {
document.body.classList.toggle('dark', isDark);
}, [isDark]);
return [isDark, toggle];
}
// Depth 3: Another layer
function useTheme() {
const [isDark, toggleDark] = useDarkMode(); // Wraps useDarkMode
const [accent, setAccent] = useState('blue');
return { isDark, toggleDark, accent, setAccent };
}High depth (>5) may indicate over-abstraction.
Confidence scores indicate how certain Drift is about the cluster:
| Score | Meaning |
|---|---|
| 90-100% | Very confident β clear pattern with consistent usage |
| 70-89% | Confident β good pattern match |
| 50-69% | Moderate β possible pattern, review recommended |
| <50% | Low β may be false positive |
Factors affecting confidence:
- Number of wrappers in cluster
- Consistency of primitive usage
- Usage count across codebase
- Naming conventions
Find all custom React hooks in your codebase:
drift wrappers --category state-management --verboseCheck for over-abstraction:
drift wrappers --max-depth 10 --json | jq '.clusters[] | select(.avgDepth > 4)'Identify wrappers with low usage:
drift wrappers --json | jq '.clusters[] | select(.totalUsages < 3)'Generate documentation for your wrapper patterns:
drift wrappers --verbose > docs/WRAPPER_PATTERNS.mdDrift automatically detects these frameworks and their primitives:
-
useState,useEffect,useContext,useReducer -
useMemo,useCallback,useRef -
useLayoutEffect,useImperativeHandle
-
app.get,app.post,app.use -
router.get,router.post -
req.body,res.json,next()
-
prisma.*.findMany,prisma.*.findUnique -
prisma.*.create,prisma.*.update prisma.$transaction
-
axios.get,axios.post,axios.put -
axios.create,axios.interceptors
- NestJS decorators and providers
- TypeORM repositories
- Mongoose models
- Redis clients
// β
Good - shallow wrapper
function useUser(id: string) {
return useQuery(['user', id], () => fetchUser(id));
}
// β οΈ Consider - deep nesting
function useUserProfile(id: string) {
const user = useUser(id); // Depth 1
const settings = useUserSettings(id); // Depth 1
const merged = useMergedData(user, settings); // Depth 2
return useFormattedProfile(merged); // Depth 3
}// β
Good - clear naming
function useLocalStorage<T>(key: string, initial: T) { }
function useDebounce<T>(value: T, delay: number) { }
function withErrorBoundary(Component: React.FC) { }
// β Bad - unclear naming
function useData() { }
function helper() { }
function wrap(fn: Function) { }/**
* Persists state to localStorage with automatic serialization.
*
* @example
* const [theme, setTheme] = useLocalStorage('theme', 'light');
*/
function useLocalStorage<T>(key: string, initial: T) { }Keep related wrappers in the same file or directory:
src/hooks/
βββ auth/
β βββ useAuth.ts
β βββ useSession.ts
β βββ usePermissions.ts
βββ data/
β βββ useQuery.ts
β βββ useMutation.ts
β βββ useCache.ts
βββ ui/
βββ useToggle.ts
βββ useDebounce.ts
βββ useMediaQuery.ts
Wrapper patterns are automatically detected and can be approved:
drift scan
drift status --category structural
# Look for "Custom Hook Pattern" or "Middleware Wrapper Pattern"
drift approve <pattern-id>Wrappers appear in call graph analysis:
drift callgraph callers useAuth
# Shows all components using the useAuth wrapperSee which wrappers have test coverage:
drift test-topology coverage src/hooks/useAuth.ts- Pattern Categories β See all pattern types
- Call Graph Analysis β Trace wrapper usage
- Hooks Detection β Find React/Vue hooks
- Cortex V2 Overview
- Memory Setup Wizard
- Memory CLI
- Universal Memory Types
- Learning System
- Token Efficiency
- Causal Graphs
- Code Generation
- Predictive Retrieval
- Architecture
- Call Graph Analysis
- Impact Analysis
- Security Analysis
- Data Boundaries
- Test Topology
- Coupling Analysis
- Error Handling Analysis
- Wrappers Detection
- Environment Variables
- Constants Analysis
- Styling DNA
- Constraints
- Contracts
- Decision Mining
- Speculative Execution
- Watch Mode
- Trends Analysis
- Projects Management
- Package Context
- Monorepo Support
- Reports & Export
- Dashboard
- 10 Languages
- 21 Frameworks
- 16 ORMs
- 400+ Detectors
- 50+ MCP Tools
- 60+ CLI Commands
- 23 Memory Types