# OpenSpec Change: react-network-libp2p-demo - **Change ID**: react-network-libp2p-demo - **Package**: `@suaveplan/react-network-libp2p-demo` - **Category**: react (browser, React-tier) - **Target path**: `packages/react/react-network-libp2p-demo` - **Status**: PROPOSED - **Date**: 2026-05-11 - **Parent**: `network-transport-family` (2026-05-11) — Wave 7 - **Related**: `network-transport-libp2p` (Wave 4) — this package extracts the upstream `libp2p-demo.tsx` so the transport package can stay React-free. --- ## Summary Net-new genesis package that houses the React demo UI for `@suaveplan/network-transport-libp2p`. Upstream `network-libp2p` shipped a 749-LOC `libp2p-demo.tsx` plus Storybook story inside the transport package; per CLAUDE.md the transport must stay React-free, so the demo migrates here. --- ## Why a separate package The upstream `network-libp2p` package mixes a universal-tier `Libp2pTransport` class with a 749-line React component, breaking the tier-isolation rule. Two options: - **Delete the demo** — clean but loses a useful runnable example. - **Extract to its own package** — preserves the demo as a working reference, keeps the transport React-free. This proposal chooses extraction. The demo lives in `packages/react/react-network-libp2p-demo/` and the transport package's parity checklist marks the demo as "🚫 dropped → migrated separately here". --- ## Current-state audit Upstream source: - `../suaveplan/packages/browser/network-libp2p/src/lib/libp2p-demo.tsx` (749 LOC) — over 300-line cap, needs splitting - `../suaveplan/packages/browser/network-libp2p/src/lib/libp2p-demo.stories.tsx` (211 LOC) --- ## Parity Checklist | Capability | Upstream | Migrated | Notes | |---|---|---|---| | `Libp2pDemo` component | ✅ | ✅ | Split into per-concern subcomponents ≤300 LOC each. | | Storybook stories | ✅ | ✅ | Default + playground + variants per CLAUDE.md. | | React runtime dep | ✅ | ✅ | Belongs at this tier. | | Direct libp2p import | upstream-bundled | ⬆️ | Consume via `@suaveplan/network-transport-libp2p` ✅ (Wave 4). | | Hardcoded bootstrap | check | 🚫 | Demo accepts bootstrap list as a prop; no public defaults. | | Storybook docs | partial | ⬆️ | Story descriptions cover use case + caveats. | | Test coverage | low (it's a demo) | partial | Snapshot tests + interaction tests via `@suaveplan/testing-dom`; not 100% (per CLAUDE.md demos are stories-not-tests). | --- ## Available workspace deps on genesis - `@suaveplan/network-transport-libp2p` ⬅ Wave 4 (required) - `@suaveplan/network` ✅ - `@suaveplan/testing-dom` ✅ - External: `react`, `react-dom`, `@react-three/fiber` (only if demo uses 3D). --- ## Acceptance gate 1. `bunx turbo lint typecheck --filter=@suaveplan/react-network-libp2p-demo` green. 2. Every source file ≤300 LOC. 3. Storybook stories cover every subcomponent. 4. Demo runs locally against a user-supplied bootstrap list (no hardcoded public defaults). 5. `STATUS.md` row added with `❌` (net-new) → flipped to `✅` on landing. --- ## Out of scope - Hosting the demo as a standalone site (deployment). - Production-grade UI polish — it's a reference demo.