---
title: "Installation | Micdrop"
description: "Install the Micdrop React Native client, the audio library it records with, and the iOS and Android permissions a voice call needs."
url: "https://micdrop.dev/docs/react-native/installation"
---

*   [Getting Started](/docs/getting-started)
*   [Client (Browser)](/docs/client)
    
    *   [Installation](/docs/client/installation)
    *   [React Hooks](/docs/client/react-hooks)
    *   [Start/Stop Call](/docs/client/start-stop-call)
    *   [Pause/Resume Call](/docs/client/pause-resume-call)
    *   [Mute/Unmute Call](/docs/client/mute-unmute-call)
    *   [Call State](/docs/client/call-state)
    *   [Display Conversation Messages](/docs/client/display-conversation-messages)
    *   [Handling Tool Calls](/docs/client/handling-tool-calls)
    *   [Device Management](/docs/client/devices-management)
    *   [Voice Activity Detection (VAD)](/docs/client/vad)
    *   [Error Handling](/docs/client/error-handling)
    *   Utility Classes
        
        *   [Mic](/docs/client/utility-classes/mic)
        *   [MicdropClient](/docs/client/utility-classes/micdrop-client)
        *   [MicRecorder](/docs/client/utility-classes/mic-recorder)
        *   [Speaker](/docs/client/utility-classes/speaker)
        
    
*   [Client (React Native)](/docs/react-native)
    
    *   [Installation](/docs/react-native/installation)
    *   [Hooks and Call State](/docs/react-native/hooks)
    *   [Audio Output and Devices](/docs/react-native/audio-output)
    *   [Voice Activity Detection (VAD)](/docs/react-native/vad)
    *   [Using Another Audio Library](/docs/react-native/custom-audio)
    
*   [Server (Node.js)](/docs/server)
    
    *   [Installation](/docs/server/installation)
    *   [With Fastify](/docs/server/with-fastify)
    *   [With NestJS](/docs/server/with-nestjs)
    *   [Auth and Parameters](/docs/server/auth-and-parameters)
    *   [First Message](/docs/server/first-message)
    *   [Save Messages](/docs/server/save-messages)
    *   [Resume a Conversation](/docs/server/resume-conversation)
    *   [Recording Audio](/docs/server/recording-audio)
    *   [Error Handling](/docs/server/error-handling)
    *   [Tools](/docs/server/tools)
    *   [Extract Value from Answer](/docs/server/extract)
    *   [Auto End Call](/docs/server/auto-end-call)
    *   [Semantic Turn Detection](/docs/server/semantic-turn-detection)
    *   [Noise Filtering](/docs/server/noise-filtering)
    *   [Micdrop Protocol](/docs/server/protocol)
    
*   [AI Integrations](/docs/ai-integration)
    
    *   Provided Integrations
        
        *   [AI SDK](/docs/ai-integration/provided-integrations/ai-sdk)
        *   [Cartesia](/docs/ai-integration/provided-integrations/cartesia)
        *   [ElevenLabs](/docs/ai-integration/provided-integrations/elevenlabs)
        *   [Gladia](/docs/ai-integration/provided-integrations/gladia)
        *   [Gradium](/docs/ai-integration/provided-integrations/gradium)
        *   [Kokoro](/docs/ai-integration/provided-integrations/kokoro)
        *   [Mistral](/docs/ai-integration/provided-integrations/mistral)
        *   [OpenAI](/docs/ai-integration/provided-integrations/openai)
        *   [Piper](/docs/ai-integration/provided-integrations/piper)
        *   [Pocket TTS](/docs/ai-integration/provided-integrations/pocket-tts)
        *   [Whisper](/docs/ai-integration/provided-integrations/whisper)
        
    *   Custom Integrations
        
        *   [Agent (LLM)](/docs/ai-integration/custom-integrations/custom-agent)
        *   [Speech-to-Text (STT)](/docs/ai-integration/custom-integrations/custom-stt)
        *   [Text-to-Speech (TTS)](/docs/ai-integration/custom-integrations/custom-tts)
        
    *   Fallback Strategies
        
        *   [FallbackAgent](/docs/ai-integration/fallback-strategies/agent-fallback)
        *   [FallbackSTT](/docs/ai-integration/fallback-strategies/stt-fallback)
        *   [FallbackTTS](/docs/ai-integration/fallback-strategies/tts-fallback)
        
    *   [Local Models](/docs/ai-integration/local-models)
        
        *   [Choosing the Models](/docs/ai-integration/local-models/choosing-models)
        *   [Latency and Memory](/docs/ai-integration/local-models/performance)
        *   [Explorations](/docs/ai-integration/local-models/explorations)
        
    *   [IA Vocale Souveraine 🇫🇷🇪🇺](/docs/ai-integration/sovereign-voice-ai)
    
