JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 26
  • Score
    100M100P100Q63599F
  • License MIT

Drop-in React teleprompter — auto-scroll, mirror, section labels, keyboard control. Zero deps.

Package Exports

  • @datatechsolutions/teleprompter

Readme

@datatechsolutions/teleprompter

Drop-in React teleprompter — voice-paced auto-scroll, mirror, section labels, keyboard control.

Teleprompter demo

npm license bundle size zero deps react 18 or 19 tests


Why I built this

I needed a teleprompter for my YC pitch. Existing options were either $400 desktop apps, ad-walled freemium sites, or browser tools that couldn't mirror text for an autocue rig without paying. So I shipped this in a weekend and used it live.

Open-sourced because every founder doing a demo needs this, and nobody should have to learn FFmpeg to get text scrolling on screen.

npm install @datatechsolutions/teleprompter
import { Teleprompter } from '@datatechsolutions/teleprompter'

const SCRIPT = `// 0–5s · Hook
Hey YC. I'm Natalia, building Astrlabe.

// 5–13s · Credibility
Brazilian. Electrical engineer. Ten years as a data scientist.`

export default function PitchPage() {
  return <Teleprompter initialScript={SCRIPT} targetDuration="01:00" />
}

That's the whole thing. Click anywhere to play, click to pause, edit the script with the pencil button, hit M to mirror the text for behind-glass rigs.

What you get

  • 🎤 Voice-paced auto-scroll — mic listens, WPM is measured, scroll follows your speaking pace in real time. Pure Web Speech API, zero backend
  • 🎬 Manual auto-scroll — 10–300 px/sec, adjustable live (fallback when voice pacing is off or unsupported)
  • 🎨 Section labels// 0–5s · Hook syntax for free
  • 🔄 Mirror mode — for autocue rigs that read off a beam-splitter
  • ⌨️ Keyboard shortcuts — Space, ↑↓, +/-, M, E, R
  • 🌗 Edge fade gradients — text materialises and dissolves cinema-style
  • 📊 Progress bar + elapsed/target timer — pace yourself live
  • 🎯 Configurable accent colour — match your brand in one prop
  • 💾 localStorage persistence — drafts survive reload (opt-out via prop)
  • 📦 ESM + CJS + types — works in any modern React app
  • prefers-reduced-motion aware — respects OS setting automatically
  • 🚫 Zero runtime dependencies — only React as peer
Headless variant — full control over markup
import { useTeleprompter } from '@datatechsolutions/teleprompter'

function MyTeleprompter() {
  const { lines, isPlaying, togglePlay, scrollerRef, fontSize, mirror } =
    useTeleprompter({ initialScript: 'Hello world' })

  return (
    <div ref={scrollerRef} onClick={togglePlay} style={{ overflow: 'auto' }}>
      {lines.map((line, i) => (
        <p key={i} style={{ fontSize, transform: mirror ? 'scaleX(-1)' : undefined }}>
          {line.text}
        </p>
      ))}
    </div>
  )
}

The hook handles requestAnimationFrame, keyboard, localStorage, elapsed timer — you decide how to render.

Voice-paced autoscroll — how it works

Enable from the component:

<Teleprompter initialScript={SCRIPT} voicePaced />

…or tune the pacing model:

<Teleprompter
  initialScript={SCRIPT}
  voicePaced={{
    lang: 'pt-BR',
    windowMs: 5000,        // sliding window for WPM averaging
    targetWpm: 150,        // pace that maps to baselineSpeed
    baselineSpeed: 60,     // px/sec at targetWpm
  }}
/>

Mid-talk, the controls show a live 142 WPM readout. Click the mic button (or remove voicePaced prop) to fall back to manual speed.

Browser support: Chromium-based browsers (Chrome, Edge, Brave, Arc) on desktop + Android Chrome. The mic button auto-hides on unsupported browsers — you don't need to gate the prop yourself.

Standalone hook (use without the component):

import { useVoicePaced } from '@datatechsolutions/teleprompter'

const { supported, active, wpm, derivedSpeed, toggle } = useVoicePaced({
  lang: 'en-US',
})

Returns a speed in px/sec that follows the speaker's WPM — wire it into whatever scroll loop you already have.

Tailwind required

This package uses Tailwind utility classes. Add the dist path to your project's tailwind.config.js content array so the classes get generated:

