Model or dataset
dabit3/react-native-ai avatar
dabit3/react-native-ai

react-native-ai: a scaffold for streaming chat and image apps, and the wiring you inherit with it

Full stack framework for building cross-platform mobile AI apps

1,299 stars169 forksTypeScriptMIT

At a glance

What is it?
dabit3/react-native-ai is an MIT-licensed TypeScript starter that pairs a React Native client with an Express server so mobile AI apps can stream from several LLM providers. The generator saves setup time, but adding a model means editing four or five files, and the README leaves deployment and per-provider auth largely open.
Who is it for?
Adopt react-native-ai if you want a working React Native plus Express skeleton for streaming chat and image generation and you accept editing app and server files together whenever a provider changes. Do not adopt it if you need a managed backend, a typed provider abstraction, or a project that survives model churn without manual edits.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 10 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap rn-ai fills: streaming chat and image generation without building the transport layer

Wiring a mobile client to a hosted LLM is not hard. Wiring it so tokens appear as they arrive, so API keys never ship inside the app bundle, and so the same screens work with more than one provider is the part that eats a week. react-native-ai targets that middle layer. The README describes it as a "Full stack framework for building cross-platform mobile AI apps" and lists streaming text and chat UIs, image services, natural language to images, and image processing as the supported surface. The intended user is a developer who already knows React Native and wants a starting point rather than a library to install into an existing app. The distribution model confirms this: you run npx rn-ai to generate a new project, not npm install to add a dependency. That distinction matters. You are not adopting a package with a versioned API. You are adopting a codebase you will edit, and the README's instructions are written accordingly, telling you which files to open and change rather than which functions to call.

Two processes, one proxy: how the client and Express server divide the work

The architecture is a React Native app plus a separate Express server, started independently. The README gives two commands under separate headings: npm start from the app directory and npm run dev from the server directory. That split is the load-bearing design decision. The server exists in part as a proxy, which the feature list describes as a way to "easily enable authentication and authorization with auth provider of choice." Provider keys live in server environment variables, so the mobile binary never holds them. Streaming is handled per provider rather than through a single abstraction. Models are declared in a MODELS array in constants.ts on the client, and each one maps to a server route through getChatType in utils.ts. The server side mirrors that structure with files under server/src/chat, one per model type, plus a chatRouter that dispatches to them. Image models follow the same shape: an IMAGE_MODELS array in constants.ts, a screen at src/screens/images.tsx, and handlers under server/src/images with an imagesRouter. The README notes that Gemini image generation lives in server/src/images/gemini.ts. This is a routing convention, not a plugin system. Nothing discovers providers automatically.

From npx rn-ai to a running app: the commands and config keys in the README

Getting started is a single generator command. Running npx rn-ai creates the project and, per the README, offers to configure environment variables during setup or leaves you to do it later. Once generated, the app and server run as two separate processes: npm start inside the app directory, npm run dev inside the server directory. Server-side configuration lives in server/.env.example, which you rename to .env and fill in. The README calls out one key by name, GEMINI_API_KEY, and states that Gemini image generation requires it. Other provider keys are implied by the supported model list (OpenAI, Anthropic, Gemini, Z.ai, Moonshot) but the README does not enumerate their variable names, so treat server/.env.example as the authoritative list and read it before assuming a key exists. Theming is configured in app/src/theme.ts, where the README shows a theme object spread from lightTheme with fields including name, label, tintColor, textColor, tabBarActiveTintColor, tabBarInactiveTintColor and placeholderTextColor, then exported alongside the five built-in themes. Adding a theme is genuinely a few lines. Adding a model is not.

Adding one LLM means editing five places, and the README says so

The README's instructions for a new chat model are a numbered list of five steps on the client: create local state, update the chat() function, write a generateModelReponse function, update getChatType in utils.ts, and render the model in the UI. The rendering example shows a conditional block keyed on chatType.label.includes('newModel') wrapping a FlatList. Then there is server work: create a file in server/src/chat matching the model type, and register it in server/src/chat/chatRouter. The README's own advice is to "copy and re-use a lot of the streaming code from the other existing paths." That is an honest description of the maintenance model, and it is the main cost of this scaffold. There is no shared streaming interface that a new provider implements. Each provider gets its own copy of the streaming logic, which means a change to how you handle aborts, retries, or partial JSON has to be applied once per provider. The supported model list in the README names OpenAI GPT-5.2 and GPT-5 mini, Anthropic Claude Fable 5, Sonnet 5, and Opus/Sonnet/Haiku 4.5, Gemini, Z.ai GLM 5.2, and Moonshot Kimi K2.7. That is a lot of surface area to keep in sync by hand when any provider changes its request shape.

