# Family Tree: a Next.js family tree driven by one JSON file

> The familytree project is a small Next.js application that renders a family tree from a single JSON file, with optional login that is a soft gate rather than a real one. Its interesting decision is the data model, which is a list of generations rather than a graph, so relationships come from a fatherId field.

**qiaoshouqing/familytree** — A minimalist open-source family tree website project.

- Repository: https://github.com/qiaoshouqing/familytree
- Website: https://familytree.pomodiary.com/
- Stars: 560 · Forks: 107
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/qiaoshouqing-familytree

## The whole family history is one JSON file

This is a minimalist open source family tree website project, a family tree visualization built with Next.js for displaying and managing your family history and member relationships. There is a live demo at familytree.pomodiary.com.

The data model is the part that shapes everything else. Family data is stored in JSON format, organised by generations. Each generation has a title and a group of people, and each person includes an id, a name, information and a father's id. Parent-child relationships are established through fatherId.

The example in the README shows the shape:

```json
{
  "generations": [
    {
      "title": "First Generation",
      "people": [
        {
          "id": "person-id",
          "name": "Name",
          "info": "Person description",
          "fatherId": "Father's ID",
          "birthYear": 1900,
          "deathYear": 1980
        }
      ]
    }
  ]
}
```

So the tree is a list of generations, each with a list of people, and the edges are derived from a reference to the father's id. birthYear and deathYear are optional, and the info field is free text for a personal description or life summary.

That design is a deliberate simplification. A general family tree needs arbitrary relationships, so a graph is the general answer, and a graph needs edge management, cycle detection and a layout algorithm. Here the hierarchy is assumed, the layout is a function of the generation index, and the only relationship that has to be right is the parent link.

The cost is that a mother is not a first class relationship. The documentation says you can add spouse, children and other important information in the info field, which is the honest description of a model that records descent and leaves the rest to prose.

## Installation is four package managers and one config copy

The Quick Start is short, and it offers the same four package managers because the project does not care which one you use.

```bash
npm install
# or
yarn install
# or
pnpm install
# or
bun install
```

Then the environment file is copied from its template:

```bash
cp .env.local.example .env.local
```

The variables in it are the family's public identity and the access rule. There is a flag for whether login authentication is required, an authentication mode that is either all, meaning allow all family members, or specific, meaning only allow specific names, the specific login name to match against, a family name used for the website title, description and footer, and the application port.

The port variable appears twice in the project, because it is read by the npm scripts as well as by the environment file. The dev script is next dev with turbopack and the port coming from an environment variable with a default of 3000, and the start script is the same with next start. So changing the port in one place changes it in both.

The run step is the mirror image of the install step, with the same four package managers offering a dev script, and then you visit http://localhost:3000 to view your tree.

The project is MIT licensed, the primary language is TypeScript, the default branch is main, and the last push was on 2026-07-02. It publishes no GitHub releases, and the package manifest marks the package as private with version 0.1.0, which is right for something intended to be forked rather than installed.

## The login is a soft gate, and the variable names say so

The login mechanism is worth examining closely, because the feature list calls it an optional login authentication mechanism and the implementation is simpler than that phrase suggests.

The mode is a string, either all or specific, and in specific mode the supplied name is matched against the logged-in name. So the mechanism is a name comparison, not a credential check. Anyone who knows the family name can get in.

The variable naming makes the intent explicit. The flag that turns authentication on is prefixed with NEXT_PUBLIC, which in Next.js means the value is inlined into the client bundle at build time rather than kept on the server. The family name is prefixed the same way, and it is described as the surname configuration for the website title, description and footer, so it is meant to be public.

That is a reasonable choice for this project and it is worth being precise about what it is. A gate that compares a name typed into a login form against a value shipped in the client bundle is a way of keeping a public site tidy, not a way of keeping private records private. If your tree contains information you would not want indexed or read by anyone who guesses the surname, this mechanism does not provide that.

The project is a family tree site, and the most common deployment is a public page for a family, so the naming is a soft gate for the whole site rather than a per-record access control. Anyone reading the source can see the configured name.

## The AI-assisted data entry workflow is the most practical part

The section on using AI to generate family data is unusual in a project README, and it is the part that solves the real problem, which is that a family history is a pile of unstructured notes.

