Getting Started

DevTools

Vue DevTools integration for debugging and inspecting your VueAirport registries.

VueAirport provides full integration with Vue DevTools to help you visualize and debug your component registries in real-time.

Features

  • 🔍 Registry Inspector - Visualize the entire CheckIn registry tree with live data
  • ⏱️ Timeline - Track all check-in/check-out events in real-time
  • 📊 Live Updates - See your registry state update as you interact with your app
  • 🎯 State Details - Inspect metadata, data, and timestamps for each item
  • 🏷️ Smart Tags - Visual indicators for child count and active states

Installation

Install the DevTools package as a development dependency:

npm install -D vue-airport-devtools

Setup

Standard Vue 3 / Vite Project

The plugin automatically injects DevTools setup in your application:

vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { VueAirportDevTools } from 'vue-airport-devtools/vite'

export default defineConfig({
  plugins: [
    vue(),
    VueAirportDevTools(), // Auto-injects DevTools
  ],
})
Auto-injection only adds DevTools in development mode (DEV).

Nuxt Project

For Nuxt, simply add the DevTools module to your configuration:

nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    // ... other modules
    'vue-airport-devtools/nuxt',
  ],
})
Development tools do not integrate in Nuxt devtools panels. For the time being, use the standard Vue DevTools extension in the browser developer tools.

Manual Setup (without Vite)

If you prefer manual setup or don't use Vite:

main.ts
import { createApp } from 'vue'
import { setupAirportDevTools } from 'vue-airport-devtools'
import App from './App.vue'

const app = createApp(App)

// Enable DevTools only in development
if (import.meta.env.DEV) {
  setupAirportDevTools(app)
}

app.mount('#app')

Usage

Enabling DevTools for a Desk

DevTools integration is opt-in and must be explicitly enabled when creating a desk:

import { useCheckIn } from 'vue-airport'

const { createDesk } = useCheckIn()

createDesk(MY_DESK_KEY, {
  devTools: true,
  deskId: 'my-feature-desk',
})
DevTools are opt-in per desk. Set devTools: true in the desk options to enable tracking and visualization. This prevents performance overhead for desks that don't need debugging.

Identifying Your Desks

Provide a descriptive deskId for better visibility in the DevTools inspector. If not provided, the desk will use the Symbol's description:

// Without deskId - uses Symbol description
createDesk(MY_DESK_KEY, {
  devTools: true,
});
// Shows as: "MY_DESK_KEY" (from Symbol description)

// With deskId - explicit name
createDesk(MY_DESK_KEY, {
  devTools: true,
  deskId: 'user-profile-form',
});
// Shows as: "user-profile-form"
The deskId is optional but highly recommended for complex applications with multiple desks. It makes debugging significantly easier.

Adding Metadata for Debugging

Item metadata appears in the inspector, making it easier to understand what each item represents:

const { checkIn } = useCheckIn()

checkIn(MY_DESK_KEY, {
  id: 'user-123',
  autoCheckIn: true,
  data: { name: 'John Doe', email: 'john@example.com' },
  meta: {
    label: 'Admin User Profile',
    role: 'admin',
    active: true,
    priority: 'high',
    description: 'Primary administrator account',
    createdBy: 'AuthModule',
  },
})

Metadata best practices:

  • label: Human-readable name (shown prominently in inspector)
  • active: Boolean state indicators
  • priority: Importance level
  • role, type, category: Classification
  • description: Detailed explanation
  • Custom fields: Any domain-specific information

Registry Inspector

The Airport Registry Inspector provides a complete visualization of your desk registries with real-time updates.

Tree View Structure

The inspector displays your registries in a hierarchical tree:

Desks (Parent Nodes):

  • Displayed with their deskId or auto-generated identifier
  • Show a badge with the number of registered children
  • Expandable to reveal all registered items

Items (Child Nodes):

  • Listed under their parent desk
  • Identified by their unique ID
  • Show an "active" badge if metadata contains active: true
  • Color-coded for easy visual identification

Inspector Features

Visual Indicators

