LocalMind: chat with your LM Studio models from a phone or browser on your own network ![React Native 0.81](https://img.shields.io/badge/React_Native-0.81-61DAFB?style=flat-square&logo=react&logoColor=black) ![Expo 54](https://img.shields.io/badge/Expo-54-1C1E24?style=flat-square&logo=expo&logoColor=white) ![TypeScript 5.9](https://img.shields.io/badge/TypeScript-5.9-3178C6?style=flat-square&logo=typescript&logoColor=white) ![Platforms](https://img.shields.io/badge/platforms-Android_%7C_iOS_%7C_Web-555?style=flat-square) ![Status](https://img.shields.io/badge/status-alpha-orange?style=flat-square) [Quick start](#quick-start) · [Issues](https://git.evandro.dev.br/evandro/LocalMind/issues)
## What it is LocalMind is a chat client for the models you run in [LM Studio](https://lmstudio.ai). It is an Expo app for Android, iOS and the web that talks to LM Studio's OpenAI-compatible `/v1` API over your LAN or `localhost`. It is only the client: there is no backend, no account and no server to deploy. ## Why use it - **Your messages stay on your network.** The app only talks to the LM Studio address you set in Settings. There is no cloud API and no fallback to one. - **Real streaming on every target.** Requests go out with `stream: true` and each SSE `choices[0].delta.content` is appended as it arrives: through `XMLHttpRequest` progress events on native, through `fetch` with a `ReadableStream` on the web. You can stop generation mid-stream. - **The chat basics are there.** Markdown with copyable code blocks, edit, delete and regenerate, a model selector fed by LM Studio, history saved on the device, and light, dark or system theme. **When not to use it:** if you want a cloud model, a server other than LM Studio (the app was built against LM Studio only), or a verified phone build. The Android and iOS builds and the native streaming path have not been verified yet. ## How it works - Screens are file-based routes (`expo-router`): `app/chat`, `app/chat/history` and `app/settings`. `hooks/useLMStudio` exposes send, regenerate, stop and model fetching. - `services/lmStudioApi` builds `http(s)://:/v1`, calls `GET /v1/models` for the selector and the connection test, and streams `POST /v1/chat/completions`. - `store/useAppStore` (Zustand) persists theme, server settings, chat sessions and the current chat in `AsyncStorage`. A finished exchange becomes a session titled from the first user message. ## Quick start You need Node.js 20.19.4 or newer (required by React Native 0.81; not declared in `package.json`), npm, and LM Studio with at least one model downloaded. To run the app, use [Expo Go](https://expo.dev/go) on a device, an Android or iOS emulator, or a browser. **1. Start LM Studio's server.** Open the **Local Server** tab (the `<->` icon), load a model, enable **CORS**, keep the port at `1234` (or note yours) and click **Start Server**. **2. Run the app.** ```bash git clone https://git.evandro.dev.br/evandro/LocalMind.git cd LocalMind npm install npm run start # Expo CLI: press w (web), a (Android), i (iOS) or scan the QR code with Expo Go ``` `npm run android`, `npm run ios` and `npm run web` open a target directly. Do not run `npm run reset-project`: it is the Expo template script and moves or deletes `app/`, `components/`, `hooks/`, `constants/` and `scripts/`. **3. Point the app at LM Studio.** Open **Settings** (gear icon in the chat header), fill **Host IP / Address** and **Port Number**, then tap **Test Connection**. On a physical device the host must be your computer's LAN address (`192.168.x.x`), not `localhost`. The badge turns to *Connected* and the loaded models appear in the header. Until then the chat shows *Server offline*: the app does not connect on launch. ## Configuration The app reads no environment variables. The server address is a runtime setting stored on the device: | Setting | Default | Notes | |---|---|---| | Host IP / Address | `localhost` | `http://` is prepended when the value does not start with `http` | | Port Number | `1234` | LM Studio's default port | | API Key (optional) | empty | Sent as `Authorization: Bearer ` only when filled in | Everything else lives in code: `temperature: 0.7` and `max_tokens: 2048` in `services/lmStudioApi.ts` (the connection test gives up after 5 s), the fixed system prompt in `constants/SystemPrompt.ts`, and the persisted state under the `localaiapp-storage` key in `store/useAppStore.ts`. ## Project status Alpha, with no tests and no CI. Known gaps: - The selected model and the model list are not persisted, so you pick a model again after a restart. - `constants/Models.ts` (a Qwen model catalog) and the `react-native-sse` dependency are not used by any code. - `app.json` and the storage key still carry the previous project name (`LocalAiApp`, `localaiapp-storage`). - Both `package-lock.json` and `pnpm-lock.yaml` are committed. Before opening a PR, run `npm run lint` (Expo's ESLint config) and `npx tsc --noEmit`. Notes on the LM Studio API, in Portuguese, are in [`docs/`](docs/). ## License No published license: all rights reserved.
Made by Evandro Fonseca Junior · git.evandro.dev.br