If you have a large amount of family data to organize, you can use AI to help you quickly generate JSON data in the correct format. The procedure is: prepare your family information text, including names, relationships and relevant information for each generation, then give a model such as DeepSeek, ChatGPT or Claude a format guide, then copy the generated JSON into config/family-data.json, then check and adjust the generated data to ensure the relationships are accurate and the format is correct.

The format guide that is fed to the model is a template with a numbered list of requirements: generate a unique id for each person, such as first-gen-1 or second-gen-2, correctly set fatherId to establish parent-child relationships, categorise people by generation, include spouse, achievements and similar in the info field, use birthYear and deathYear to record the years if available, and ensure the JSON format is valid and can be directly imported.

That is a good decomposition of the problem. The hard part of the data entry is not the JSON, it is the model, and the requirements list tells the model exactly what the shape of the tree has to satisfy. The instruction to check and adjust the relationships afterwards is the honest part, because the parent links are the only thing in the file that a mistake in which makes the tree render wrong.

The documentation says this method can quickly convert unstructured family information into the JSON format the system requires, particularly suitable for large amounts of data, and the visualisation itself is not the hard part.

## A React Flow canvas with Tailwind, deployed to Vercel

The package manifest shows what the interface is built from. Next.js is pinned at 15.2.2 with React 19, and the visualisation library is reactflow at version 11, with the heroicons React package for icons. Styling is Tailwind 4 through the PostCSS plugin, and the language is TypeScript 5 with the eslint 9 flat config.

That is a small, modern stack, and reactflow is the significant choice. A family tree is a graph layout problem, and reactflow gives you the node and edge primitives, pan and zoom, and the layout machinery, so the project does not have to write a tree layout from scratch. The generational structure of the data then becomes a mapping from generation index to row, which is straightforward once the graph primitives exist.

The scripts in the manifest are minimal. There is dev, build and start as you would expect from Next.js, a lint script using next lint, and one that is worth pointing out: init-config, which runs a script called exportManualData.js. That is the path by which the JSON in the config directory becomes whatever the application reads, and it is the one piece of the pipeline that the README does not walk through in detail.

For deployment, the recommendation is the Vercel platform, in four steps: push your code to GitHub, GitLab or Bitbucket, import your repository on Vercel, set the environment variables, and deploy. The repository also carries a dokploy.json, which is a configuration for Dokploy, the self-hosted alternative to Vercel, so a deployment that avoids a third party is at least prepared for.

The project has a Chinese version of the README at README.zh.md, a CLAUDE.md, and the configuration directory with a family-data.example.json to copy from.

## Conclusion

Adopt this project if you want to publish a family tree quickly and are willing to hand edit a JSON file, since the whole family history is one document and the visual layer is a thin React Flow rendering of it. Do not adopt it if you need multi-user editing, since the data is a static file with an optional name-based login, not a database. Before you deploy, note that the environment variables are prefixed with NEXT_PUBLIC and therefore baked into the client bundle, so the authentication settings are a display convention rather than a security boundary, and that the recommended path is the Vercel import.

## FAQ

### How do I install and run this family tree project?

Run `npm install` (or yarn, pnpm or bun), copy the environment template with `cp .env.local.example .env.local`, create your data file `family-data.json` in the config directory, then run `npm run dev` and open http://localhost:3000.

### What is the family data format?

JSON organised by generations, where each generation has a title and a list of people, and each person has an id, a name, an info description, a fatherId used to establish the parent-child relationship, and optional birthYear and deathYear fields.

### How does the optional login work?

It is controlled by environment variables: a flag for whether authentication is required, a mode of all to allow all family members or specific to allow only specific names, and the name to match. The variables are prefixed with NEXT_PUBLIC, so the values end up in the client bundle, which makes this a simple gate rather than a secure one.

### Can I generate the family data with AI?

Yes. The README describes preparing your family information as text, giving a model such as DeepSeek, ChatGPT or Claude a format guide with the required JSON shape and rules, copying the result into config/family-data.json, and then checking that the relationships are correct before using it.

## Sources

- [Issues](https://github.com/qiaoshouqing/familytree/issues)
- [License: MIT](https://github.com/qiaoshouqing/familytree/blob/main/LICENSE)
- [Project website](https://familytree.pomodiary.com/)
- [qiaoshouqing/familytree on GitHub](https://github.com/qiaoshouqing/familytree)
- [README](https://github.com/qiaoshouqing/familytree/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/qiaoshouqing-familytree
