Development & releases
npm run package:buildnpm run package:checknpm run typechecknpm testnpm run buildnpx playwright install chromiumnpm run test:e2enpx jsr publish --dry-run --allow-dirtyUnit tests cover configuration, authentication failure, timeouts, call/permission races, busy handling, duplicate terminal events, media cleanup, transfer success/failure, and preview behavior. Browser tests exercise the UI on desktop/mobile and run automated WCAG accessibility checks. They also verify prefill/automatic dialing under StrictMode, no repeat attempts after reconnection or microphone denial, WebGL fallback, reduced motion, and borrowed-stream cleanup. A local SIP registrar/proxy connects two actual JsSIP browser clients, automatically dials after digest registration, and verifies two-way WebRTC audio, mute, hold/resume, DTMF sending, and hangup. This does not validate your production PBX or TURN setup; complete a live call with a second registered endpoint before deployment.
| Directory | Responsibility |
|---|---|
src/core/ |
SIP state, media ownership, validation, public event types |
src/react/ |
Provider and external-store hook |
src/components/ |
Presets, composable controls, scoped themes |
src/components/elevenlabs/ |
Attributed ElevenLabs UI Orb/shader and waveform adaptations |
publish/ |
Generated JSX-free TypeScript for JSR; do not edit directly |
demo/ |
React playground; excluded from the published source package |
tests/ |
Lifecycle unit tests and desktop/mobile browser tests |
Documentation and Pages
Section titled “Documentation and Pages”npm cinpm ci --prefix docsnpm run docs:dev# Build documentation and the playground as one Pages artifact:npm run site:buildStarlight serves /react-phone/; the React playground is copied to /react-phone/playground/. Both use the same GitHub Pages deployment. The documentation uses neutral dark tokens and Geist typography; it has no runtime dependency on the phone widget. Mermaid diagrams are rendered to static SVG with npm run docs:diagrams (install Playwright Chromium first).
Publish to JSR
Section titled “Publish to JSR”The package name and entry points are in jsr.json. Generated publish/ sources, README, and license notices are explicitly allowlisted; the demo, credentials, test results, and development files are excluded.
Edit the original TypeScript/TSX in src/, then run npm run package:build and commit the generated publish/ tree. This lowers JSX to React runtime calls while retaining public TypeScript annotations and documentation. JSR’s npm bridge can then emit ordinary JavaScript without leaving TSX files containing npm: imports. CI runs npm run package:check to reject stale generated files. The committed output also keeps the supplied Publish workflow build-free.
The published package targets React 19. A small generated declaration bridge also avoids JSR rewriting type imports into invalid @types/react imports. It aliases React’s original types without runtime code.
After publication, npm run test:consumer installs the exact release into a temporary, independent React app. It checks strict declarations with skipLibCheck: false, a Vite production build, and browser calls using both public entry points. The Published consumer workflow runs this automatically after Publish succeeds; PHONE_PACKAGE_VERSION can select an earlier published version when troubleshooting. Building this repository’s playground alone does not test JSR’s npm conversion.
nodeModulesDir: "auto" lets the publisher resolve dependencies in a clean checkout without an npm install step. lock: false prevents the publisher from generating a second lockfile that would make the release checkout dirty; normal development uses the committed package-lock.json.
# Validate locally without uploading a release.npx jsr publish --dry-run --allow-dirty
# Publish after reviewing and committing the release.npx jsr publishThe supplied .github/workflows/publish.yml is preserved exactly: pushes to main publish with GitHub OIDC through the linked alshell7/react-phone repository. Keep package.json and jsr.json versions in sync. Bump both for a new release; JSR versions are immutable. The independent check.yml runs types, unit/browser tests, build, and publishing validation. Configure branch protection to require Check before merging; the requested Publish workflow does not depend on that job.
License & attribution
Section titled “License & attribution”MIT © Owais. ElevenLabs UI supplies the adapted Orb and waveform components; JsSIP handles SIP/WebRTC. react-softphone informed the tutorial/architecture approach. See THIRD_PARTY_NOTICES.md for attribution and licenses. No ElevenLabs API key is needed.