npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pie-players/pie-tool-text-to-speech

v0.1.9

Published

Text-to-Speech tool for PIE assessment player with word-level highlighting

Downloads

807

Readme

Text-to-Speech Tool (<pie-tool-text-to-speech>)

A draggable, floating tool that reads selected text aloud with word-level highlighting for accessibility.

Features

  • Text Selection: Automatically detects selected text on the page
  • Word Highlighting: Highlights each word as it's spoken (yellow background + underline)
  • Speed Control: Adjustable speech rate from 0.5x (Slow) to 2.0x (Very Fast)
  • Playback Controls: Play, Pause/Resume, and Stop buttons
  • Visual Feedback: Status indicator shows speaking/paused state
  • Draggable: Move the tool anywhere on screen
  • Accessibility: Full keyboard support and screen reader compatible

Usage

As Web Component

<pie-tool-text-to-speech
  visible="true"
  tool-id="textToSpeech"
></pie-tool-text-to-speech>

As Svelte Component

<script>
  import { ToolTextToSpeech } from '$lib/tags/tool-text-to-speech';
  import { toolCoordinator } from '$lib/assessment-toolkit/tools';

  let visible = false;
</script>

<ToolTextToSpeech
  {visible}
  toolId="textToSpeech"
  coordinator={toolCoordinator}
/>

Via Tool Toolbar

The TTS tool is automatically included when using <pie-tool-toolbar>:

<pie-tool-toolbar tools="protractor,ruler,textToSpeech"></pie-tool-toolbar>

How It Works

  1. Select Text: User selects any text on the page
  2. Click Play: Tool reads the selected text aloud
  3. Word Highlighting: Each word is highlighted with yellow background and underline as it's spoken
  4. Adjust Speed: Use the slider to change speech rate (0.5x - 2.0x)
  5. Pause/Resume: Pause and resume playback at any time
  6. Stop: Stop playback and clear highlights

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | visible | Boolean | false | Show/hide the tool | | toolId | String | 'textToSpeech' | Unique identifier for the tool | | coordinator | ToolCoordinator | Required | Tool coordination service |

TTS Service Integration

The tool uses the shared TTSService from $lib/services/tts:

import { ttsService } from '$lib/services/tts';

// Initialize
await ttsService.initialize();

// Set root element for highlighting
ttsService.setRootElement(containerElement);

// Speak with options
await ttsService.speak(text, {
  rate: 1.0,
  highlightWords: true
}, {
  onEnd: () => { /* cleanup */ },
  onError: (error) => { /* handle error */ }
});

Browser Support

Text-to-Speech (Web Speech API)

  • ✅ Chrome 33+
  • ✅ Safari 7+
  • ✅ Edge 14+
  • ✅ Firefox 49+
  • ✅ Mobile: iOS 7+, Android 4.4+
  • Coverage: 97%+ of users

Word Highlighting (CSS Custom Highlight API)

  • ✅ Chrome 105+
  • ✅ Safari 17.2+
  • ✅ Edge 105+
  • ✅ Firefox 128+
  • Coverage: 85-90% of users

The tool gracefully degrades: TTS works everywhere, highlighting only on modern browsers.

Accessibility

  • Screen Reader Compatible: Uses Web Speech API which doesn't interfere with screen readers
  • Keyboard Navigation: Tool can be moved with keyboard (when focused)
  • High Contrast: Works with high contrast mode
  • Reduced Motion: Respects prefers-reduced-motion setting
  • ARIA Labels: All buttons have proper aria-label attributes

Speed Presets

| Value | Label | Description | |-------|-------|-------------| | 0.5x | Slow | Half speed | | 0.75x | Slower | 3/4 speed | | 1.0x | Normal | Default speed | | 1.25x | Faster | 1.25x speed | | 1.5x | Fast | 1.5x speed | | 2.0x | Very Fast | Double speed |

Visual Design

The tool features:

  • Purple gradient header (matches other PIE tools)
  • Clean, modern UI with rounded corners
  • Responsive buttons with hover/disabled states
  • Status indicators with animated pulse
  • Color-coded feedback: Green (speaking), Yellow (paused), Red (error)

Error Handling

The tool handles these error scenarios:

  1. TTS Not Supported: Shows error message if browser doesn't support Web Speech API
  2. No Text Selected: Disables play button until text is selected
  3. Speech Errors: Shows error message and stops playback
  4. Network Issues: Gracefully handles offline scenarios (Web Speech API works offline)

Performance

  • Lightweight: ~15KB minified
  • No Dependencies: Uses browser-native APIs
  • Efficient: Only highlights visible text, no DOM mutation
  • Memory Safe: Cleans up event listeners on unmount

Example: Complete Integration

<script>
  import { ToolTextToSpeech } from '$lib/tags/tool-text-to-speech';
  import { toolCoordinator } from '$lib/assessment-toolkit/tools';
  import { onMount } from 'svelte';

  let showTTS = false;

  onMount(() => {
    // Register tool
    toolCoordinator.registerTool('textToSpeech', 'Text-to-Speech');
  });

  // Subscribe to tool visibility
  $: {
    const state = toolCoordinator.getToolState('textToSpeech');
    showTTS = state?.isVisible ?? false;
  }
</script>

<!-- Assessment content -->
<div class="question-prompt">
  <p>Read this question carefully and select the best answer.</p>
</div>

<!-- TTS button -->
<button on:click={() => toolCoordinator.toggleTool('textToSpeech')}>
  🔊 Text-to-Speech
</button>

<!-- TTS tool -->
<ToolTextToSpeech
  visible={showTTS}
  toolId="textToSpeech"
  coordinator={toolCoordinator}
/>

Future Enhancements

  • [ ] Voice selection (male/female, language)
  • [ ] Auto-detect language
  • [ ] Save speed preference
  • [ ] Read entire page/section
  • [ ] Keyboard shortcuts
  • [ ] Multiple language support
  • [ ] AWS Polly integration (premium voices)

Related