Local-first semantic memory for desktop & AI applications
Deploy persistent, private chat context for local LLMs and cloud models without massive storage overhead. Store, search, and retrieve conversation history locally using lightweight vector embeddings. Ideal for Electron, Tauri, and Node.js apps requiring user-specific knowledge retention without transmitting private data to external servers. Your memory stays on your device, fully under your control. .
| Feature | Description |
|---|---|
| π 100% Local | All data stored on your device using LanceDB |
| π Semantic Search | Find messages by meaning, not just keywords |
| β‘ Fast | Vector embeddings powered by transformers.js |
| π¦ Zero Config | Works out of the box, no external services |
| πͺΆ Lightweight | ~80MB model, cached after first download |
| π Framework Agnostic | Works with Electron, Node.js, React Native |
| Scenario | Benefit |
|---|---|
| Desktop Apps | Persistent memory for Electron/Tauri apps without backend costs |
| Local LLMs | Context window management for private, offline model deployment |
| Privacy | Retain user knowledge and preferences without sending data to cloud |
npm install local-llm-memoryyarn add local-llm-memorypnpm add local-llm-memoryimport { ChatMemory } from 'local-llm-memory';
// Initialize the memory store
const memory = new ChatMemory({
dataPath: './my-chat-data', // Where to store data (default: ./chat-memory)
maxMessages: 10000 // Max messages to keep (default: 10000)
});
// Initialize (downloads model on first run)
await memory.initialize();
// Add a message
await memory.addMessage(
'The user prefers dark mode in all applications',
{ category: 'preference', userId: 'user-123' }
);
// Search semantically
const results = await memory.search('what are the user preferences?', {
limit: 5,
threshold: 0.7
});
console.log(results);
// [
// {
// text: 'The user prefers dark mode in all applications',
// score: 0.89,
// metadata: { category: 'preference', userId: 'user-123' },
// timestamp: 1712345678000
// }
// ]import { ChatMemory } from 'local-llm-memory';
const memory = new ChatMemory();
await memory.initialize();
// Store conversation turns
await memory.addMessage('User asked about pricing', { role: 'user', topic: 'sales' });
await memory.addMessage('Explained the tiered pricing model', { role: 'assistant' });
// Find related context before responding
const context = await memory.search('pricing questions');// main.js (Electron main process)
const { ChatMemory } = require('local-llm-memory');
const { app } = require('electron');
let memory;
app.whenReady().then(async () => {
memory = new ChatMemory({
dataPath: app.getPath('userData') + '/chat-memory'
});
await memory.initialize();
console.log('Chat memory ready!');
});
// IPC handler for renderer
ipcMain.handle('chat:search', async (event, query) => {
return await memory.search(query);
});import { ChatMemory } from 'local-llm-memory';
const memory = new ChatMemory({
embeddingModel: 'Xenova/all-MiniLM-L6-v2', // Default model
vectorSize: 384 // Default dimensions
});const stats = await memory.getStats();
console.log(stats);
// {
// totalMessages: 1234,
// dataSize: '12.5 MB',
// oldestMessage: '2024-01-15T10:30:00.000Z',
// newestMessage: '2024-04-14T15:45:00.000Z'
// }await memory.clear();
console.log('All chat memory cleared');Create a new chat memory instance.
| Option | Type | Default | Description |
|---|---|---|---|
dataPath |
string | ./chat-memory |
Directory to store data |
maxMessages |
number | 10000 |
Maximum messages before FIFO deletion |
embeddingModel |
string | Xenova/all-MiniLM-L6-v2 |
HuggingFace model ID |
vectorSize |
number | 384 |
Embedding vector dimensions |
Initialize the database and download embedding model if needed.
await memory.initialize((progress) => {
console.log(`${progress.status}: ${progress.progress}%`);
});Add a message to memory. Returns the message ID.
const id = await memory.addMessage('Important message', {
source: 'user-input',
priority: 'high'
});Semantic search across all messages.
| Option | Type | Default | Description |
|---|---|---|---|
limit |
number | 10 |
Max results to return |
threshold |
number | 0.5 |
Minimum similarity score (0-1) |
const results = await memory.search('find important messages', {
limit: 5,
threshold: 0.7
});Get memory statistics.
Delete all messages.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LOCAL-LLM-MEMORY β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Your Application β
β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β ChatMemory (API) ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β β
β βββββββββββββββββββ ββββββββββββββββββββββ β
β β EmbeddingService β β LanceDB β β
β β (transformers.js)β β (Vector Database) β β
β βββββββββββββββββββ ββββββββββββββββββββββ β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Local File System ββ
β β ./chat-memory/ ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β NO CLOUD. NO API KEYS. NO EXTERNAL SERVICES. β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Use Case | Description |
|---|---|
| AI Chatbots | Remember conversation context across sessions |
| Personal Assistants | Store and retrieve user preferences |
| Customer Support | Find similar past questions and answers |
| Research Tools | Build searchable knowledge base from notes |
| Note-Taking Apps | Semantic search over personal notes |
Contributions are welcome! Please read our Contributing Guide for details.
MIT License - see LICENSE for details.
- LanceDB - Serverless vector database
- Transformers.js - Local ML models
- Xenova/all-MiniLM-L6-v2 - Embedding model
| Feature | local-llm-memory | Pinecone | Chroma | Weaviate |
|---|---|---|---|---|
| Self-Hosted | β | β | β | β |
| Zero Config | β | β | β | |
| No API Keys | β | β | β | β |
| Browser Support | β | β | β | |
| Node.js Support | β | β | β | β |
| Embedding Included | β | |||
| Cost | Free | $$$ | Free | Free |
Clinical Data Scientist & Former Clinician
I am a clinician turned clinical data scientist and Clinical Quant, building clinical research intelligence platforms and biotech catalysts.
I develop open-source, local-first tools to help developers maintain sovereignty over their data and AI context.
Made with β€οΈ by Clinical Quant