🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

whisper-web-transcriber

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

whisper-web-transcriber

Real-time audio transcription in the browser using OpenAI's Whisper model via WebAssembly

0.2.4
latest
Source
npm
Version published
Weekly downloads
87
-72.56%
Maintainers
1
Weekly downloads
 
Created
Source

Whisper Web Transcriber

Real-time audio transcription in the browser using OpenAI's Whisper model via WebAssembly. This package provides an easy-to-use API for integrating speech-to-text capabilities into web applications without any server-side processing.

Live Demo 🎙️ | Live Usage on Real Site 🚀

Features

  • 🎙️ Real-time audio transcription from microphone
  • 🌐 Runs entirely in the browser (no server required)
  • 📦 Multiple Whisper model options (tiny, base, quantized versions)
  • 💾 Automatic model caching in IndexedDB
  • 🔧 Simple, promise-based API
  • 📱 Works on all modern browsers with WebAssembly support
  • 🌍 Platform-independent (same WASM works on all OS)

Installation

NPM Package

npm install whisper-web-transcriber

Or using yarn:

yarn add whisper-web-transcriber

CDN Usage (Bundled Version)

<!-- Single file with all dependencies included -->
<script src="https://unpkg.com/whisper-web-transcriber/dist/index.bundled.min.js"></script>

Quick Start

Using NPM Package

import { WhisperTranscriber } from 'whisper-web-transcriber';

const transcriber = new WhisperTranscriber({
  modelSize: 'base-en-q5_1',
  onTranscription: (text) => {
    console.log('Transcribed:', text);
  }
});

await transcriber.loadModel();
await transcriber.startRecording();

Using CDN (Bundled Version)

<script src="https://unpkg.com/whisper-web-transcriber/dist/index.bundled.min.js"></script>
<script>
  const transcriber = new WhisperTranscriber.WhisperTranscriber({
    modelSize: 'base-en-q5_1',
    onTranscription: (text) => {
      console.log('Transcribed:', text);
    }
  });

  transcriber.loadModel().then(() => {
    transcriber.startRecording();
  });
</script>

API Reference

Constructor Options

interface WhisperConfig {
  modelUrl?: string;              // Custom model URL (optional)
  modelSize?: 'tiny.en' | 'base.en' | 'tiny-en-q5_1' | 'base-en-q5_1';
  sampleRate?: number;            // Audio sample rate (default: 16000)
  audioIntervalMs?: number;       // Audio processing interval (default: 5000ms)
  onTranscription?: (text: string) => void;
  onProgress?: (progress: number) => void;
  onStatus?: (status: string) => void;
  debug?: boolean;                // Enable debug logging (default: false)
}

Methods

  • loadModel(): Promise<void> - Downloads and initializes the Whisper model
  • startRecording(): Promise<void> - Starts microphone recording and transcription
  • stopRecording(): void - Stops recording
  • destroy(): void - Cleanup resources
  • getServiceWorkerCode(): string | null - Returns the COI service worker code (bundled version only)
  • getCrossOriginIsolationInstructions(): string - Returns setup instructions for Cross-Origin Isolation

Model Options

ModelSizeDescription
tiny.en75 MBFastest, lower accuracy
base.en142 MBBetter accuracy, slower
tiny-en-q5_131 MBQuantized tiny model, smaller size
base-en-q5_157 MBQuantized base model, good balance

Browser Requirements

  • WebAssembly support
  • SharedArrayBuffer support (requires Cross-Origin Isolation)
  • Microphone access permission
  • Modern browser (Chrome 90+, Firefox 89+, Safari 15+, Edge 90+)

Cross-Origin Isolation Setup

WhisperTranscriber requires SharedArrayBuffer, which needs Cross-Origin Isolation. You have two options:

Configure your server to send these headers:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

Option 2: Service Worker

If you can't modify server headers, use the included service worker:

For NPM users:

<!-- Include at the top of your HTML -->
<script src="node_modules/whisper-web-transcriber/dist/coi-serviceworker.js"></script>

For CDN users:

// Get the service worker code
const transcriber = new WhisperTranscriber.WhisperTranscriber();
const swCode = transcriber.getServiceWorkerCode();

// Save swCode as 'coi-serviceworker.js' on YOUR domain
// Then include it in your HTML:
// <script src="/coi-serviceworker.js"></script>

