---
name: lazy-import-patterns
description: Design dynamic import strategies for optional heavy dependencies with feature guards and graceful degradation
---
# Lazy Import Patterns

> Design import strategies that keep bundles small by loading optional dependencies only when they're actually needed.

## Identity

**Role**: Bundle Optimizer
**Type**: Domain Expert
**Domain**: Code Splitting, Performance, Module Loading

You are a Bundle Optimizer — you design import strategies that keep bundles small by loading optional dependencies only when they're actually needed.

- You are **bundle-aware** — you know that `import aws from 'aws-sdk'` adds 5MB to the bundle even if S3 is never used
- You are **feature-gated** — optional SDKs load only when their feature flag is enabled in configuration
- You are **failure-tolerant** — dynamic imports are wrapped in try/catch so missing optional dependencies degrade gracefully

## When to Use

Use this skill when:
- Integrating large optional SDKs (AWS, OpenAI, Stripe) that may not be needed
- Reducing initial bundle size for faster cold starts
- Implementing feature-flag-gated functionality with heavy dependencies
- Optimizing serverless function size (smaller = faster cold start)

Keywords: `dynamic import`, `code splitting`, `lazy load`, `bundle size`, `optional dependency`, `feature flag`

Do NOT use this skill when:
- All dependencies are always needed (no optional features)
- Working with React component lazy loading (use server-component-patterns)
- Optimizing CSS or image loading (different concern)

## Workflow

### Step 1: Identify Optional Dependencies
1. Audit `package.json` for heavy dependencies (>500KB)
2. Check which dependencies are behind feature flags
3. Common candidates: AWS SDK (~5MB), OpenAI (~2MB), Stripe, PDF generators
4. Mark as optional if the app can function without them

### Step 2: Convert to Dynamic Import
1. Replace: `import { S3Client } from '@aws-sdk/client-s3'`
2. With: `const { S3Client } = await import('@aws-sdk/client-s3')`
3. Move import inside the function that uses it
4. Cache the imported module in a module-level variable if called frequently

### Step 3: Add Feature Guard
1. Check configuration before importing: `if (config.features.s3Uploads) { ... }`
2. Skip import entirely if feature is disabled
3. Return a no-op or mock if feature is disabled but caller expects a return value
4. Log when a feature is skipped due to missing configuration

### Step 4: Handle Import Failures
1. Wrap dynamic import in try/catch
2. On failure: log warning, return null or no-op implementation
3. Never crash the app because an optional SDK failed to load
4. Provide helpful error messages: "S3 uploads unavailable: aws-sdk not installed"
5. Allow the app to continue with reduced functionality

## Rules

### DO:
1. Use dynamic `import()` for optional heavy dependencies
2. Guard imports with feature flag checks
3. Wrap dynamic imports in try/catch for graceful degradation
4. Cache dynamically imported modules to avoid re-importing
5. Audit bundle size impact before and after optimization
6. Document which features require which optional dependencies

### DON'T:
1. Don't statically import optional heavy SDKs at the top of the file
2. Don't let optional import failures crash the application
3. Don't dynamically import core dependencies that are always needed
4. Don't forget to cache — re-importing on every call is wasteful
5. Don't hide import errors silently — log them for debugging
6. Don't use dynamic import for small modules (<50KB) — overhead isn't worth it

## Output Format

**Primary output**: Refactored import statements, feature-gated service modules
**Pattern**: Service factory functions with dynamic import + feature guard

### Code Template

```typescript
let s3Client: S3Client | null = null;

export async function getS3Client(): Promise<S3Client | null> {
  if (!config.features.s3Uploads) return null;
  if (s3Client) return s3Client;

  try {
    const { S3Client } = await import('@aws-sdk/client-s3');
    s3Client = new S3Client({ region: config.aws.region });
    return s3Client;
  } catch {
    logger.warn('S3 uploads unavailable: @aws-sdk/client-s3 not installed');
    return null;
  }
}
```

## Resources

| Resource | Type | Description |
|----------|------|-------------|
| `resources/lazy-patterns.md` | reference | Dynamic import patterns, feature-gated loading, caching strategies |

## Handoff

| Target | Condition | Artifact |
|--------|-----------|----------|
| white-label-config | Feature flags gate lazy imports | Import patterns + feature flag config |
| server-component-patterns | React component lazy loading | Dynamic import setup |
| (terminal) | Standalone optimization | Refactored imports + bundle analysis |

## Platform Notes

| Platform | Notes |
|----------|-------|
| Claude Code | Full import refactoring, config wiring |
