FamilyNest is a web-based application for creating and managing family trees. It is designed to be modular and can connect to various backend servers for data management.
Demo available! The Supabase demo server is available as a website if you want to test FamilyNest before installing it on your own server. Visit the demo site here: https://familynest-web.vercel.app.
- Features
- Technologies
- Getting Started
- Backend & Servers
- Person Data Structure
- API Endpoint Guide
- Contributing
- Acknowledgements
- License
- Create, view, and edit family trees with an intuitive interface.
- Supports complex relationships like remarriage and consanguinity.
- Connects to different backend servers for flexible data storage.
- Responsive design for use on desktops, tablets, and mobile devices.
- Multi-language support with an integrated translation system.
- Frontend: Built with Rust compiled to WASM (WebAssembly) and Vanilla JavaScript.
- Backend: Can connect to any backend server that implements the API specification.
If you just want to use the application without hosting it yourself, you can find a public demo server and follow its instructions.
To run the frontend interface locally, you'll need the following prerequisites installed:
To run the frontend interface locally, follow these steps:
-
Clone the repository:
git clone https://github.com/PaulExplorer/FamilyNestWeb.git cd FamilyNestWeb -
Important: FamilyNest is only a frontend; it requires a backend server to function. For development, we recommend running
dev.pyin the JSON Server that a simple server and it's good for testing. Configure the frontend to connect to it during development, the frontend is already configured by default to connect to this development server. -
Start the frontend server for development:
trunk serve
-
Or, to build the optimized release version for production:
trunk build --release -M
Example servers are provided in separate repositories to demonstrate backend implementation. Please refer to their respective documentation for setup instructions.
- Simple JSON Server: A basic server that uses a single JSON file for data storage. This is the easiest way to get started with development.
- Supabase Server: A more advanced server that uses Supabase for multi-user management, authentication, and collaboration.
If you want to create your own custom server (e.g., using Node.js, Python, or another technology), you must implement the endpoints defined in the API Endpoint Guide. Your server must send and receive data matching the Person Data Structure. The JSON server is the simplest example to follow.
All person data exchanged with the server (e.g., in GET /data and POST /persons/batch) should follow this JSON structure.
A Person object has the following fields:
id(number): The unique integer ID.firstname(string): The person's first name.lastname(string): The person's last name.nickname(string, optional): A nickname.gender(string): "M" (Male), "F" (Female), "U" (Unknown) or "O" (Other).notes(string, optional): Free-form text notes.sources(array of strings, optional): A list of source descriptions.events(object, optional): A map where keys are event types (e.g., "birth", "death") and values are an array ofLifeEventobjects.parents(array of numbers, optional): A list of parent IDs.spouses(array of numbers, optional): A list of spouse IDs.country(string, optional): A country of residence or origin.job(string, optional): A job or occupation.photo(string, optional): A URL to a photo.documents(array ofDocument, optional): A list of associated documents.version(number): An internal version number for cache and conflict management.
date(object): AFlexibleDateobject.place(object): APlaceobject.note(string, optional): A note specific to this event.
A string representing the date and its precision, e.g., "Nor. 2025-11-12". The precision can be "Nor." (Exact), "Ab." (About), "Bf." (Before), or "Aft." (After).
name(string, optional): The short name of the place.display_name(string): The full, formatted name of the place.coord(object, optional): ACoordobject.
latitude(number)longitude(number)
name(string): The display name for the document.url(string): The URL where the document can be accessed.
All API requests are made to a base URL that you must define in index.html inside the initConnection function. The server must implement the following endpoints relative to that base URL.
This is the root/health-check endpoint. The server should return a JSON response with its configuration and status.
Response Fields:
exist(boolean):trueif the family tree at this endpoint exists.success(boolean):trueif the request was successful.error(string, optional): An error message, if any.demo(boolean): Iftrue, editing is enabled in the UI without saving to the backend (demo mode).file(boolean): Iftrue, file uploads are supported and enabled by the server.editable(boolean): Iftrue, editing and saving are enabled.
Requests a new, unique ID from the server to create a new person.
Response Fields:
success(boolean):trueif the request is successful.error(string): An error message, if any.id(number): A unique integer ID for the new person.
Fetches the entire list of persons in the family tree.
Response Fields:
success(boolean):trueif the request is successful.error(string): An error message, if any.data(array): A list ofPersonobjects (see Person Data Structure).
The primary endpoint for saving changes to the tree. It sends additions, modifications, and deletions in a single "batch" request.
JSON Payload Fields:
add(array): A list of newPersonobjects to add.modify(array): A list of existingPersonobjects to update.delete(array): A list of person IDs (numbers) to delete.
Response Fields:
success(boolean):trueif the request is successful.error(string): An error message, if any.
Uploads a file (image or document) to the server. The file should be sent in the request body (e.g., as multipart/form-data).
<type>should be the stringimageordocument.
Response Fields:
success(boolean):trueif the request is successful.error(string): An error message, if any.filename(string): The new filename or identifier for the uploaded file (if successful).url(string): The public-facing URL to access the file (if successful).
If your backend requires custom headers for authentication (e.g., CSRF tokens, API keys), you can add them by modifying the additionalHeaders object in index.html.
<script>
let additionalHeaders = {
"X-CSRF-Token": "your-token-here",
Authorization: "Bearer your-api-key",
};
// ... rest of the script
</script>These headers will be included in all API requests made to the backend.
Contributions are welcome! Please feel free to submit a Pull Request or open an issue for any bugs or feature requests.
This project relies on the powerful graph layout capabilities of Graphviz to calculate the positions of individuals in the family tree. The rendering in the browser is made possible by Viz.js, a JavaScript port of Graphviz.
A huge thank you to the creators and maintainers of these tools for their significant contributions to the open-source community.
This project is licensed under the AGPLv3 License.