export default {
  content: [
    './src/**/*.{ts,tsx}',
    './node_modules/@datatechsolutions/teleprompter/dist/**/*.{js,mjs,cjs}',
  ],
}

Without that line, the teleprompter renders unstyled. We picked Tailwind because the package is small and Tailwind classes mean zero CSS to ship — your bundle stays lean.

Props

<Teleprompter />

Prop Type Default Notes
initialScript string '' Lines starting with // render as section labels. Blank lines = visual gaps.
storageKey string | null @datatechsolutions/teleprompter:v1 Pass null to disable persistence.
initialSpeed number 60 Scroll speed in px/sec.
initialFontSize number 32 / 44 / 56 Auto-picks based on viewport width.
enableKeyboard boolean true Wire Space / ↑↓ / +/- / M / E / R.
speedRange { min, max, step } { 10, 300, 10 } Bounds for speed bumps.
fontSizeRange { min, max, step } { 20, 120, 4 } Bounds for font size bumps.
targetDuration string | null '01:00' Shown next to elapsed timer.
voicePaced boolean | VoicePacedOptions false Enable mic-driven autoscroll. See voice-paced section.
enableEditing boolean true Show the in-built edit modal.
controlsAccessory ReactNode Extra UI in the control bar.
keyboardHint string | null (default hint string) Override or hide the hint at the bottom.
accentColor string #8b5cf6 (violet-500) Accent driving controls, marker, progress bar.
showProgressBar boolean true Thin accent line at viewport bottom.
fadeEdges boolean true Soft fade gradients top + bottom.
reducedMotion boolean OS preference Disable marker pulse + smooth easing.

useTeleprompter()

Returns:

  • lines — parsed script (comment vs body)
  • scriptText / setScriptText
  • isPlaying / play / pause / togglePlay / reset
  • speed / setSpeed / bumpSpeed
  • fontSize / setFontSize / bumpFontSize
  • mirror / toggleMirror
  • elapsedMs
  • scrollerRef — attach to your scroll container

Script syntax

// Section label — uppercase tracking, smaller font, accent color
Body line one — large body text, what the speaker reads.
Body line two.

// Next section (blank lines above add a gap)
Another section.

That's it. No markdown, no escaping. The // prefix is matched after trimming, so leading whitespace is fine.

Keyboard shortcuts

Key Action
Space Play / pause
/ Speed +10 / -10 px/s
+ / - Font size +4 / -4 px
M Toggle mirror
E Open edit modal
R Reset to top

Shortcuts are disabled while typing in <input> / <textarea>.

Brand it

Match your accent in one prop:

<Teleprompter accentColor="#10b981" />   {/* emerald */}
<Teleprompter accentColor="#f97316" />   {/* orange */}
<Teleprompter accentColor="#06b6d4" />   {/* cyan */}

The colour drives section labels, the centre reader marker, the progress bar, the active mirror button, and the Save & reset gradient — so the whole UI shifts in sync.

FAQ

Does it work without Tailwind? Not yet. v1.0.0 will optionally ship a vanilla CSS sheet — see #4.

Is the AI version free? v0.4.0 will add AI script generation + tone shift via a hosted proxy. Free tier capped. See RFC #14.

Mobile? Works today (responsive control bar, viewport-aware font size). Touch gestures (swipe / pinch) coming in v0.3.0 — #12.

SSR? Yes — parseScript and the hook short-circuit on typeof window === 'undefined', so Next.js / Remix work without 'use client' directives at the import level. The component itself uses useEffect so wrap it in client boundary if your framework demands it.

Development

npm install
npm test           # vitest run — 39 unit tests
npm run build      # tsup → ESM + CJS + types
npm run type-check

End-to-end Playwright tests live in examples/playground/ and run against a real Vite dev server consuming the package via npm link.

Contributing

Issues + PRs welcome. The roadmap is public — every milestone lives as a GitHub EPIC tagged roadmap:

  • v0.3.0 — timing intelligence (in progress; voice-paced ✅, structured sections + touch gestures still open)
  • v0.4.0 Whisper backend — opt-in client-side Whisper for Firefox/Safari support + multi-language accuracy
  • v0.4.0 AI Co-pilot — write & rewrite scripts via LLM

License

MIT — see LICENSE.