genograph
v1.2.3
Published
Genograph — Offline, private family-tree browser & editor that runs in your browser. Your data never leaves your machine.
Maintainers
Readme
An offline, private family-tree browser & editor that runs in your own browser. Create, load and manage as many family trees as you like — record people, dates, places, relationships and interview notes. No account, no cloud, no tracking. Your data never leaves your machine.
Built for sitting down with relatives and slowly mapping out a family: click a person, ask questions, type what you learn, and everything saves automatically to a plain JSON file on your computer.
Why Genograph?
- Private by design. A tiny local server serves the app to
localhostonly and reads/writes JSON files on your disk. Nothing is ever uploaded. A strict Content Security Policy prevents outbound requests to third-party services. - Offline. The local version works completely offline; the hosted version continues working after it has loaded. No external fonts, scripts or CDNs.
- Zero runtime dependencies. Just Node.js and plain HTML/CSS/JS. Easy to audit.
- Yours forever. Trees are human-readable JSON you fully own; export any time.
- Built for real interviews. Per-person notes, approximate dates, uncertain flags, multiple marriages, maiden names, causes of death, and more.
Use it in your browser (no install)
Prefer not to install anything? A free, hosted build runs entirely in your browser:
→ https://genograph.github.io/
There is still no account, no cloud and no upload — the page is just the app, and your trees are saved on your own machine:
- Chromium browsers (Chrome, Edge, Brave, …): click Open a folder in the tree
menu and the app reads and writes real
.jsonfiles in the folder you pick — just like the local app, including automatic.backups/and a.trash/folder. Point it at a synced folder (Dropbox, iCloud Drive, …) and your trees follow you between machines. Genograph itself never uploads data; a synced folder may be transmitted by the storage provider you choose. - Other browsers (Safari, Firefox), or before you pick a folder: trees are kept in your browser's own local database. They persist across reloads on that browser; use Export JSON to back them up or carry them elsewhere.
After the hosted app has loaded, you can go offline and keep working.
For real files and automatic backups in every browser, install the local app below.
Install & run
You need Node.js 18 or newer.
Fastest — run without installing
npx genographThis downloads and starts the app, then opens it in your browser at
http://localhost:3456.
Install globally
npm install -g genograph
genographFrom source
git clone https://github.com/genograph/genograph.github.io.git
cd genograph.github.io
npm startStop the app any time with Ctrl+C.
Usage
The app opens with an example tree (the immediate relatives of Guy de Lusignan, 12th-century King of Jerusalem) so you can explore right away.
- Your trees — use the tree menu in the header to create, open,
rename, duplicate, delete, import (a
.jsonfile) or export the current tree. - Data folder — the bottom of the tree menu shows where your trees are saved and lets you change it (for example to your Desktop or a synced folder). You can either point the app at an existing folder of trees or tick Move my current trees to take them with you. Your choice is remembered the next time you launch.
- Click a person to open the side panel and edit name, sex, birth/death/burial, occupation, and notes.
- Choose the default person from the side panel to decide who the tree opens on; the choice is saved with the tree.
- Double-click a person to re-root ("focus") the tree on them.
- Add relatives with the
+buttons in the panel (father / mother / spouse / child / sibling), or straight on the canvas: the selected person's card shows+buttons for each missing parent (above), a spouse (right edge) and a new child (below). While typing a name you can link an existing person instead of creating a duplicate. - Views: Whole Family, Close Family, Ancestors (segmented control, top).
- Search anyone (top-left), including people not connected to the current view.
- Dark mode and EN / TR language toggle in the header.
- Drag to pan, scroll / pinch to zoom, Fit to frame the whole tree.
Command-line options
genograph [options]
-p, --port <n> Port to listen on (default 3456)
-d, --data <dir> Folder to store your trees (default ~/.genograph/trees)
--host <addr> Address to bind (default 127.0.0.1)
--no-open Don't open the browser automatically
-h, --help Show help
-v, --version Show versionYou can also set the data folder with the GENOGRAPH_DATA environment variable.
Where your trees are saved
By default trees live in ~/.genograph/trees. There are three ways to change
that, in order of priority:
--data <dir>orGENOGRAPH_DATA— pins the folder for that run only.- In the app — the tree menu has a Data folder row showing the current
path with an option to switch to any folder (e.g.
~/Desktop/family-trees). The folder is created if it doesn't exist, and you can move your existing trees into it. This choice is remembered in~/.genograph/config.jsonand used on the next launch. - The default —
~/.genograph/treeswhen nothing above is set.
A --data flag or GENOGRAPH_DATA always wins over the remembered choice and,
while active, the in-app picker is disabled so the session stays where you pointed it.
Your data & privacy
- Trees are stored as individual JSON files in your data folder (by default
~/.genograph/trees). Each save first copies the previous version into a.backups/folder (the newest copies are kept) so you can recover from mistakes. On macOS and Linux, app-created files use owner-only permissions; the default app folder is also tightened automatically when an older installation starts. - The server binds to
127.0.0.1and rejects requests with a non-localHostheader, so other devices on your network cannot reach it. Browser mutations additionally require the exact local origin and a per-process request token. - Nothing is sent anywhere. This is a local tool; treat your data folder like any other personal documents and back it up yourself if it matters to you.
Tree file format
A tree is a JSON object with a people array. Each person has a stable id plus
optional fields:
{
"summary": { "name": "My Family", "root": "p1" },
"people": [
{
"id": "p1",
"name": "Ada Lovelace",
"sex": "F",
"birth_date": "1815.12.10", // YYYY | YYYY.MM | YYYY.MM.DD
"birth_place": "London",
"birth_country": "England",
"occupation": "Mathematician",
"deceased": true,
"death_date": "1852.11.27",
"notes": "Notes from the interview…",
"father_id": "p2",
"mother_id": "p3",
"spouse_ids": ["p4"],
"children_ids": ["p5"]
}
]
}Relationships are stored by id (names can repeat in a family, so ids keep links
unambiguous); human-readable name fields are written alongside for portability.
Dates support an approximate flag (birth_date_uncertain, …). See
examples/lusignan.json for a complete example.
Genograph currently imports and exports its documented JSON format. GEDCOM import/export, source citations, media attachments and printable tree export are not yet supported.
Development
npm start # run the app from source
npm test # run the fast suite (Node's built-in test runner)
npm run test:e2e # run browser lifecycle tests (after installing Playwright)
npm run test:watch # re-run tests on changeThe core logic is split into small, dependency-free, unit-tested modules:
public/lib/model.js— parsing, migration, date/place normalization, serializationpublic/lib/layout.js— the genealogy layout algorithmpublic/lib/treeStore.js— shared, pure store helpers (id rules, slugging, tree shape)public/lib/storage.js— picks a storage backend for the environment, with three behind it:serverStore.js(local API),fsStore.js(File System Access folder) andidbStore.js(IndexedDB)src/store.js— safe tree file storage with backups (Node)src/server.js— the local HTTP server and JSON API
See CONTRIBUTING.md.
For security vulnerabilities, follow the private reporting instructions in SECURITY.md. Never attach a real family tree or information about living people to a public issue.
Hosting the browser app
.github/workflows/pages.yml publishes the static app to GitHub Pages on every push to
main. It assembles _site from public/ plus the bundled examples/lusignan.json and
nothing else — your trees/ folder is gitignored and never part of the build, so no private
data can ship. The same public/ is served by the local Node server, so there is one codebase:
it detects /api/trees to use the server, and falls back to browser storage when hosted statically.
License
MIT © Mete Morris
