---
title: wirekit:doctor
description: Diagnostic command — verify your WireKit integration is healthy
visibility: guest
draft: false
---

# `wirekit:doctor`

A no-side-effect diagnostic command that walks your installation and reports any drift between WireKit's expected setup and what your project actually has on disk. Run it after a fresh `composer require pushery/wirekit`, after every `composer update`, or whenever components look unstyled / non-interactive.

```bash
php artisan wirekit:doctor
```

`wirekit:doctor` is an alias of `wirekit:verify` — same checks, friendlier name. Both commands are idempotent and read-only; running them never modifies your project.

## What it checks

The doctor walks every check in sequence, grouped into five sections:

### 1 · Asset publishing & freshness

| Check | Pass criterion |
|-------|----------------|
| `wirekit.css` published | File exists at `public/vendor/wirekit/wirekit.css` |
| `wirekit.js` published | File exists at `public/vendor/wirekit/wirekit.js` |
| Asset freshness | md5 hash of published copy matches the package source — catches forgotten `vendor:publish --force` after `composer update` |
| Built CSS contains WireKit utility rules | Tailwind `@source` directive is correctly picking up WireKit blade templates and emitting matching utility classes |

### 2 · Integration wiring

| Check | Pass criterion |
|-------|----------------|
| Tailwind `@source` directive | `resources/css/app.css` includes `@source '../../vendor/pushery/wirekit/resources/views/**/*.blade.php';` |
| `config/wirekit.php` published | Config file exists in your `config/` directory |
| Blade directives present | Layout file contains `@wirekitStyles` (in `<head>`) AND `@wirekitScripts` (before `</body>`) |
| Bundle config | `config('wirekit.scripts.bundle')` is `'full'` or `'core'` |
| CSS `@import` anti-pattern | Warns if `wirekit.css` is `@import`-ed in `app.css` instead of using the `@wirekitStyles` directive |

### 3 · Token alignment

Compares your Tailwind-side CSS custom properties against the matching WireKit-side tokens and reports every pair whose values disagree. Example: a `--font-sans: 'Inter'` declaration in your `app.css` against WireKit's `--font-wk-sans: 'Instrument Sans'` is reported as a mismatch. Pairs where either side is a `var(...)` reference (intentional alias) are skipped.

| Token pair | What it covers |
|------------|----------------|
| `--font-sans` ↔ `--font-wk-sans` | Sans serif font family — drives both Tailwind utilities (`font-sans`) AND WireKit chrome |
| `--font-serif` ↔ `--font-wk-serif` | Serif font family |
| `--font-mono` ↔ `--font-wk-mono` | Monospace font family |
| `--color-accent` ↔ `--color-wk-accent` | Accent color — your brand primary vs. WireKit's primary surface |
| `--color-accent-foreground` ↔ `--color-wk-accent-fg` | Accent foreground (for contrast against accent) |
| `--radius` ↔ `--radius-wk` | Border radius scale — keeps Tailwind utilities visually consistent with WireKit components |
| `--shadow` ↔ `--shadow-wk` | Box-shadow scale |

For each pair the doctor emits one of three states:

- **`✓ aligned`** — the two tokens resolve to the same value (after normalization).
- **`⚠ mismatch`** — the values differ. Output includes both literal values plus an actionable fix hint.
- **`i skipped`** — either the Tailwind side is a `var(...)` reference (intentional alias) or the token is unset on one side. Skipped checks don't count as warnings.

### 4 · Light/dark token symmetry

Compares the `--color-wk-*` tokens declared in your `:root {}` block against those in your `.dark {}` block. Missing entries on either side mean the corresponding component will inherit a stale value when the theme flips — your end-users see this as "looks wrong in dark mode" without an obvious cause.

| Check | Pass criterion |
|-------|----------------|
| `:root` vs `.dark` color-token symmetry | Every `--color-wk-*` declared in one block is also declared in the other |

Output shapes:

- **`✓`** — both blocks declare the same set of `--color-wk-*` tokens (or neither block exists; the check stays silent).
- **`⚠`** — at least one token is asymmetric. The warning lists the missing token names per block.

The check is **scoped to color tokens only**. Font, radius, and shadow tokens are intentionally theme-agnostic (declared once in `:root`, never repeated in `.dark`), so the doctor doesn't flag those.

### 5 · Alpine plugin cleanup hygiene

Static-analysis scan of your `resources/js/` tree for custom Alpine plugins. Flags two anti-patterns that commonly produce silent `TypeError` console errors after Livewire morph / conditional render / SPA navigation tears down a host element while a browser-queued observer callback is still in flight.

| Anti-pattern | What the doctor looks for |
|--------------|--------------------------|
| Observer without `destroy()` | A file containing `new IntersectionObserver(...)` / `new MutationObserver(...)` / `new ResizeObserver(...)` that has NO `destroy()` lifecycle method. Without `destroy()`, the observer holds the host-element reference forever and prevents garbage collection. |
| Unguarded in-callback `disconnect()` | A file containing both `.disconnect()` AND an observer instantiation, but no `if (! this._<observer>) return;` early-return OR `this._<observer>?.disconnect()` optional-chaining form. Without the guard, callbacks queued before destroy() throw `TypeError: Cannot read properties of null (reading 'disconnect')`. |