User Profile Form (3)
  - user-123 [active]
  - user-456
  - user-789 [active]

Shopping Cart (2)
  - product-001
  - product-002
  • Badge count: Number of checked-in items
  • Active indicator: Shows which items are currently active
  • Hierarchical structure: Clear parent-child relationships

State Details Panel

Select any node to view comprehensive information:

For Desks:

{
  deskId: "user-profile-form",
  size: 3,
  items: [...],
  context: {
    activeUser: "user-123",
    selectUser: [Function],
    // ... other context properties
  }
}

For Items:

{
  id: "user-123",
  metadata: {
    label: "Admin User Profile",
    active: true,
    role: "admin",
    priority: "high",
    createdBy: "AuthModule"
  },
  data: {
    name: "John Doe",
    email: "john@example.com",
    role: "administrator"
  },
  timestamps: {
    createdAt: "2025-01-15T10:30:00.000Z",
    updatedAt: "2025-01-15T11:45:00.000Z"
  }
}

Data Displayed:

  • Metadata: All custom metadata fields (label, active, role, etc.)
  • Data: The actual data stored in the registry
  • Context: Shared context from the parent desk
  • Timestamps: Creation and last update times
  • Registry Info: Statistics like item count

Real-Time Updates

The inspector updates automatically as your application state changes:

  • Items appear when they check in
  • Items disappear when they check out
  • Data updates reflect immediately
  • Badge counts update in real-time
  • Active states change dynamically

Practical Use Cases

Verify Component Registration

Check if a component successfully registered:

  1. Open the Registry Inspector
  2. Locate the desk by its deskId
  3. Verify the item appears under the desk
  4. Inspect the metadata and data

Debug State Issues

When data doesn't appear as expected:

  1. Find the item in the inspector
  2. Check the data property
  3. Compare with expected values
  4. Verify timestamps.updatedAt for recent changes

Monitor Active States

Track which items are currently active:

  1. Look for [active] badges in the tree
  2. Or check metadata.active in the details panel
  3. Verify active state changes in real-time

Events Timeline

The Airport Events Timeline traces all desk events in real-time, providing a complete audit trail of your application's registration lifecycle.

Event Types and Colors

The timeline uses color-coded events for easy identification:

Fired when a component registers with a desk

Details shown:
- Desk ID
- Item ID
- Initial data
- Metadata
- Timestamp

Timeline Features

Event Details

Click on any event to see comprehensive information:

Check-In Event:

{
  type: 'check-in',
  deskId: 'user-profile-form',
  itemId: 'user-123',
  timestamp: 1705315800000,
  data: {
    name: 'John Doe',
    email: 'john@example.com'
  },
  metadata: {
    label: 'Admin User',
    role: 'admin'
  }
}

Update Event:

{
  type: 'update',
  deskId: 'user-profile-form',
  itemId: 'user-123',
  timestamp: 1705316100000,
  before: {
    email: 'john@example.com'
  },
  after: {
    email: 'john.doe@company.com'
  }
}

Plugin Event:

{
  type: 'plugin',
  pluginName: 'validation',
  deskId: 'user-profile-form',
  itemId: 'user-123',
  duration: 2.5, // milliseconds
  timestamp: 1705316200000,
  result: 'success'
}

Timeline Filtering

Use filters to focus on specific event types:

  • Show only check-in events
  • Show only updates
  • Show only plugin executions
  • Show events for a specific desk
  • Show events for a specific item

Performance Monitoring

Track plugin execution times:

  • See which plugins are slowest
  • Identify performance bottlenecks
  • Monitor execution patterns
  • Compare plugin performance
Use timeline filters to display only specific event types or filter by desk/item ID for focused debugging.

Debugging Workflows

Scenario 1: Component Not Registering

Problem: A child component doesn't appear to communicate with its parent desk.

