Skip to content

imDarshanGK/localmind

Repository files navigation

LocalMind v2.0

Offline AI Assistant - Chat with Your Documents. Privately.

No cloud. No API key. No data leaks. Runs 100% on your machine.

Python FastAPI React Ollama License: MIT SSoC 2026 PRs Welcome Discord


Quick Start · Features · Tech Stack · Troubleshooting · Contributing · Screenshots


What's New in v2.0

Feature Description
Streaming Responses See AI reply token-by-token in real time
Plugin System Calculator, Word Counter, JSON Formatter, Code Runner, Summarizer
Audit Log Track and view history of all plugin executions
8 Languages English, Hindi, Tamil, Telugu, Kannada, French, German, Spanish
Export Chats Download conversations as Markdown, JSON, or TXT
Session Manager Full CRUD - create, rename, search, delete chat sessions
Settings Panel Temperature, RAG chunks, model, theme, language
Docker v2 Health checks, persistent volumes, nginx reverse proxy
30+ Tests Full pytest suite with mocked Ollama

All Features

Feature Status
Fully Offline (Ollama) Included
PDF / TXT / CSV / DOCX / MD / HTML upload Included
RAG — Chat with Documents Included
Streaming Responses (SSE) Included
Multi-Model (Llama3, Mistral, Phi3, Gemma, DeepSeek) Included
8 UI Languages Included
Chat History (SQLite) Included
Session Manager (CRUD) Included
Session Search Included
Plugin System (6 plugins) Included
Plugin Audit Log Included
Export (MD / JSON / TXT) Included
Settings Panel Included
Docker Compose Included
30+ Tests Included
Zero telemetry Included

🛠 Tech Stack

┌────────────────────────────────────────────────┐
│               LocalMind v2.0                   │
├──────────────┬─────────────────────────────────┤
│  Frontend    │  React 18 + Tailwind + Vite     │
│  Backend     │  Python 3.11 + FastAPI          │
│  AI Engine   │  Ollama (local LLM)             │
│  RAG         │  LangChain + ChromaDB           │
│  Embeddings  │  sentence-transformers (local)  │
│  Database    │  SQLite (100% local)            │
│  Streaming   │  Server-Sent Events (SSE)       │
│  Deploy      │  Docker Compose + nginx         │
│  Testing     │  pytest + TestClient            │
└──────────────┴─────────────────────────────────┘

Quick Start

Option 1 - Docker (Recommended, 3 commands)

# 1. Pull a model (one-time, ~4GB)
ollama pull llama3

# 2. Clone and start
git clone https://github.com/yourusername/localmind.git
cd localmind && docker compose up

# 3. Open browser
open http://localhost:3000

Option 2 - Manual Setup

git clone https://github.com/yourusername/localmind.git
cd localmind

# Backend
cd backend
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp ../.env.example ../.env
uvicorn app:app --reload --port 8000

# Frontend (new terminal)
cd frontend
npm install && npm run dev
# Open http://localhost:3000

Prerequisites: Python 3.11+ | Node 18+ | Ollama | Docker

Render Deploy

If you deploy on Render, set the frontend build to use VITE_API_BASE_URL and configure the backend with CORS_ORIGINS.

# backend service envs
OLLAMA_HOST=http://<your-ollama-host>:11434
DEFAULT_MODEL=llama3
CORS_ORIGINS=https://<your-frontend>.onrender.com

# frontend static site envs
VITE_API_BASE_URL=https://<your-backend>.onrender.com/api

The included render.yaml defines a backend web service and a frontend static site for the same repo.

macOS Install Troubleshooting

node or npm not found

Symptom: zsh: command not found: node or The engine "node" is incompatible with this module

brew install nvm
echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.zshrc
echo '[ -s "$(brew --prefix nvm)/nvm.sh" ] && . "$(brew --prefix nvm)/nvm.sh"' >> ~/.zshrc
source ~/.zshrc
nvm install 18 && nvm use 18

Open a new terminal window after running this so the PATH update takes effect.


pip install fails building wheels

Symptom: xcrun: error: invalid active developer path or clang: error: command not found

xcode-select --install   # one-time, installs Apple Command Line Tools

cd backend
python3 -m venv venv && source venv/bin/activate
pip install --upgrade pip setuptools wheel
pip install -r requirements.txt

