Files

84 lines
5.3 KiB
Markdown

<div align="center">
<img src="assets/readme/hero.svg" width="100%" alt="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)
</div>
## 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)://<host>:<port>/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 <key>` 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.
<div align="center">
<sub>Made by <a href="https://evandro.dev.br">Evandro Fonseca Junior</a> · <a href="https://git.evandro.dev.br/evandro">git.evandro.dev.br</a></sub>
</div>