Debugging steps:

  1. Verify desk exists:
    • Open Registry Inspector
    • Look for the desk by its deskId
    • If missing, check desk creation code
  2. Check item registration:
    • Expand the desk node
    • Look for the item by its ID
    • If missing, verify autoCheckIn: true or manual check-in
  3. Inspect check-in event:
    • Open Events Timeline
    • Look for green check-in events
    • Verify the item ID matches
  4. Check for errors:
    • Look for failed check-in attempts in console
    • Verify injection key matches between parent and child
    • Check if onBeforeCheckIn hook cancelled registration

Common causes:

  • Wrong injection key
  • autoCheckIn: false without manual check-in
  • Plugin or hook returning false
  • Component unmounting before check-in completes

Scenario 2: Data Not Updating

Problem: Component data changes but the desk registry doesn't update.

Debugging steps:

  1. Check watchData setting:
    checkIn(DESK_KEY, {
      watchData: true,
      data: () => myData.value,
    });
    
  2. Monitor update events:
    • Open Events Timeline
    • Interact with component to trigger changes
    • Look for blue ↻ Update events
    • If no events appear, data watching isn't configured
  3. Verify data function:
    • Ensure data function returns the correct value
    • Check that reactive dependencies are tracked
    • Confirm shallow vs deep watching configuration
  4. Inspect before/after data:
    • Click on update events in timeline
    • Compare before/after values
    • Verify changes match expectations

Common causes:

  • watchData: false or not set
  • Data function not reactive (missing .value)
  • Using shallow: true when nested changes occur
  • Data wrapped in non-reactive object

Scenario 3: Plugin Debugging

Problem: Need to verify plugin execution and performance.

Debugging steps:

  1. Enable plugin tracking:
    createDesk(DESK_KEY, {
      devTools: true,
      plugins: [myPlugin],
    });
    
  2. Monitor plugin events:
    • Open Events Timeline
    • Look for purple Plugin events
    • Check event details for plugin name
  3. Check execution order:
    • Multiple plugins execute in array order
    • Verify plugins appear in correct sequence
    • Check if earlier plugins cancel later ones
  4. Measure performance:
    • Review duration field in plugin events
    • Identify slow plugins (> 10ms)
    • Optimize heavy computations
  5. Verify data transformation:
    • Inspect data before plugin execution
    • Compare with data after execution
    • Ensure transformations are correct

Example plugin debugging:

const debugPlugin = {
  name: 'debug-validation',
  onBeforeCheckIn: (id, data, desk) => {
    console.log('[Plugin Debug] Before check-in:', { id, data });
    
    if (!data.email) {
      console.warn('[Plugin Debug] Validation failed: Missing email');
      return false; // Cancels check-in
    }
    
    return true;
  },
  onCheckIn: (id, data, desk) => {
    console.log('[Plugin Debug] Checked in successfully:', { id, data });
  },
};

createDesk(FORM_DESK_KEY, {
  devTools: true,
  deskId: 'form-validation-desk',
  plugins: [debugPlugin],
});

Timeline will show:

Plugin: debug-validation
Duration: 0.8ms
Result: cancelled (returned false)

Common issues:

  • Plugin not in plugins array
  • Plugin returning undefined (treated as true)
  • Plugin throwing errors (check console)
  • Slow plugin blocking registration

Scenario 4: Conditional Check-In Issues

Problem: Component not checking in/out based on condition.

Debugging steps:

  1. Verify watchCondition setup:
    const isVisible = ref(true);
    
    checkIn(DESK_KEY, {
      watchCondition: isVisible, // or () => someCondition.value
      data: myData,
    });
    
  2. Monitor check-in/out events:
    • Toggle the condition
    • Watch for green check-in events when condition becomes true
    • Watch for red check-out events when condition becomes false
  3. Check initial state:
    • With autoCheckIn: false: No check-in until condition is true
    • With autoCheckIn: true: Immediate check-in if condition starts true
  4. Verify condition reactivity:
    • Ensure condition is a Ref or reactive function
    • Check that condition changes are detected
    • Look for console warnings about non-reactive conditions

Example debugging:

// Wrong: Non-reactive condition
checkIn(DESK_KEY, {
  watchCondition: () => true,
});