If the popup says tools are already installed, run xcode-select -p to confirm the path, then retry pip.


Apple Silicon architecture mismatch

Symptom: bad CPU type in executable or mach-o file, but is an incompatible architecture

cd backend
rm -rf venv
arch -arm64 python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

cd ../frontend
arch -arm64 npm install

If your Python or Node was installed under Intel Homebrew, open a Rosetta shell first (arch -x86_64 zsh) and rerun the same commands there.


Port 3000 or 8000 already in use

Symptom: EADDRINUSE: address already in use

lsof -ti :3000 | xargs kill
lsof -ti :8000 | xargs kill

Then re-run npm run dev and uvicorn app:app --reload --port 8000.


Ollama not reachable

Symptom: Failed to connect to Ollama or Connection refused — localhost:11434

ollama serve
ollama pull llama3
curl http://localhost:11434/api/tags   # should return a JSON list of models

If ollama is not found, download the app from ollama.com and reopen Terminal.


Python version too old

Symptom: python --version shows 3.10 or earlier

brew install python@3.11

cd backend
python3.11 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Run python --version inside the activated venv — it should show 3.11.x.


Verifying Your macOS Setup

node --version      # v18.x or v20.x
npm --version       # 8 or higher
python3 --version   # Python 3.11.x or higher
ollama list         # shows llama3 or another pulled model

If all four pass and npm run dev starts without errors, your setup is complete.


Project Structure

localmind/
├── backend/
│   ├── app.py                    # FastAPI entry point
│   ├── routes/
│   │   ├── chat.py               # /api/chat — streaming + standard
│   │   ├── sessions.py           # /api/sessions — full CRUD
│   │   ├── upload.py             # /api/upload — file indexing
│   │   ├── models.py             # /api/models — Ollama management
│   │   ├── plugins.py            # /api/plugins — 6 built-in plugins
│   │   ├── export.py             # /api/export — MD, JSON, TXT
│   │   └── settings.py           # /api/settings — app config
│   ├── services/
│   │   ├── rag_service.py        # LangChain + ChromaDB RAG
│   │   ├── ollama_service.py     # Ollama + streaming
│   │   └── db_service.py        # SQLite — all CRUD
│   ├── models/
│   │   └── schemas.py           # Pydantic v2 schemas
│   ├── tests/
│   │   └── test_api.py          # 30+ tests
│   ├── requirements.txt
│   └── Dockerfile
├── frontend/
│   ├── src/
│   │   ├── App.jsx               # Root — state, routing
│   │   ├── components/
│   │   │   ├── ChatWindow.jsx    # Messages + streaming + export
│   │   │   ├── Sidebar.jsx       # Sessions + model + language
│   │   │   ├── StatusBar.jsx     # Header toolbar
│   │   │   ├── UploadPanel.jsx   # Drag-drop file upload
│   │   │   ├── PluginsPanel.jsx  # Plugin runner UI
│   │   │   └── SettingsPanel.jsx # Settings form
│   │   └── utils/
│   │       └── api.js            # All backend API calls
│   ├── package.json
│   ├── vite.config.js
│   └── Dockerfile
├── docker-compose.yml
├── .env.example
├── .gitignore
├── README.md
├── CONTRIBUTING.md
└── ROADMAP.md

Plugins

Plugin Description
Calculator Safe math evaluator (supports sqrt, log, sin, etc.)
Summarizer Extractive summary of long text
Word Counter Words, chars, sentences, paragraphs
{} JSON Formatter Validate and pretty-print JSON
Code Runner Run Python snippets in a sandbox
Translator Language detection + translation via LocalMind

📤 Bulk Session Export API

Export multiple chat sessions in a single payload.

Endpoint: POST /api/export/sessions

Request Headers: Content-Type: application/json

Request Body:

{
  "session_ids": ["sess_1", "sess_2"],
  "format": "json"
}

Response (JSON format):

{
  "exported_at": "2026-06-24 19:30",
  "sessions": [
    {
      "session": {
        "id": "sess_1",
        "title": "LocalMind Chat",
        "model": "llama3",
        "language": "en",
        "message_count": 2,
        "created_at": "2026-06-24 19:00:00",
        "updated_at": "2026-06-24 19:05:00"
      },
      "messages": [
        {
          "id": 1,
          "role": "user",
          "content": "Hello",
          "sources": [],
          "created_at": "2026-06-24 19:00:05",
          "benchmarks": {}
        }
      ]
    }
  ]
}

