Vagibond

Follow Vagibond

Stay connected with us on social media for updates on new ventures.

Thanks for subscribing!

Incestry API

Incestry is an interactive family tree visualization SDK. Build zoomable, pannable family trees with support for complex relationships including sibling marriages, uncle-niece unions, and the kind of circular ancestry that makes geneticists weep.

🌳
Family Tree or Family Wreath?
Our advanced algorithms can detect when your ancestry is "concerningly circular" and visualize the full horror with ghost nodes and inbreeding indicators.

What You Can Build

Live Demo

See what you can build with the Incestry API.

Incestry Demo

Or see the full Targaryen family tree in action:

Targaryen Family Tree Demo

Quickstart

Add an interactive family tree to your site in under 60 seconds.

1. Add a container

html
<!-- Container must have width and height -->
<div id="family-tree" style="width: 100%; height: 600px;"></div>

2. Include the SDK and initialize

html
<script src="https://incestry.vagibond.com/incestry-core.js"></script>
<script>
  Incestry.init('#family-tree', {
    theme: 'incestry-royal',
    layout: 'horizontal'
  });

  Incestry.loadFromUrl('/data/my-family.json');
</script>

Or use auto-initialization

html
<!-- Data attribute auto-loads the tree -->
<div data-incestry="/data/my-family.json"
     data-incestry-theme="incestry-royal"
     data-incestry-layout="horizontal"
     style="width: 100%; height: 600px;"></div>

<script src="https://incestry.vagibond.com/incestry-core.js"></script>

Installation

CDN (Recommended)

html
<script src="https://incestry.vagibond.com/incestry-core.js"></script>

Self-hosted

bash
curl -O https://incestry.vagibond.com/incestry-core.js

Configuration Options

Pass these options to Incestry.init().

Option Type Default Description
layout string 'horizontal' 'horizontal' (top-down) or 'vertical' (left-right)
theme string 'incestry-default' Theme name: 'incestry-default', 'incestry-royal', 'incestry-dark'
nodeWidth number 140 Width of person nodes in pixels
nodeHeight number 180 Height of person nodes in pixels
minZoom number 0.2 Minimum zoom level
maxZoom number 3 Maximum zoom level
fitOnInit boolean true Auto-fit tree to viewport on load
enablePan boolean true Enable drag-to-pan
enableZoom boolean true Enable scroll/pinch zoom
enableTouch boolean true Enable touch gestures (pinch zoom)
showPhotos boolean true Display profile photos in nodes
showDates boolean true Display birth/death dates
showInbreedingIndicators boolean true Show warning badges on inbred individuals
showRelationshipLabels boolean true Show labels like "Sibling Marriage" on unions
onNodeClick function null Callback when a node is clicked
onReady function null Callback when tree is fully loaded

Themes

Three built-in themes are available.

Theme Description Best For
incestry-default Light cream background, teal/brown accents General family trees, ancestry sites
incestry-royal Dark purple background, gold accents Royal dynasties, Game of Thrones fans
incestry-dark Dark gray background, cyan accents Modern apps, dark mode preference
javascript
// Change theme at runtime
Incestry.setTheme('incestry-royal');

Layouts

Layout Description
horizontal Root at top, descendants flow downward (org chart style)
vertical Root at left, descendants flow right (timeline style)
javascript
// Toggle layout at runtime
Incestry.setLayout('vertical');

Data Schema Overview

Family tree data is provided as JSON with three main sections.

json
{
  "meta": {
    "title": "House Targaryen",
    "description": "Fire and Blood"
  },
  "people": [ ... ],
  "unions": [ ... ],
  "roots": ["person-id-1"],
  "inbreeding": { ... }
}

People Schema

Each person in the tree.

json
{
  "id": "aegon-i",
  "firstName": "Aegon",
  "lastName": "Targaryen",
  "nickname": "The Conqueror",
  "gender": "male",           // "male", "female", "other"
  "birthDate": "27 BC",
  "deathDate": "37 AC",
  "photo": "https://example.com/photo.jpg",
  "bio": "First King of the Seven Kingdoms",
  "customFields": {
    "Dragon": "Balerion",
    "Title": "King"
  }
}
Field Required Description
id Yes Unique identifier
firstName Yes First name (or full name if no lastName)
lastName No Last name / surname
nickname No Displayed in quotes below name
gender No Affects node border color
birthDate No Any date format
deathDate No Any date format
photo No URL to profile photo
bio No Short bio shown in popup
customFields No Key-value pairs shown in popup

Unions Schema

Marriages, partnerships, and parent-child relationships.

json
{
  "id": "aegon-visenya",
  "type": "marriage",         // "marriage", "partnership", "affair"
  "partners": ["aegon-i", "visenya"],
  "children": ["maegor-i"],
  "label": "Sibling Marriage"  // Optional label
}

Inbreeding Data

Optional inbreeding coefficients for each person.

json
{
  "inbreeding": {
    "daenerys": {
      "coefficient": 0.375,
      "note": "4th generation of sibling marriages"
    }
  }
}

When present, nodes with inbreeding data will display a warning indicator and the coefficient in their popup.

API Methods

Incestry.init(selector, options)

Initialize the tree in a container.

javascript
Incestry.init('#container', { theme: 'incestry-royal' });

Incestry.setData(data)

Set tree data directly.

javascript
Incestry.setData({
  people: [...],
  unions: [...],
  roots: ['person-1']
});

Incestry.loadFromUrl(url)

Load tree data from a JSON URL.

javascript
Incestry.loadFromUrl('/data/family.json');

Incestry.setTheme(themeName)

Change the visual theme.

Incestry.setLayout(mode)

Switch between 'horizontal' and 'vertical' layouts.

Incestry.setZoom(level)

Set zoom level (0.2 to 3).

Incestry.resetView()

Reset to fit all nodes in viewport.

Incestry.focusNode(nodeId)

Pan to and select a specific node.

javascript
Incestry.focusNode('daenerys');

Incestry.selectNode(nodeId)

Select a node and show its popup.

Incestry.deselectAll()

Deselect all nodes and hide popups.

Incestry.getSelectedNode()

Returns the currently selected node data, or null.

Incestry.destroy()

Clean up and remove the tree.

Events

Use callbacks in config or the on() method.

javascript
Incestry.init('#tree', {
  onNodeClick: (node) => {
    console.log('Clicked:', node.firstName);
  },
  onZoomChange: (zoom) => {
    console.log('Zoom:', Math.round(zoom * 100) + '%');
  },
  onLayoutChange: (layout) => {
    console.log('Layout:', layout);
  },
  onReady: () => {
    console.log('Tree loaded!');
  }
});

Changelog

v1.0.0 2026-02-02
  • feature Initial release
  • feature SVG-based rendering with pan/zoom
  • feature Touch support (pinch zoom, drag)
  • feature 3 built-in themes
  • feature Inbreeding detection and visualization
  • feature Ghost nodes for cycle handling
  • feature Keyboard navigation (arrow keys, +/-, 0 to reset)
  • feature Targaryen family tree demo