VoiceInput

Add voice input to
your React app.

Dictation for your inputs and textareas.
Keep your components, styling, and editing behavior.

Live demoInitializing the interactive demo…

The demo relays audio through voiceinput.dev to enforce its limits, then sends it to OpenAI. It stores neither audio nor transcripts; SDK integrations connect directly to providers.

Drop it into the field you already have.

Install two packages, then add a hook to your textarea or use VoiceTextarea. Your styling and form logic stay yours.

npm install @voiceinput/react @voiceinput/openai
composer.tsx
"use client";

import { useState } from "react";
import { VoiceTextarea } from "@voiceinput/react";
import { openai } from "@voiceinput/openai";
import "@voiceinput/react/styles.css";

const provider = openai({ tokenEndpoint: "/api/voice-token" });

export function Composer() {
  const [text, setText] = useState("");

  return (
    <VoiceTextarea
      aria-label="Message"
      placeholder="Write a message…"
      value={text}
      onValueChange={setText}
      voice={{ provider }}
    />
  );
}
Server route (required)
app/api/voice-token/route.ts
import { createOpenAITokenHandler } from "@voiceinput/openai/server";
import { getCurrentUser } from "./app-auth"; // your existing session check

export const runtime = "nodejs";
const appOrigin = new URL(process.env.APP_ORIGIN!).origin;

export const POST = createOpenAITokenHandler({
  apiKey: process.env.OPENAI_API_KEY!,
  authorize: async (request) => {
    if (request.headers.get("origin") !== appOrigin) return null;
    const user = await getCurrentUser(request);
    return user ? { subject: user.id } : null;
  },
});

app-auth contains your authentication and quota helpers. Complete server setup

Keep the flow of writing.

Speak where the cursor is. Select a phrase to replace it. Undo as usual.

Explore editing behavior

Your keys. Your provider.

Your server issues a temporary credential. Audio streams from your app straight to OpenAI, ElevenLabs, or Deepgram. Switch providers without touching your field.

See how it works