Output shapes:

- **`✓`** — no anti-patterns detected, OR `resources/js/` doesn't exist (developers without custom plugins skip the check entirely).
- **`⚠`** — one or more files match a heuristic. The warning lists each file + the specific anti-pattern(s) detected.

Opt out for a file that intentionally uses a pattern the heuristic doesn't recognize (for example, the observer reference is captured in a closure-local variable rather than `this._observer`): add this comment marker anywhere in the file:

```javascript
// wirekit-doctor: cleanup-ok
```

The doctor will skip that file. Use sparingly — most intentional exemptions in practice turn out to be bugs on closer inspection. See [Authoring Custom Alpine Plugins](../extending/authoring-custom-alpine-plugins.md) for the canonical defensive-cleanup pattern WireKit's own plugins follow.

## Example output

```text
WireKit Integration Check

  ✓ wirekit.css published
  ✓ wirekit.js published
  ✓ wirekit.css is up to date
  ✓ Tailwind @source includes WireKit templates
  ✓ config/wirekit.php published
  ✓ Blade directives configured
  ✓ JS bundle configured: full
  ✓ Built app CSS contains WireKit utility rules

  Token alignment:
    ✓ Sans font: aligned (inter)
    ⚠ Serif font: mismatch — Tailwind `'Lora', serif` vs WireKit `'Playfair Display', serif`. Fix: php artisan wirekit:install --font-serif=<key>
    i Mono font: skipped (Tailwind-side token unset)
    ✓ Accent color: aligned (oklch(60% 0.2 250))
    i Accent foreground: skipped (var(...) reference — intentional alias)
    ✓ Border radius: aligned (0.5rem)
    i Shadow: skipped (Tailwind-side token unset)

  9 passed, 1 warnings, 0 failed
```

## Common failures and fixes

> Each subsection below quotes the exact doctor line that triggered it (in a code block) followed by what it means and how to fix it. The `⚠` glyph indicates a warning; `i` is informational; `✓` confirms alignment.

### Sans font mismatch

```text
⚠ Sans font: mismatch — Tailwind 'Inter' vs WireKit 'Roboto'
```

Your `font-sans` Tailwind utilities will render Inter while WireKit components render Roboto. Pick one and run:

```bash
php artisan wirekit:install --font=<key>
```

(see [`wirekit:install` flag table](../cli-reference.md#wirekitinstall) for available keys)

This writes BOTH `--font-sans` AND `--font-wk-sans` to the same family in your `app.css` — guaranteed alignment.

### Accent color mismatch

```text
⚠ Accent color: mismatch — Tailwind oklch(60% 0.2 250) vs WireKit oklch(50% 0.3 30)
```

Tailwind's `bg-accent` will render blue while `<x-wirekit::button>` renders red. Either:

- Update your `@theme { --color-accent: ... }` block to match WireKit, or
- Override `--color-wk-accent` in `:root` to match your brand

The token alignment doctor doesn't auto-fix color tokens (unlike fonts) because brand identity is too project-specific to template.

### Sans font skipped (token unset)

```text
i Sans font: skipped (token unset)
```

You haven't set `--font-sans` (or `--font-wk-sans`) — likely you're using the bundled WireKit defaults on both sides. No action required; the skip is informational.

### Light/dark color-token asymmetry

```text
⚠ Light/dark color-token symmetry — :root has 3 token(s) missing from .dark: --color-wk-bg-elevated, --color-wk-border, --color-wk-text-muted
```

Your `:root {}` declares color tokens that aren't repeated in `.dark {}` (or vice versa). When the theme flips, the missing-side block inherits whatever the cascade resolves to — usually a stale value from the other block. Developers see this as "the dark variant of this card looks wrong" without an obvious source.

Add the missing tokens to whichever block lacks them. Every WireKit-shipped color token has both a light and a dark value; the rule of thumb is one declaration per block per token.

### `resources/css/app.css` not found

```text
⚠ resources/css/app.css not found
```

You're running the doctor from a fresh checkout that hasn't run `wirekit:install` yet, OR your CSS lives at a non-standard path. Run `wirekit:install` first, or set up `app.css` manually per the [Integration guide](../getting-started/integration.md).

## CI integration

`wirekit:doctor` exits with status code `1` when any check fails (warnings don't fail the build). Wire it into your CI:

```yaml
# .github/workflows/test.yml
- name: WireKit integration check
  run: php artisan wirekit:doctor
```

Or as a Claude Code stop-hook:

```json
// .claude/settings.json
{
  "hooks": {
    "Stop": [
      { "type": "command", "command": "php artisan wirekit:doctor" }
    ]
  }
}
```

## Aliases and history

- `wirekit:doctor` is the canonical name.
- `wirekit:verify` is the back-compat alias — same code path, identical output.

## See Also

- [`wirekit:install`](../cli-reference.md#wirekitinstall) — initial setup; provides the `--font*` flags that the doctor's token-alignment checks reference.
- [Integration guide](../getting-started/integration.md) — full setup from `composer require` through asset wiring.
- [Design Tokens](../theming/design-tokens.md) — design-token reference (helpful when interpreting mismatch hints).
