A standalone, LLM-powered mind-map application built with FastAPI, SQLite, and Mind Elixir. Paste text or Markdown, upload a text file, or restore an exported map; the app asks an OpenAI-compatible LLM to create a structured concept hierarchy and renders it as an interactive, expandable mind map.
The application is designed to work with OpenAI as well as compatible hosted or local endpoints that implement the OpenAI chat-completions API.
- Generate a mind map from pasted text, Markdown, or
.txt/.mdfiles or a.jsonfile saved from a previous run - Use any model returned by the configured OpenAI-compatible endpoint
- Expand a node with LLM-generated child concepts
- Collapse branches, expand/collapse all visible nodes, pan, and re-center the map
- Search node labels; matching nodes and their ancestor paths are expanded automatically
- Ask node-specific questions through the built-in Q&A panel
- Preserve graph sessions in SQLite and restore the active session after a browser refresh
- Export the map as Markdown, JSON, PNG, or SVG
- Export the in-browser Q&A history as Markdown
- Toggle light and dark themes; Mind Elixir canvas colors remain synchronized with the selected theme
- Color-code root-level branches and their descendants
Browser (templates/index.html)
├─ Mind Elixir rendering, search, imports/exports, node Q&A UI
└─ fetch() requests to FastAPI API endpoints
│
V
FastAPI (backend/main.py)
├─ Serves the Jinja template at /
├─ Calls an OpenAI-compatible LLM endpoint
├─ Converts generated Markdown into a graph
└─ Reads/writes sessions to SQLite
│
V
mindmap_sessions.db
The frontend is intentionally self-contained: its CSS and JavaScript live in templates/index.html, and Mind Elixir is imported from a CDN. The backend holds the graph model, API routes, LLM calls, and SQLite persistence.
.
├── backend/
│ └── main.py # FastAPI app, LLM integration, graph/session logic
├── templates/
│ └── index.html # Interactive Mind Elixir frontend
├── mindmap_sessions.db # Created/updated automatically at runtime
├── requirements.txt
└── README.md
Run the server from the project root. The database path is relative (mindmap_sessions.db), so starting Uvicorn from another directory will create or use a database there instead.
- Python 3.10+
- An OpenAI-compatible API endpoint with chat-completions and model-listing support
- Network access for the browser to load Mind Elixir from
esm.sh
Install Python dependencies:
python -m venv .venv
source .venv/bin/activate # Windows PowerShell: .venv\Scripts\Activate.ps1
pip install -r requirements.txtConfiguration is supplied through environment variables.
| Variable | Default | Purpose |
|---|---|---|
OPENAI_API_KEY |
sk-... placeholder |
API key sent to the OpenAI-compatible service |
OPENAI_BASE_URL |
https://api.openai.com/v1 |
Base URL of the compatible API |
LLM_MODEL |
gpt-4o-mini |
Default model used to generate, expand, and query maps |
The UI calls /api/models on startup and populates the model selector from the endpoint's model list. If that request fails, the app falls back to the value of LLM_MODEL.
Security: Do not commit API keys. Prefer exporting the variables in your shell, using a local
.envfile that is ignored by Git, or using your deployment platform's secret manager.
From the project root:
export OPENAI_BASE_URL="http://llama-swap:9090/v1" # Or any compatible openai compatible endpoint
export OPENAI_API_KEY="sk-xxx" # if running locally, or if you don't have any api set
export LLM_MODEL="Gemma4-MoE" # insert the model you use on your computer
export EMBEDDING_MODEL="LFM2.5-Embedding-350M" # I like the LFM series of models. If you are using llama-swap, this needs to be routed as well
uvicorn backend.main:app --reload --host 0.0.0.0 --port 8000- Open the app and select a model from the toolbar.
- Paste text or Markdown, choose a
.txt/.mdfile, or drag and drop a supported text file. - Select Generate / Restore.
- Hover a node and use the + button to expand it with related child concepts.
- Click a node to open the Q&A panel and ask a focused question about that concept.
- Use the toolbar to search, expand/collapse all, re-center the map (reset), toggle the theme, or export files.
If the text area contains an exported graph JSON object with nodes and edges, the frontend treats it as a restore operation rather than generating a new graph.
| Method | Route | Purpose |
|---|---|---|
GET |
/ |
Render the application page |
GET |
/api/models |
List models from the configured LLM provider |
GET |
/api/session/{session_id} |
Load the visible graph for a saved session |
POST |
/api/generate |
Generate a graph from text or Markdown |
POST |
/api/expand |
Generate children for a node |
POST |
/api/collapse |
Hide a node's descendants |
POST |
/api/query |
Ask an LLM question scoped to a node and its parent context |
POST |
/api/restore |
Create a new session from exported graph JSON |
POST |
/api/upload |
Decode an uploaded text file as UTF-8 |
Sessions store all nodes and edges plus expanded/hidden-node state. API responses return the visible graph, so collapse hides descendants without deleting them.
- Server-side: each generated/restored map is saved to SQLite in the
sessionstable ofmindmap_sessions.db. - Browser-side: the active session ID is stored in
localStorageasmindmap-session-id, allowing the app to restore that session on reload. - JSON export: downloads the current graph for later import/restore.
- Markdown export: downloads the visible Mind Elixir hierarchy.
- PNG/SVG export: captures the rendered map.
- Q&A Markdown export: downloads questions and answers collected during the current browser session.
Q&A history is currently maintained in the browser UI; it is not persisted to the SQLite graph session.
-
Basic mind-map functions, showing search and node expansion for
k-which matches tok-meansork-foldetc
Check that OPENAI_BASE_URL, OPENAI_API_KEY, and network connectivity are correct. The configured provider must support a model-list endpoint compatible with the OpenAI client. The UI can still show the LLM_MODEL fallback if listing fails.
Inspect the Uvicorn terminal for the upstream provider error. Confirm that the selected model is available at the configured endpoint and supports chat completions.
Here are a few curl commands to see if everything works properly.
- Checking if the tool works correctly
curl -X POST "http://localhost:7000/api/documents/upload" \
-H "Content-Type: application/json" \
-d '{
"text": "# Machine Learning Basics\n\nMachine learning is a subset of artificial intelligence that provides systems the ability to automatically learn and improve from experience without being explicitly programmed.\n\n## Supervised Learning\nSupervised learning is a type of machine learning where the model is trained on labeled data, meaning the input data is paired with the correct output.\n\n## Unsupervised Learning\nUnsupervised learning is a type of machine learning where the model is trained on unlabeled data. The system tries to learn the patterns and the structure from the data without any explicit guidance.",
"filename": "ml_basics.md"
}'
INFO: 127.0.0.1:63609 - "POST /api/documents/upload HTTP/1.1" 200 OK
{"document_id":"0ddedf08-4c45-428c-8238-059043477149","status":"success"}%
Note down the document_id, this is needed for the next steps
- Generation of the nodes etc
curl -X POST "http://localhost:7000/api/search" \
-H "Content-Type: application/json" \
-d '{
"query": "what is paired data?",
"limit": 3
}'
INFO: 127.0.0.1:54794 - "POST /api/search HTTP/1.1" 200 OK
{"query":"what is paired data?","results":[]}%
hkothand@Harishs-MBP mindmap_test % vi ../mindmap/README.md
hkothand@Harishs-MBP mindmap_test % curl -X POST "http://localhost:7000/api/generate" \
-H "Content-Type: application/json" \
-d '{
"text": "dummy text, will be ignored",
"document_id": "0ddedf08-4c45-428c-8238-059043477149"
}'
INFO: 127.0.0.1:54834 - "POST /api/generate HTTP/1.1" 200 OK
{"session_id":"4eac91d3-0e0f-4319-8a62-2724e48508ab","graph":{"nodes":{"root":{"id":"root","label":"Machine Learning Basics","summary":"","depth":0,"expanded":true},"5012d3ad":{"id":"5012d3ad","label":"Subset of Artificial Intelligence","summary":"","depth":1,"expanded":true},"ac261015":{"id":"ac261015","label":"Supervised Learning Type","summary":"","depth":1,"expanded":true},"df44ad7c":{"id":"df44ad7c","label":"Trained on labeled data","summary":"","depth":2,"expanded":true},"1de98421":{"id":"1de98421","label":"Unsupervised Learning Type","summary":"","depth":1,"expanded":true},"5f190687":{"id":"5f190687","label":"Trained on unlabeled data","summary":"","depth":2,"expanded":true}},"edges":[{"source":"root","target":"5012d3ad"},{"source":"root","target":"ac261015"},{"source":"ac261015","target":"df44ad7c"},{"source":"root","target":"1de98421"},{"source":"1de98421","target":"5f190687"}],"expanded_nodes":["root","5f190687","5012d3ad","1de98421","df44ad7c","ac261015"],"hidden_nodes":[]},"markdown":"# Machine Learning Basics\n- Subset of Artificial Intelligence\n- Supervised Learning Type\n - Trained on labeled data\n- Unsupervised Learning Type\n - Trained on unlabeled data"}%
- Searching the document
curl -X POST "http://localhost:7000/api/search" \
-H "Content-Type: application/json" \
-d '{
"query": "label",
"limit": 3
}'
INFO: 127.0.0.1:55016 - "POST /api/search HTTP/1.1" 200 OK
{"query":"label","results":[]}%
Open browser developer tools and inspect the console. The frontend imports Mind Elixir from https://esm.sh/mind-elixir@4; an offline browser or restrictive network/content-security policy can prevent that import.
Use New Map. It clears the saved session ID in the browser and reloads the page. To remove all saved server sessions during development, stop the app and delete mindmap_sessions.db. The reset button centers the map/resets the canvas to the state when it was drawn. Note - your node expansions, Q/A are still saved on resetting the canvas as long as your mindmap_sessions.db is available.
I made this to just help making learning easy. Feel free to modify it as per your own convenience.
Export the API keys etc on your terminal, and not in the app if you decide to modify it.
Happy learning!
I have created an UPDATES.md that documents the changes I'll be making to the tool.
- esm.sh for the mind-elixir library
- This standalone application was developed with AI assistance and was informed by prior use of Fu-Jie's MIT-licensed Smart Mind Map Tool for Open WebUI, found here: https://github.com/Fu-Jie/openwebui-extensions/tree/main/plugins/tools/smart-mind-map-tool. The current implementation is a separate FastAPI and Mind Elixir application.
This project is licensed under the MIT License. See MIT LICENSE.
This project was developed with human authorship and AI-assisted development.