*   [Migration](/docs/migration)
    
    *   [Upgrade to v3](/docs/migration/v3)
    

[Micdrop](/) › [Documentation](/docs/getting-started)

# Installation

## Packages

Terminal window

```
npm install @micdrop/react-native react-native-audio-api
```

Audio is captured and played by [`react-native-audio-api`](https://github.com/software-mansion/react-native-audio-api), an implementation of the Web Audio API for React Native. It ships a player UI that pulls in three more packages, so install those as well:

Terminal window

```
npx expo install react-native-worklets react-native-gesture-handler react-native-reanimated
```

For the React hooks:

Terminal window

```
npm install @micdrop/react
```

The [Silero voice detection](/docs/react-native/vad) needs `onnxruntime-react-native` as well, which does not autolink on Expo SDK 57 today. The volume detection needs nothing.

Native code is involved, so the app runs from a development build. Expo Go does not include these libraries.

## Expo

Add the config plugin to `app.json`. It writes the microphone permission and the audio service into the native projects:

```
{  "expo": {    "plugins": [      [        "react-native-audio-api",        {          "iosMicrophonePermission": "We need the microphone so you can talk with the assistant.",          "androidPermissions": [            "android.permission.RECORD_AUDIO",            "android.permission.MODIFY_AUDIO_SETTINGS",            "android.permission.FOREGROUND_SERVICE",            "android.permission.FOREGROUND_SERVICE_MICROPHONE",            "android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"          ],          "androidFSTypes": ["microphone", "mediaPlayback"]        }      ]    ]  }}
```

Then build once:

Terminal window

```
npx expo run:ios# ornpx expo run:android
```

Later runs only need `npx expo start --dev-client`.

## Bare React Native

Add the microphone permission by hand.

`ios/<App>/Info.plist`:

```
<key>NSMicrophoneUsageDescription</key><string>We need the microphone so you can talk with the assistant.</string><key>UIBackgroundModes</key><array>  <string>audio</string></array>
```

`android/app/src/main/AndroidManifest.xml`:

```
<uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
```

Then run `pod install` in `ios/`.

The permission itself is requested by `Micdrop.start()`, there is nothing to call beforehand.

## Targeting phones only

Expo offers a web target unless you say otherwise, and bundling for it needs `react-native-web`. An app meant for phones says so in `app.json`, which keeps the dev server from failing on `Unable to resolve react-native-web`:

```
{  "expo": {    "platforms": ["ios", "android"]  }}
```

## Reaching the server

A phone does not share `localhost` with your machine, so a development server has to be reached by its address on the network. With Expo, the app already knows where it was loaded from:

```
import Constants from 'expo-constants'import { Platform } from 'react-native'
let host = Constants.expoConfig?.hostUri?.split(':')[0] ?? 'localhost'
// An Android emulator has its own loopback, so `localhost` there is the// emulator rather than the machine running the serverif (Platform.OS === 'android' && ['localhost', '127.0.0.1'].includes(host)) {  host = '10.0.2.2'}
export const serverUrl = `ws://${host}:8087`
```

Have the server listen on every interface (`host: '0.0.0.0'`) so it accepts that connection.

An iOS simulator shares the machine’s network, and a phone on the same Wi-Fi gets the address Expo advertised, so both work without the special case. A phone plugged in over USB reaches the machine through `adb reverse tcp:8087 tcp:8087`.

In production, use `wss://` and let the app talk to your deployed server.

## Monorepo

Metro has to see the packages outside the app folder. In `metro.config.js`:

```
const path = require('path')const { getDefaultConfig } = require('expo/metro-config')
const projectRoot = __dirnameconst monorepoRoot = path.resolve(projectRoot, '../..')
const config = getDefaultConfig(projectRoot)config.watchFolders = [monorepoRoot]config.resolver.nodeModulesPaths = [  path.resolve(projectRoot, 'node_modules'),  path.resolve(monorepoRoot, 'node_modules'),]
module.exports = config
```

With pnpm, leave hierarchical lookup on: each package finds its own dependencies through the store next to it.

[Previous← Client (React Native)](/docs/react-native)[NextHooks and Call State →](/docs/react-native/hooks)

On this page

*   [Packages](#packages)
*   [Expo](#expo)
*   [Bare React Native](#bare-react-native)
*   [Targeting phones only](#targeting-phones-only)
*   [Reaching the server](#reaching-the-server)
*   [Monorepo](#monorepo)
