Quickstart: React (web)
Core LLM Wiki runs entirely client-side on sql.js, which is SQLite compiled to WebAssembly. You don’t need a server unless you want one for the LLM call.
-
Install
Terminal window npm install @equationalapplications/react-llm-wiki sql.js -
Wrap sql.js in a
SQLiteAdapterThe engine talks to SQLite through a six-method interface. Here it is for sql.js:
src/sqljsAdapter.ts import initSqlJs from 'sql.js';import type { SQLiteAdapter } from '@equationalapplications/react-llm-wiki';export async function createSqlJsAdapter(): Promise<SQLiteAdapter> {// Serve sql-wasm.wasm from your public folder (or a CDN).const SQL = await initSqlJs({ locateFile: (file) => `/${file}` });const db = new SQL.Database();const adapter: SQLiteAdapter = {async execAsync(sql) { db.exec(sql); },async runAsync(sql, params = []) {db.run(sql, params as any[]);return { changes: db.getRowsModified(), lastInsertRowId: 0 };},async getAllAsync(sql, params = []) {const stmt = db.prepare(sql);stmt.bind(params as any[]);const rows = [];while (stmt.step()) rows.push(stmt.getAsObject());stmt.free();return rows as any;},async getFirstAsync(sql, params = []) {const stmt = db.prepare(sql);stmt.bind(params as any[]);const row = stmt.step() ? stmt.getAsObject() : null;stmt.free();return row as any;},async withTransactionAsync(fn) {db.run('BEGIN');try { const r = await fn(adapter); db.run('COMMIT'); return r; }catch (e) { db.run('ROLLBACK'); throw e; }},async closeAsync() { db.close(); },};return adapter;} -
Create the wiki and provide it
src/main.tsx import { createRoot } from 'react-dom/client';import { createWiki, WikiProvider } from '@equationalapplications/react-llm-wiki';import { createSqlJsAdapter } from './sqljsAdapter';import { App } from './App';const wiki = createWiki(await createSqlJsAdapter(), {llmProvider: {generateText: async ({ systemPrompt, userPrompt }) => {const res = await fetch('/api/generate', {method: 'POST',body: JSON.stringify({ systemPrompt, userPrompt }),});return res.text();},},});await wiki.setup();createRoot(document.getElementById('root')!).render(<WikiProvider wiki={wiki}><App /></WikiProvider>,); -
Use the hooks
src/App.tsx import { useMemoryRead, useWikiWrite } from '@equationalapplications/react-llm-wiki';export function App() {const { execute: write, isPending: saving } = useWikiWrite();const { data, refetch } = useMemoryRead('user-123', 'preferences');return (<><buttondisabled={saving}onClick={async () => {await write('user-123', { event_type: 'observation', summary: 'Prefers dark mode.' });refetch();}}>Remember</button><ul>{data?.facts.map((f) => <li key={f.id}>{f.title}</li>)}</ul></>);}
Not using React?
Section titled “Not using React?”Use @equationalapplications/core-llm-wiki with the same adapter. The API is identical, minus the hooks:
import { createWiki, formatContext } from '@equationalapplications/core-llm-wiki';
const wiki = createWiki(adapter, { llmProvider });await wiki.setup();await wiki.write('user-123', { event_type: 'observation', summary: '…' });const context = formatContext(await wiki.read('user-123', 'query'));This works the same in Vue, Svelte, Solid, or plain HTML.
Desktop apps
Section titled “Desktop apps”The same packages work inside desktop shells such as Tauri or Electron.
Curated Thoughts is a Tauri app.
Its React UI runs react-llm-wiki, and a Rust back end handles file watching, local embeddings,
and an MCP server.