Image models add an input-shape decision the chat path does not have

The image side has a constraint worth flagging before you pick it. The README states the main consideration plainly: does the model take text, image, or both as inputs? The app is described as configured to handle both, but you must update the generate function to pass values to the API accordingly. That is a branch you write per provider, not a capability the framework negotiates. For Gemini, the README points to server/src/images/gemini.ts and says to configure GEMINI_API_KEY and select the Nano Banana image models from the settings screen. Other providers require a new file under server/src/images/modelName, a handler for the API call, and registration in imagesRouter. So the image path is structurally identical to the chat path: declare in constants.ts, render in the screen, handle on the server, register the route. If your app only ever needs one image provider, this is fine. If you plan to swap image backends, you are writing the same adapter twice.

What the README does not cover, and where that bites

There are real gaps. No releases were retrieved for this repository, so there is no changelog to read before upgrading a generated project; you would be diffing against the template yourself. The README does not describe deployment, so running the Express server in production, setting CORS, or handling rate limits is left to you. It does not document the authentication implementation, only the intent: the proxy is there so you can add "authentication and authorization with auth provider of choice." That means the proxy is a place to put auth, not an auth system. It also does not list the environment variable names for OpenAI, Anthropic, Z.ai or Moonshot, so the .env.example file is the only source of truth. And there is no mention of offline behavior, token accounting, or cost controls. For a scaffold, that is a reasonable scope. For a team expecting a framework to own those concerns, it is a mismatch. The MIT licence keeps the code permissive, but it also means no vendor is on the hook for provider breakage; the copy-and-adapt model puts that on you.

How this compares to calling a provider SDK directly from the app

The obvious alternative is skipping the scaffold and calling a provider SDK from the React Native client. That is faster to start and removes the Express process entirely, but it puts API keys in the app bundle unless you build your own proxy, which is the exact work this project front-loads for you. A second alternative is a hosted backend-as-a-service that exposes a chat endpoint and manages keys and scaling. That trades file-level control for operational relief, and it usually means your streaming format is whatever the vendor defines. react-native-ai sits between them: you own the server, you own the streaming code, and you get a working client UI for it. The difference in approach is concrete. With a direct SDK call you write UI and transport. With a hosted backend you write UI and configuration. With react-native-ai you write UI, transport, and a server route per provider, but the first version of all three already exists in the template.

Who should generate a project from this template, and what to check first

Generate a project with npx rn-ai if you are building a React Native app whose core feature is streaming chat or image generation, you want a server proxy from day one so keys stay off the device, and you are comfortable treating the output as your own code. Do not generate one if you need a stable dependency you can bump in package.json, if you expect provider abstraction to be handled for you, or if you cannot absorb the five-file edit every time you add or replace a model. The first thing to verify is server/.env.example, because it is the only place the README points to for the full set of provider keys, and the second is the getChatType mapping in utils.ts, since that is where a client model label becomes a server route and a mismatch there produces a request that never reaches a handler. Run both processes, npm run dev in the server directory and npm start in the app directory, and send one message through a single provider before you add a second. If that round trip works and you can follow the label-to-route mapping in utils.ts, the rest of the template is readable code you can extend.

Editorial conclusion

Adopt react-native-ai if you want a working React Native plus Express skeleton for streaming chat and image generation and you accept editing app and server files together whenever a provider changes. Do not adopt it if you need a managed backend, a typed provider abstraction, or a project that survives model churn without manual edits. Before committing, run npx rn-ai in a scratch directory and open server/.env.example to confirm which keys your chosen providers require, then trace one model end to end through constants.ts, chat.tsx, utils.ts and the matching file in server/src/chat to see how much code a single provider swap actually costs you.

Official sources

  1. dabit3/react-native-ai on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Community notes

Community notes