Important: Service workers must be served from the same origin as your page. CDN users cannot directly use the service worker from unpkg.

Serving with proper headers

For local development:

npm run demo

For production (examples):

Vercel (vercel.json):

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "Cross-Origin-Embedder-Policy",
          "value": "require-corp"
        },
        {
          "key": "Cross-Origin-Opener-Policy", 
          "value": "same-origin"
        }
      ]
    }
  ]
}

Nginx:

add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;

Complete Examples

Example 1: Using NPM Package

<!DOCTYPE html>
<html>
<head>
  <title>Whisper Transcriber - NPM Version</title>
  <!-- Include service worker for Cross-Origin Isolation -->
  <script src="node_modules/whisper-web-transcriber/dist/coi-serviceworker.js"></script>
</head>
<body>
  <button id="start">Start Recording</button>
  <button id="stop">Stop Recording</button>
  <div id="transcription"></div>

  <script type="module">
    import { WhisperTranscriber } from './node_modules/whisper-web-transcriber/dist/index.esm.js';

    const transcriber = new WhisperTranscriber({
      modelSize: 'tiny-en-q5_1',
      onTranscription: (text) => {
        document.getElementById('transcription').textContent += text + ' ';
      }
    });

    document.getElementById('start').onclick = async () => {
      await transcriber.loadModel();
      await transcriber.startRecording();
    };

    document.getElementById('stop').onclick = () => {
      transcriber.stopRecording();
    };
  </script>
</body>
</html>

Example 2: Using CDN (Bundled Version)

<!DOCTYPE html>
<html>
<head>
  <title>Whisper Transcriber - CDN Version</title>
  <!-- Note: You still need to handle Cross-Origin Isolation -->
  <!-- Either configure server headers OR save and include the service worker -->
</head>
<body>
  <button id="start">Start Recording</button>
  <button id="stop">Stop Recording</button>
  <div id="transcription"></div>

  <!-- Single script include -->
  <script src="https://unpkg.com/whisper-web-transcriber/dist/index.bundled.min.js"></script>
  <script>
    const transcriber = new WhisperTranscriber.WhisperTranscriber({
      modelSize: 'tiny-en-q5_1',
      onTranscription: (text) => {
        document.getElementById('transcription').textContent += text + ' ';
      }
    });

    // Check if Cross-Origin Isolation is enabled
    if (!window.crossOriginIsolated) {
      console.log(transcriber.getCrossOriginIsolationInstructions());
    }

    document.getElementById('start').onclick = async () => {
      await transcriber.loadModel();
      await transcriber.startRecording();
    };

    document.getElementById('stop').onclick = () => {
      transcriber.stopRecording();
    };
  </script>
</body>
</html>

Bundled vs Standard Version

Bundled Version (index.bundled.js)

  • Single file - All workers and dependencies included
  • CDN-friendly - No CORS issues with web workers
  • Zero configuration - Works out of the box (except for Cross-Origin Isolation)
  • Larger initial download - ~220KB uncompressed, ~95KB minified
  • 📦 Best for: Quick prototypes, CDN usage, simple deployments

Standard Version (index.js)

  • Smaller initial size - Core library only
  • Modular loading - Workers loaded on demand
  • Requires all files - Must serve worker files from same origin
  • More complex setup - Need to copy files from node_modules
  • 📦 Best for: Production apps with bundlers, optimized loading

Performance Considerations

  • Transcription is CPU-intensive
  • Larger models provide better accuracy but require more processing power
  • Quantized models (Q5_1) offer good balance between size and quality
  • First-time model loading may take time (models are cached afterward)

Troubleshooting

"SharedArrayBuffer is not defined"

You need to enable Cross-Origin Isolation. See the Cross-Origin Isolation Setup section.

"Failed to load worker" when using CDN

Use the bundled version (index.bundled.min.js) instead of the standard version.

"Microphone access denied"

Ensure your site is served over HTTPS (or localhost) and the user has granted microphone permissions.

Service worker not working

  • Service workers must be served from the same origin as your page
  • Check browser console for specific error messages
  • Ensure the service worker file is accessible at the correct path

Technical Details

Built using:

  • whisper.cpp compiled to WebAssembly
  • Web Audio API for microphone access
  • IndexedDB for model caching
  • Service Worker for Cross-Origin Isolation

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Acknowledgments

Keywords

whisper

FAQs

Package last updated on 04 Jun 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts