MCPcopy Index your code
hub / github.com/EvanBacon/grok-voice-demo

github.com/EvanBacon/grok-voice-demo @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
202 symbols 500 edges 76 files 2 documented · 1% updated 7d ago★ 62
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Grok Voice Agents Demo

https://github.com/user-attachments/assets/5bbe3366-c520-4032-b7f1-09a76903b8bc

A realtime voice agent demo built with Expo and Expo Router, powered by xAI's Grok Voice Agent API. Talk to Grok in real time — spoken turns stream into a live chat UI — from a single codebase that runs on iOS, Android, and web. Ships with iOS 26 Liquid Glass support and a responsive web UI.

Features

  • Grok voice agent -- realtime, low-latency voice conversations over a WebSocket with server-side Voice Activity Detection for natural turn-taking
  • Cross-platform audio -- browser Web Audio API on web and react-native-audio-api on iOS/Android, behind a shared core
  • Voice settings -- pick the voice and personality, applied to the session on the next start
  • Streaming transcripts -- spoken turns stream into the same message list as typed messages, with throttled ~30fps updates and markdown rendering
  • Liquid Glass -- glassmorphic prompt composer, navigation bars, and toolbar buttons on iOS 26 via expo-glass-effect
  • Web-first sidebar -- collapsible sidebar with Radix context menus, dropdown menus, and tooltips for a desktop-grade web experience
  • Platform-adaptive layouts -- native gesture-driven drawer on iOS/Android, sidebar + inset content panel on web
  • Dark mode -- automatic light/dark theme using OKLCH design tokens in Tailwind CSS v4
  • Native UI controls -- SwiftUI model picker menu, toolbar buttons, and haptic feedback on iOS
  • Keyboard-aware -- prompt input stays above the keyboard with react-native-keyboard-controller
  • Virtualized chat -- performant scrolling with @legendapp/list and Reanimated-powered scroll-to-bottom button

Tech Stack

Layer Technology
Framework Expo SDK 56
Navigation Expo Router (file-based) with typed routes, Legend List for virtualized chat
Styling Tailwind CSS v4 via Uniwind + tailwind-merge
Native UI @expo/ui (SwiftUI), expo-symbols, expo-haptics, expo-glass-effect
Web UI Radix UI (context menu, dropdown menu, tooltips), Lucide icons
Markdown Custom AST renderer with mdast-util-from-markdown + react-syntax-highlighter
Animations react-native-reanimated, react-native-gesture-handler

Getting Started

Environment Variables

Copy .env.example to .env and fill in the values:

cp .env.example .env
Variable Description
XAI_API_KEY Your xAI API key. Used by the Grok voice agent route (app/api/voice-session+api.ts) to mint realtime session tokens.
EXPO_PUBLIC_MOCK_AI Set to 1 to use mock streaming responses instead of calling the API. Useful for UI development without an API key.

Voice Agent (Grok)

Tap the audio-wave icon in the chat composer to talk to Grok's realtime Voice Agent API without leaving the conversation. The composer turns into a live voice bar (persona orb + waveform + stop) and the spoken turns stream into the same message list as typed messages. It streams microphone audio (24kHz PCM16) over a WebSocket and plays back Grok's spoken replies; server-side Voice Activity Detection handles turn-taking. The sliders icon opens Voice Settings to pick the voice and personality (both applied to the session on the next start).

The long-lived XAI_API_KEY never reaches the client: it fetches a short-lived ephemeral token from /api/voice-session, then opens the realtime WebSocket with that credential.

The audio layer is platform-split behind a shared core (grok-voice-core.ts):

  • Web (grok-voice.ts) — browser Web Audio API (getUserMedia + an AudioWorklet for capture, AudioContext scheduling for playback). The token is passed via the WebSocket subprotocol, since browsers can't set headers.
  • iOS / Android (grok-voice.native.ts) — react-native-audio-api (AudioRecorder for capture, AudioBufferQueueSourceNode for playback). The token goes in an Authorization header. iOS uses the voiceChat audio-session mode so hardware echo cancellation keeps the agent from hearing itself.

Native requires a rebuild after install (npx expo run:ios / run:android) for the react-native-audio-api config plugin (mic permission + audio session) to take effect. Echo cancellation needs a physical device.

Install & Run

# Install dependencies
bun install

# Start the dev server
bun start

# Run on a specific platform
bun run ios
bun run android
bun run web

Requires Bun and the Expo CLI. For iOS, you'll need Xcode and a simulator or device.

Customization

Theme

Edit global.css to change the design tokens. Colors use OKLCH for perceptual uniformity across light and dark modes. The @theme block maps CSS variables to Tailwind classes:

--app-background  ->  bg-background
--app-foreground  ->  text-foreground
--app-muted       ->  bg-muted
--app-border      ->  border-border
/* etc. */

Chat Backend

The typed-chat backend streams from xAI's Grok models via @ai-sdk/xai in the server-side chat API route (app/api/chat+api.ts). Swap the model id or provider there to point at a different backend -- the streaming architecture (createStreamingStore + throttled token callback) is ready for any AI SDK provider.

Database

I recommend using Convex, which you can setup in a single command:

npx eas-cli@latest integrations:convex:connect

Pair this with better-auth for authentication. Convex also has support for Expo Notifications: Learn more.

License

This template was made for https://agent.expo.dev and is made freely available under the MIT license.

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Function 149
Method 22
Interface 19
Class 12

Languages

TypeScript100%

Modules by API surface

src/utils/grok-voice-core.ts21 symbols
src/utils/grok-voice.ts9 symbols
src/utils/grok-voice.native.ts9 symbols
src/components/markdown/utils.ts8 symbols
src/app/chats.tsx7 symbols
src/components/markdown/ast-renderer.ts6 symbols
src/components/chat/prompt-input.tsx6 symbols
src/components/attachments-content.tsx6 symbols
src/components/touchable-glass.tsx5 symbols
src/components/markdown/code-block.tsx5 symbols
src/components/drawer-layout.tsx5 symbols
src/components/drawer-content.tsx5 symbols

For agents

$ claude mcp add grok-voice-demo \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page