On-Device AI in React Native & Expo
In this Expo & React Native tutorial, you’ll learn how to run a large language model (LLM) directly on a user’s device: no server, no API key needed. We’ll start from scratch with a simple chat exchange, and progressively introduce more advanced features: multimodal input, speech-to-text, text-to-speech, voice activity detection, tool calling and RAG. Each concept is explained before the code, so you can follow along whether you're new to on-device AI. Why run AI On-Device? Most AI features rely on a cloud API: you send a request to a remote server, it runs the model, and sends a response back. That works well, but it comes with tradeoffs. Running the model directly on the device avoids all of them: Works offline — no internet connection required Privacy by design — user data never leaves the device Low latency — no network round-trip No cloud costs — inference is free The tradeoff is raw capability: on-device models are smaller and less powerful than frontier cloud models. But for many use cases like summarization, chatbots, or local search, they're more than good enough. About NobodyWho We'll use the NobodyWho library throughout this tutorial. It wraps llama.cpp in Rust and exposes a clean React Native API for running locally any model in .gguf format. Install it with npm install react-native-nobodywho or npx expo install react-native-nobodywho for Expo. Loading a Model NobodyWho can download a GGUF model for you directly from Hugging Face, cache it, and reuse it on every subsequent launch. That means you don't need to bundle anything into your app or manage downloads yourself: import { Chat } from " react-native-nobodywho " ; const chat = await Chat . fromPath ({ modelPath : " huggingface:NobodyWho/Qwen_Qwen3-0.6B-GGUF/Qwen_Qwen3-0.6B-Q4_K_M.gguf " , }); The first time this runs, the model is downloaded to the app’s cache directory. Every call after that loads the model directly. modelPath accepts a few different forms: Form Example Notes HuggingFace reference hf