# Cache Badge

Cache Badge [#cache-badge]

The **Cache Badge** annotates a result as served from the semantic cache, optionally with the hit latency (e.g. "cached · 12ms"). Local apps cache responses on-device; surfacing a cache hit makes that invisible speedup legible. Drive `cached`/`latencyMs` from your `useSemanticCache` lookup result. It renders nothing when `cached` is false, so it is safe to drop next to any result.

Preview [#preview]

```tsx
'use client';

import { CacheBadge } from '@/components/cache-badge';

/**
 * Demo for CacheBadge. Shows a cached annotation with and without latency next
 * to a mock assistant reply; the un-cached variant renders nothing.
 */
export default function CacheBadgeDemo() {
  return (
    <div className="flex w-full max-w-md flex-col gap-3">
      <div className="flex items-center gap-2 rounded-lg border border-border bg-card px-3 py-2 text-sm">
        <span className="flex-1">The capital of France is Paris.</span>
        <CacheBadge cached latencyMs={12} />
      </div>
      <div className="flex items-center gap-2 rounded-lg border border-border bg-card px-3 py-2 text-sm">
        <span className="flex-1">Served from cache, no latency shown.</span>
        <CacheBadge cached />
      </div>
    </div>
  );
}
```

Installation [#installation]

```bash
npx shadcn@latest add @localmode/ui/local-first/cache-badge
```

Dependencies [#dependencies]

* `lucide-react` — icons
* `clsx` + `tailwind-merge` — via the shared `cn()` util (installed automatically as a registry dependency)

Files installed [#files-installed]

* `cache-badge.tsx` — the `CacheBadge` component
* `lib/utils.ts` — the `cn()` helper (if not already present)

Props [#props]

**CacheBadge**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `cached` | `boolean` | — | **Required.** Whether the annotated result was served from the semantic cache. When false, nothing renders. |
| `latencyMs` | `number` | — | Optional cache-hit latency in milliseconds (e.g. 12 → "cached · 12ms"). |
| `label` | `string` | `"cached"` | Label override for the cached state. |

Examples [#examples]

Annotate a cached reply [#annotate-a-cached-reply]

```tsx
const result = await cache.lookup({ prompt, modelId });
<CacheBadge cached={result.hit} latencyMs={result.durationMs} />
```

Customization [#customization]

Uses the `emerald` palette to read as a positive signal. Because it returns `null` when `cached` is false, you can render it unconditionally next to every result. Styled entirely with shadcn/ui CSS-variable utilities so it inherits your theme — because you own the copied file, every class and threshold is yours to change.