dial-up-loader
A retro React loader that renders an old-school modem terminal and synthesises dial-up handshake sounds with the Web Audio API.
Installation
npm install dial-up-loader
Peer dependencies
react >= 16.8
Quick Start
import { DialUpLoader } from 'dial-up-loader'; export function App() { return <DialUpLoader autoPlay={false} />; }
Props
DialUpLoaderProps
| Prop | Type | Default | Description |
|---|---|---|---|
sound |
boolean |
true |
Enables synthesized modem audio. |
autoPlay |
boolean |
false |
Automatically starts the sequence on mount. |
message |
string |
stage message | Overrides the default status text. |
size |
'sm' | 'md' | 'lg' |
'md' |
Controls font and modem art sizing. |
theme |
'dark' | 'light' |
'dark' |
Selects dark or light terminal styling. |
className |
string |
— | Additional root class name. |
style |
React.CSSProperties |
— | Inline styles merged onto the root element. |
speed |
number |
1 |
Playback speed multiplier. |
active |
boolean |
true |
Stops playback and marks the loader idle when false. |
onConnect |
() => void |
— | Called after the full connection sequence completes. |
onStop |
() => void |
— | Called when the loader is deactivated. |
loop |
boolean |
false |
Replays the whole sequence after completion. |
showModem |
boolean |
true |
Shows ASCII modem art. |
showProgress |
boolean |
true |
Shows the terminal-style progress bar. |
showLeds |
boolean |
true |
Shows animated modem LEDs. |
aria-label |
string |
computed | Accessible status label for assistive tech. |
useDialUpSound(options)
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Enables sound playback. |
speed |
number |
1 |
Playback speed multiplier. |
onComplete |
() => void |
— | Called after the full modem sequence finishes. |
UseDialUpSoundReturn
| Field | Type | Description |
|---|---|---|
play |
() => Promise<void> |
Starts the dial-up sequence. |
stop |
() => void |
Stops playback and resets the hook. |
isPlaying |
boolean |
Indicates whether the sequence is active. |
stage |
ConnectionStage |
Current stage: idle, dialing, ringing, negotiating, connected, or error. |
progress |
number |
Current progress from 0 to 100. |
Browser autoplay note
Modern browsers often block audio playback until the user interacts with the page. If autoPlay is enabled, visuals may start immediately, but sound can still require a click or tap depending on browser policy.
Next.js / SSR
Built files already include "use client" via the bundler banner, so the package works cleanly in the Next.js App Router. Style injection only runs in the browser.
Examples
Demo
npm install npm run demo:dev
For a static bundle:
The raw demo\index.html file is not meant to be opened directly from disk. Use the scripts above so the package build exists and the demo is served with the correct module handling.
Auto play
<DialUpLoader autoPlay />
Looping playback
<DialUpLoader autoPlay loop />
Light theme
<DialUpLoader theme="light" />
Custom message
<DialUpLoader message="Negotiating with the mothership..." />
Headless hook
import { useDialUpSound } from 'dial-up-loader'; export function HeadlessDialer() { const { play, stop, stage, progress, isPlaying } = useDialUpSound({ enabled: true, speed: 1.25, }); return ( <div> <button onClick={() => void play()} disabled={isPlaying}> Start </button> <button onClick={stop}>Stop</button> <p>{stage}</p> <p>{progress}%</p> </div> ); }
Contributing
Issues and pull requests are welcome. Please run install, build, lint, and test locally before opening a PR.
License
MIT © 2025