// Correct: Reactive condition
const isActive = ref(false);
checkIn(DESK_KEY, {
  watchCondition: isActive,
});

// Complex condition
checkIn(DESK_KEY, {
  watchCondition: () => 
    isLoggedIn.value && 
    hasPermission.value && 
    !isDisabled.value,
  autoCheckIn: true,
});

Timeline patterns:

  • Condition falsetrue: See Check In event
  • Condition truefalse: See Check Out event
  • No events: Condition not changing or not reactive

Scenario 5: Memory Leaks

Problem: Items not checking out when components unmount.

Debugging steps:

  1. Monitor registry size:
    • Check desk badge count in inspector
    • Count should decrease when components unmount
  2. Verify check-out events:
    • Navigate away from components
    • Look for red ✗ Check Out events in timeline
    • If missing, check-out isn't happening
  3. Common causes:
    • Missing onUnmounted cleanup (VueAirport handles this automatically)
    • onBeforeCheckOut hook returning false
    • Desk destroyed before components unmount
  4. Force cleanup:
    // Manual cleanup if needed
    const { checkOut } = checkIn(DESK_KEY, { ... });
    
    // Later
    checkOut(); // Manual check-out
    

Best Practices for DevTools

Use Descriptive Labels

Make debugging easier with clear, human-readable labels:

// Not helpful
checkIn('1', data, {
  active: true,
});

// Descriptive and informative
checkIn('user-123', userData, {
  label: 'John Doe (Admin)',
  role: 'admin',
  active: true,
  department: 'Engineering',
});

Benefits:

  • Instantly understand what each item represents
  • Easier to spot issues in inspector
  • Better team collaboration
  • Faster debugging

Add Rich Metadata

Include detailed metadata that provides debugging context:

// ❌ Minimal metadata
checkIn('item-1', data, {
  active: true,
});

// ✅ Rich, contextual metadata
checkIn('order-12345', orderData, {
  label: '🛒 Order #12345',
  active: true,
  status: 'pending',
  priority: 'high',
  customer: 'John Doe',
  createdBy: 'CheckoutModule',
  source: 'web-app',
  timestamp: Date.now(),
  tags: ['urgent', 'vip-customer'],
});

Recommended metadata fields:

  • label: Human-readable description (shown prominently)
  • active: Boolean state indicator
  • status: Current state ('pending', 'complete', etc.)
  • priority: Importance level ('low', 'medium', 'high')
  • type, category, role: Classification
  • createdBy, source: Origin tracking
  • tags: Array of keywords for filtering
  • Custom domain-specific fields

Use Meaningful Desk IDs

Choose descriptive IDs that reflect the desk's purpose and domain:

// Generic or unclear
createDesk(KEY1, {
  devTools: true,
  deskId: 'desk1',
});

// Clear and descriptive
createDesk(NAVIGATION_KEY, {
  devTools: true,
  deskId: 'main-navigation-tabs',
});

createDesk(FORM_KEY, {
  devTools: true,
  deskId: 'user-profile-form-fields',
});

createDesk(CART_KEY, {
  devTools: true,
  deskId: 'shopping-cart-items',
});

createDesk(ADMIN_USERS_KEY, {
  devTools: true,
  deskId: 'admin-panel-users',
});

Naming conventions:

  • Use kebab-case for readability
  • Include the feature/module name
  • Be specific about the desk's purpose
  • Keep it concise but descriptive

Enable DevTools Selectively

Only enable DevTools for desks you need to debug:

// Enable for desks under development or debugging
createDesk(NEW_FEATURE_KEY, {
  devTools: true,
  deskId: 'new-feature-beta',
});

// Don't enable for all desks unnecessarily
createDesk(STABLE_FEATURE_KEY, {
  devTools: false,
});

Benefits:

  • Reduces DevTools overhead
  • Cleaner inspector view
  • Focuses attention on relevant desks
  • Better performance in large applications

Combine Debug Mode with DevTools

Use debug logging alongside DevTools for comprehensive insights:

