个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Build, edit, and export a family tree, entirely in the browser.
TL;DR: The Family Tree Project is a client-side app for building, editing, and exporting a family tree. There is no backend and no build step; everything runs in the browser and saves to localStorage.
The project set out to make it easy to sketch a family tree online without an account, a server, or dedicated software: open the page, add people, and the tree draws and saves itself in the browser. It also served as a from-scratch project for building out front-end and product skills.查看完整 README ↗Build, edit, and export a family tree, entirely in the browser.
Live site · Overview · Installation · Architecture · Contributing & Licence
TL;DR: The Family Tree Project is a client-side app for building, editing, and exporting a family tree. There is no backend and no build step; everything runs in the browser and saves to
localStorage.
| Status | Active |
| Stack | Vanilla HTML, CSS, and JavaScript (ES modules); no framework, no build step |
| Hosting | GitHub Pages |
| License | MIT |
| Live | techcabana.github.io/the-family-tree-project |
The project set out to make it easy to sketch a family tree online without an account, a server, or dedicated software: open the page, add people, and the tree draws and saves itself in the browser. It also served as a from-scratch project for building out front-end and product skills.
| In scope | Not in scope |
|---|---|
| Adding, editing, and positioning family members and their relationships (parent, spouse, partner, sibling) | User accounts or authentication |
| Filtering by tag, family side, generation, role, link, and status | Syncing a tree across devices or browsers |
| Exporting the tree as JSON, PNG, PDF, SVG, or CSV, and re-importing a JSON export | Server-side storage; all data lives in the browser's localStorage |
| Requirement | Version | Notes |
|---|---|---|
| A modern browser | any current version | The only runtime the app needs |
| A static file server | any | js/main.js loads as an ES module (type="module"), which browsers block when the page is opened directly via file://. The folder has to be served over http(s). |
git clone https://github.com/TechCabana/the-family-tree-project.git
cd the-family-tree-project
Nothing to install. There's no package manager and no build step; the app is plain HTML, CSS, and JavaScript served as-is.
python -m http.server 8080
Then open http://localhost:8080. Any other static file server (npx serve, VS Code's Live Server, etc.) works the same way.
You should see a demo family tree already drawn on the canvas, four generations starting with Robert Johnson and Mary Brown.
| Symptom | Cause | Fix |
|---|---|---|
| Blank canvas, or a console error about CORS or a module MIME type | index.html was opened directly via file:// instead of served over http | Serve the folder with a static server (step 3) and load it via http://localhost:... |
| The tree reverts to the demo data | Browser storage was cleared, or the page is open in a private/incognito window | Re-import a previous export with Import JSON in the sidebar |
| Layer | Choice | Why this one |
|---|---|---|
| Language | Vanilla JavaScript (ES modules), HTML, CSS | No framework or build step |
| Runtime | Browser only | Everything runs client-side |
| Storage | Browser localStorage (key familyTreeData) | No backend; a tree lives on the device that created it |
| Hosting | GitHub Pages | Static files, nothing to run server-side |
| Automation | None | No CI configured |
| Testing | None | No test suite in the repo |
Vanilla JavaScript, no framework, no build step. This project doubles as a from-scratch exercise in front-end fundamentals, and a framework or bundler would trade that learning value for conveniences a small, single-page app doesn't need. It also means the repo runs from any static file server with nothing to install and nothing to keep upgraded.
localStorage instead of a backend. No account, no server, and no data ever leaves the
browser that created it. A backend was considered and rejected: this is a single-maintainer,
zero-budget, zero-traffic personal project, and a free static site people use over the web
already satisfies the goal of a free, accessible tool without the ongoing cost and complexity of
hosting infrastructure, accounts, or sync. That tradeoff is a real limitation — a browser cache
clear with no export backup loses the tree — and is tracked as its own concern rather than solved
by adding a server. If real multi-device demand ever shows up, an optional cloud-backup tier (no
required signup) is the fallback direction, not full accounts.
Export libraries loaded from CDN, no bundler. html2canvas, jsPDF, and html-to-image are
pulled in directly by index.html rather than installed and bundled, so the "no build step"
promise holds even for a feature that would normally justify one.
flowchart LR
D[js/data.js demo seed] --> M[js/main.js state + render]
L[(localStorage)] --> M
M --> L
M --> T[Tree canvas: member cards + SVG links]
M --> E[Export: JSON / PNG / PDF / SVG / CSV]
index.html loads js/main.js as an ES module, which imports the demo dataset from js/data.js.main.js checks localStorage for a familyTreeData key. If it's there, it's used; otherwise the app clones the demo data (loadDataFromLocalStorage, js/main.js:6).#tree-layout as draggable cards, with relationship lines drawn on the #tree-connections SVG.#edit-modal, #relationship-modal). Saving calls saveDataToLocalStorage() (js/main.js:86), which persists the change.html2canvas, jsPDF, or html-to-image (all loaded from CDN in index.html) to produce a PNG, PDF, or SVG, or serializes it directly to JSON or CSV.{
"members": [
{ "id": 1, "name": "Robert Johnson", "relationship": "Great Grandfather", "status": "Married", "birthDate": "1925-03-15", "deathDate": "2005-11-20", "generation": 0, "side": "paternal", "tags": ["Military", "Craftsman"], "avatar": null, "description": "Served in WWII." }
],
"connections": [
{ "id": "c1", "members": [1, 2], "link": "Spouse", "type": "Biological", "status": "Married", "note": "Married for 50 years." }
]
}
| Field | Type | Notes |
|---|---|---|
members[].id | number | Unique per member |
members[].name | string | Full name |
members[].relationship | string | Role label shown on the card (Father, Grandmother, ...) |
members[].status | string | Relationship status (Married, Single, ...) |
members[].birthDate / deathDate | string (ISO date) or null | deathDate is null while the person is living |
members[].generation | number | Vertical tier used for layout and the generation filter |
members[].side | string | paternal, maternal, or ego |
members[].tags | string[] | Free-form labels shown on the card |
members[].avatar | string or null | Data URL of an uploaded photo, or null |
connections[].members | [number, number] | The two member ids the connection joins |
connections[].link | string | Parent, Spouse, Partner, or Sibling |
connections[].type | string | Biological, Adopted, or Step-Relationship |
the-family-tree-project/
├── index.html entry point: tree canvas, sidebar controls, edit modals
├── about.html static About page
├── how-to.html static user guide
├── css/
│ └── style.css all styling
├── js/
│ ├── main.js app state, rendering, editing, export logic
│ └── data.js demo seed data, used when localStorage is empty
├── assets/
│ ├── leaf.svg decorative background leaf
│ └── HowTo/ screenshots used by how-to.html
└── LICENSE MIT license text
| Path | Role |
|---|---|
index.html | Entry point and app shell |
js/main.js | All application logic: rendering, editing, filtering, export |
js/data.js | Seed data loaded on first run |
css/style.css | Single stylesheet for the whole app |
assets/ | Images used by the app and the how-to guide |
Issues and pull requests are welcome. Open an issue before starting anything large, so the approach can be agreed first. Commits follow Conventional Commits, and work lands on main through a pull request.
Released under the MIT licence. The full text is in LICENSE, and it covers the code in this repository only.
assets/icons.svg rather than loaded from CDNBuilt and maintained by TechCabana