Supported formats: json, markdown, txt.


Smoke Tests

Local execution:

docker compose up -d --build
bash tests/smoke_test.sh

Preserve containers:

KEEP_CONTAINERS=true bash tests/smoke_test.sh

Increase timeout:

TIMEOUT_SECONDS=180 bash tests/smoke_test.sh

Cleanup:

docker compose down -v

Expected outputs: You should see attempt logs for both the frontend and backend, concluding with "All smoke tests passed successfully." Troubleshooting: If a service fails to start, the script will automatically print the diagnostic output of docker compose ps and docker compose logs. Verify that port 8000 (backend) and 3000 (frontend) are not already in use.


Running Tests

cd backend
pip install pytest pytest-asyncio
pytest tests/ -v
# 30+ tests covering: sessions, chat, plugins, upload, export, settings

Local Backup Verification

# Verify backup and restore round-trip works correctly
pytest backend/tests/test_backup.py -v

🧹 Database Maintenance

Auto Vacuum SQLite

LocalMind automatically reclaims disk space after large deletions — clearing a chat, deleting a session, removing documents — by running SQLite's VACUUM command once enough rows have been deleted.

┌──────────────────────────────────────────────────┐
│            Vacuum Scheduling Flow                │
├──────────────────────────────────────────────────┤
│  1. Rows deleted (session / messages / docs)     │
│  2. Deleted count tracked in app_settings        │
│  3. Threshold crossed? ──No──> wait, keep count  │
│              │                                    │
│             Yes                                   │
│              ▼                                    │
│  4. VACUUM runs (separate autocommit connection) │
│  5. Counter resets to 0                          │
└──────────────────────────────────────────────────┘
Env Variable Default Description
DB_VACUUM_THRESHOLD 500 Cumulative deleted rows before an automatic VACUUM runs

Why threshold-based? Running VACUUM on every delete would rebuild the entire database file each time — slow and wasteful for small deletes. Batching it keeps the database lean without hurting day-to-day performance.

📊 See it in action (measured locally)
Stage DB File Size
After inserting 5,000 messages ~1.22 MB
After deleting them (no vacuum) ~1.22 MB — unchanged
After VACUUM runs ~40 KB


🚀 Optimization & Performance Utilities

Embeddings Cache Warmup

To prevent cold-start latency when users upload documents for the first time, you can pre-download and warm up the SentenceTransformer inference weights (all-MiniLM-L6-v2) before starting the web server.

Run the following command within your active virtual environment inside the backend directory:

cd backend
python warmup.py

## 🤝 Contributing

1. Fork → Clone → Create branch (`git checkout -b feature/your-feature`)
2. Make changes → Write tests → Commit (`git commit -m "feat: ..."`)
3. Push → Open Pull Request

Issues labeled [`good-first-issue`](https://github.com/yourusername/localmind/issues?q=label%3Agood-first-issue) are perfect for beginners!

Read [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide.

---

## License

MIT © 2026

<div align="center">

If LocalMind helped you, please star the repo. ⭐✨🚀

</div>

---

## 🌟 Community Showcase

Built something cool with LocalMind? We'd love to see it! Open a Pull Request to add your project, tutorial, or integration to this list.

### 🛠️ Projects & Integrations
* **[Community projects will appear here.]** - A brief 1-2 sentence description of what your integration does. (By [@yourusername](https://github.com/yourusername))
* *Contributions welcome! Add your tool here.*

### 📚 Community Articles & Tutorials
* *Have you written a blog post or recorded a video setup guide? Share it with the community here!*

---

### 🛡️ Dependency Security Scanning

Our CI pipeline automatically audits backend dependencies for known vulnerabilities (CVEs) on every push and pull request using `pip-audit`.

To scan your dependencies locally before pushing code, run the following commands inside your virtual environment:

```bash
# Install the security scanner
pip install pip-audit

# Run the vulnerability audit against your requirements file
pip-audit -r requirements.txt
</div>

About

Offline AI assistant - chat with your documents locally. No cloud, no API key, no data leaks. Built with Python + FastAPI + Ollama + LangChain.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

9 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors