npm package: @remcostoeten/dev-widget
Description: Minimal, portable dev menu widget for React applications
Author: Remco Stoeten
Latest version: 0.0.1

# @remcostoeten/dev-widget

[![npm version](https://img.shields.io/npm/v/@remcostoeten/dev-widget)](https://www.npmjs.com/package/@remcostoeten/dev-widget)
[![CI](https://github.com/remcostoeten/dev-widget/actions/workflows/ci.yml/badge.svg)](https://github.com/remcostoeten/dev-widget/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Minimal, type-safe dev widget for React apps.

## Installation

```bash
bun add @remcostoeten/dev-widget
```

## React usage

```tsx
import { DevWidget } from '@remcostoeten/dev-widget/react'

export function App(): React.ReactElement {
	return (
		<>
			<main>App</main>
			<DevWidget
				mode='development-only'
				theme={{ mode: 'system', accent: '#3bb273' }}
				features={{
					performance: { enabled: true, fpsThreshold: 50 },
					auth: { enabled: true, provider: 'better-auth' }
				}}
			/>
		</>
	)
}
```

## Features

- Auth domain
- Routes domain
- Links domain
- Performance domain
- System domain
- Monitor domain

## Feature checklist

- [x] React widget shell with tab categories
- [x] Domain lifecycle (setup/start/stop) via runtime registry
- [x] Plugin API with typed event subscription
- [x] Event bus for cross-domain communication
- [x] Next.js log ingestion route handler
- [x] In-memory storage adapter
- [x] Tauri storage adapter export
- [x] Route discovery adapter for Next.js and React projects
- [x] Right rail with diagnostics render panel
- [x] Keyboard shortcuts (toggle + Escape)
- [x] Accessibility: focus-visible, reduced-motion handling, live region announcements
- [x] Internal subpath export (`@remcostoeten/dev-widget/internal`)
- [x] Source maps and declaration output in package build
- [x] CI publish artifact validation step
- [x] Demo app build pipeline

## Needs additional work

- AI providers: `openai` and `local` modes are declared but not implemented yet; only `rules` and `custom` are active (`src/domains/performance/aiProviderFactory.ts`).
- Runtime prop updates: `DevWidget` memoizes runtime by `shouldRender` only, so runtime does not re-bootstrap when non-visibility props change after mount (`src/devWidget.tsx`).
- Storage wiring: `providers.storage` is part of public config but not wired into runtime/domain persistence flow yet (`src/types/public.ts` and `src/core/bootstrap.ts`).
- Endpoint validation: Next log handler accepts event payloads without schema validation; malformed event shapes can be persisted (`src/adapters/next/routeHandler.ts`).
- CI parity: local checks pass, but final release confidence still depends on a pushed branch and green remote GitHub Actions run.

## Plugin API

```ts
import { createRuntime } from '@remcostoeten/dev-widget'

const runtime = createRuntime({ mode: 'always' })

await runtime.registerPlugin({
	id: 'my-plugin',
	version: '1.0.0',
	register(ctx) {
		ctx.onEvent('performance/drop-detected', function onDrop(payload) {
			console.log('FPS drop:', payload.fps)
		})
	}
})
```

## Subpath exports

```ts
import { DevWidget } from '@remcostoeten/dev-widget/react'
import { createLogHandler } from '@remcostoeten/dev-widget/next'
import { createTauriStorage } from '@remcostoeten/dev-widget/tauri'
import type { WidgetDomain } from '@remcostoeten/dev-widget/internal'
```

## Accessibility

The widget includes keyboard shortcuts, focus-visible styling, live announcements, and reduced-motion support.
See `specs/10-dev-widget-accessibility-keyboard-spec.md` for the detailed behavior contract.

## Core options

- `enabled?: boolean`
- `mode?: 'development-only' | 'always'`
- `theme?: { mode?: 'system' | 'light' | 'dark'; accent?: string; density?: 'compact' | 'comfortable'; radius?: 'none' | 'sm' | 'md' | 'lg' }`
- `features?: { auth?: boolean | AuthOptions; routes?: boolean | RoutesOptions; performance?: boolean | PerfOptions; system?: boolean | SystemOptions; links?: boolean | LinksOptions }`
- `disable?: FeatureId[]`
- `providers?: { auth?: AuthConfig; ai?: AiConfig; storage?: StorageConfig }`
- `keyboard?: { toggleKey?: string; enableShortcuts?: boolean }`
- `accessibility?: { reducedMotion?: 'system' | 'always' | 'never'; announceUpdates?: boolean }`
- `rightRail?: { enabled?: boolean; defaultPanel?: string | null; collapsible?: boolean; panels?: PanelConfig[] }`

## Changelog

- [CHANGELOG.md](CHANGELOG.md)

## Contributing

```bash
bun run lint
bun run format:check
bun run type-check
bun test
bun run build
```

## License

MIT