createDesk(MY_DESK_KEY, {
  devTools: true,
  debug: true,
  deskId: 'debug-desk',
});

checkIn(MY_DESK_KEY, {
  debug: true,
  data: myData,
});

Debug output example:

[useCheckIn:desk-core] Checked in: user-123 { name: 'John', role: 'admin' }
[useCheckIn:desk-child] Checked in: user-123 { name: 'John', role: 'admin' }
[useCheckIn:desk-core] Updated: user-123 { role: 'superadmin' }

Performance

DevTools are automatically disabled in production and have zero impact on your final bundle.

Development impact:

  • Minimal overhead for registry tracking
  • Event timeline stored in memory
  • Automatic cleanup on component unmount
Timeline events are kept in memory. For applications with very high activity (hundreds of events per second), consider:
  • Refreshing DevTools periodically
  • Using timeline filters to reduce displayed events
  • Enabling DevTools only on specific desks during debugging

Compatibility

  • Vue DevTools 6+: Recommended version
  • Vue 3.3+: Required for VueAirport
  • Browsers: Chrome, Firefox, Edge (with Vue DevTools extension)

Troubleshooting

DevTools Don't Appear in Browser

Possible causes and solutions:

  1. Vue DevTools extension not installed:
    • Install Vue DevTools browser extension
    • Chrome, Firefox, and Edge are supported
  2. Not in development mode:
    • Verify you're running npm run dev or equivalent
    • Check import.meta.env.DEV === true
    • DevTools are disabled in production builds
  3. Plugin not configured:
    • Verify Vite plugin in vite.config.ts:
      import { VueAirportDevTools } from 'vue-airport-devtools/vite'
      
      export default defineConfig({
        plugins: [vue(), VueAirportDevTools()],
      })
      
    • Or Nuxt module in nuxt.config.ts:
      export default defineNuxtConfig({
        modules: ['vue-airport-devtools/nuxt'],
      })
      
  4. Check browser console for errors:
    • Open browser developer tools
    • Look for VueAirport-related errors
    • Verify no initialization failures

Events Not Appearing in Timeline

Debugging steps:

  1. Verify DevTools enabled on desk:
    createDesk(MY_DESK_KEY, {
      devTools: true,
    });
    
  2. Check desk is created before components:
    • Desk must exist before child components check in
    • Verify initialization order in component lifecycle
  3. Verify event types:
    • Only desk-related events appear
    • Check-in, check-out, update, plugin, clear events
    • Non-desk operations won't be tracked
  4. Console errors:
    • Check browser console for errors
    • Look for failed event emissions
    • Verify DevTools connection is active

Inspector Shows Empty Registry

Common causes:

  1. No desks created yet:
    • Create at least one desk with createDesk()
    • Ensure desk creation happens during setup
  2. No items checked in:
    • Register at least one item with checkIn()
    • Verify autoCheckIn: true or manual check-in
    • Check if onBeforeCheckIn hooks are cancelling registration
  3. Wrong injection key:
    • Verify child components use same injection key
    • Check for typos in key symbols
    • Ensure key is exported/imported correctly
  4. Try refreshing:
    • Click the refresh button in DevTools
    • Reload the page
    • Restart the dev server

Performance Issues with DevTools

Solutions:

  1. Enable DevTools selectively:
    // Only enable for desks you're debugging
    createDesk(DEBUG_DESK_KEY, {
      devTools: true,
    });
    
    createDesk(OTHER_DESK_KEY, {
      devTools: false, // Disabled
    });
    
  2. Clear timeline periodically:
    • Use timeline filter to reduce events shown
    • Refresh DevTools to clear event history
    • Focus on specific desk or event type
  3. Reduce debug logging:
    createDesk(MY_DESK_KEY, {
      devTools: true,
      debug: false, // Disable console logging
    });
    
For more help:
  • Check the GitHub issues
  • Search for similar problems
  • Open a new issue with DevTools console output

Next Steps

Explore Plugins

Discover built-in plugins and how to create your own.

Practical Examples

See DevTools in action with our commented examples.

::