Skip to main content

gedcom-lite

A lightweight, fidelity-preserving GEDCOM parser, writer, and command-line toolkit for genealogy files. Supports GEDCOM 5.5.1, 5.5.5, and the current FamilySearch GEDCOM 7.0+ standard.

The "lite" in the name is a deliberate scope choice: pure Python, no runtime dependencies, no schema validation, no genealogy domain modelling beyond what the file format itself defines. The library models GEDCOM as a tree of Structure records and exposes search and mutation primitives that round-trip every file in the official sample suite byte-for-byte.

Why use it

  • Round-trip fidelity. Parse a file and write it back unchanged: BOM, line endings, CONC/CONT choice, sibling order, and unknown extension tags are all preserved.
  • Targeted edits. Mutation primitives mark only the structures you change as dirty; every other line emits byte-identical to the source. An update that touches a single NAME produces a one-line diff.
  • Encoding coverage. Detects UTF-8 (with or without BOM), UTF-16 LE/BE (with BOM), and ANSEL (legacy 5.5.1) — the ANSEL codec ships in-package.
  • No dependencies. Pure Python 3.11+ standard library.
  • Three CLI tools. gedcom-read, gedcom-search, gedcom-update cover the common verbs without scripting.

Install

# from PyPI
pip install gedcom-lite

# from git
pip install "git+https://github.com/vaelen/gedcom-lite@v0.1.0"

# editable, for hacking
git clone https://github.com/vaelen/gedcom-lite
cd gedcom-lite
pip install -e ".[dev]"

Library usage

from gedcom_lite import GedcomDocument

doc = GedcomDocument.parse("tree.ged")

print(doc.version)               # '7.0'
print(doc.encoding)              # 'utf-8-sig'
print(doc.record_counts())       # {'INDI': 142, 'FAM': 47, ...}

indi = doc.resolve("@I1@")
name = indi.find("NAME")
name.set_payload("Jane /Doe/")

doc.write("tree-edited.ged")

The full surface is documented in src/gedcom_lite/__init__.py. Common helpers:

from gedcom_lite import (
    GedcomDocument, Structure,
    parse_date_value, DateValue,
    parents_of, children_of, ancestors_of, descendants_of,
    document_to_dict, structure_to_dict,
)

CLI usage

Three console scripts are installed:

gedcom-read   FILE [...]
gedcom-search FILE [filters...]
gedcom-update FILE [-o OUT | --in-place] SUBCOMMAND ...

Examples:

# overview of a file
gedcom-read tree.ged

# list every individual
gedcom-read tree.ged list INDI

# show one record with pointers resolved
gedcom-read tree.ged record @I1@

# JSON dump for piping into jq
gedcom-read tree.ged --json | jq '.records | length'

# find people named Smith
gedcom-search tree.ged --person Smith

# people born between 1900 and 1910
gedcom-search tree.ged --born-between 1900 1910

# died before 1776 (MIN/MAX work as unbounded sentinels on either side)
gedcom-search tree.ged --died-between MIN 1776

# combine person/date/place filters — they AND together
gedcom-search tree.ged --person Smith --born-between 1800 1850 --died-in Boston

# children, parents, ancestors, descendants
gedcom-search tree.ged --children-of @I1@
gedcom-search tree.ged --ancestors-of @I1@ --depth 4

# traversal composes with person/date/place filters as a post-filter
gedcom-search tree.ged --ancestors-of @I1@ --born-in Boston --facts

# ancestor records carry their generation in JSON (subject = 0, parents = 1, …)
gedcom-search tree.ged --ancestors-of @I1@ --json | jq '.[].generation'

# canonical per-INDI facts (xref, name, birth, death, parents, famc)
gedcom-search tree.ged --xref @I1@ --facts
gedcom-search tree.ged --ancestors-of @I1@ --facts | jq '.[] | {xref, name, generation}'

# Sosa-Stradonitz numbered ancestors (subject = 1, father of N = 2N, mother = 2N+1)
gedcom-search tree.ged --ahnentafel @I1@ --primary-famc-only

# list individuals with conflicting (multiple) FAMC links
gedcom-search tree.ged --famc-conflicts --facts

# edit a name (default writes to stdout)
gedcom-update tree.ged set-payload @I1@ NAME "Jane /Doe/" > new.ged

# add a NOTE to a record (write to a file)
gedcom-update tree.ged -o new.ged add-substructure @I1@ "" NOTE "Met at reunion"

# delete a record, voiding inbound pointers
gedcom-update tree.ged -o new.ged delete-record @I7@ --orphan-pointers void

# overwrite the source (be sure)
gedcom-update tree.ged --in-place set-payload @I1@ NAME "Jane /Doe/"

gedcom-update never modifies the input file unless --in-place is given.

Run any tool with --help for the full flag list.

Tests

pip install -e ".[dev]"
pytest

The suite covers:

  • Tokenizer edge cases (xref slot, missing payload, malformed lines)
  • Encoding detection (BOM-first, then 1 CHAR, then ANSEL)
  • ANSEL codec round-trips, including combining-mark ordering
  • Date parsing across ABT, BET … AND …, FROM … TO …, calendar escapes
  • Round-trip of every fixture in examples/ (the gating test)
  • Mutation primitives, including the "only-touched-lines-change" property
  • Ancestry/descendancy traversal
  • CLI smoke tests for gedcom-read, gedcom-search, gedcom-update

Releasing

Maintainer notes — releases publish to PyPI from .github/workflows/release.yml via OIDC trusted publishing (no stored tokens).

  1. Bump the version in pyproject.toml, src/gedcom_lite/__init__.py, and CHANGELOG.md. Push the changes to the main branch.
  2. (Optional) Rehearse to TestPyPI: gh workflow run release.yml.
  3. Cut the release: gh release create vX.Y.Z --generate-notes. The workflow builds and uploads to PyPI on the release: published event.

The PyPI / TestPyPI trusted-publisher entries and the matching pypi / testpypi GitHub Environments are one-time setup, documented at the top of release.yml. CI runs pytest on push and PR across Python 3.11/3.12/3.13.

Versions in scope

  • GEDCOM 5.5.1 (1999) — the de-facto interchange format used by virtually every genealogy app shipped before 2022.
  • GEDCOM 5.5.5 (2019) — cleanup release of the 5.5.x line.
  • FamilySearch GEDCOM 7.0+ (2021–) — current, actively maintained. UTF-8 only, real extension mechanism, GEDZIP packaging, no CONC.

GEDCOM 7 is a breaking change from 5.5.x. gedcom-lite reads any of the three; on write it never silently promotes a file to a different version.

License

MIT — see LICENSE.

References

Metadata

Release files for gedcom-lite 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gedcom-lite 0.2.0
File Size Uploaded
gedcom_lite-0.2.0.tar.gz 143.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gedcom-lite 0.2.0
File Interpreter ABI Platform
gedcom_lite-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 174.0 kB

Release files / gedcom_lite-0.2.0.tar.gz

Download URL gedcom_lite-0.2.0.tar.gz
Size 143.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b7fdddbdc469abaae00163ccddf5848d48d99fb677741ee6f936f1d50b7c6b1c
BLAKE2b-256 checksum
How to use checksums
174d3f2b7bd901190cf668826f050c30d9b19ecf2a45650c0058af9e6706eb60
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 6, 2026.

Transparency log

Release files / gedcom_lite-0.2.0-py3-none-any.whl

Download URL gedcom_lite-0.2.0-py3-none-any.whl
Size 30.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0f71a3e77e6c451c900c7fc5030f437f9fc9d49dbd525dc222ae0197cc310559
BLAKE2b-256 checksum
How to use checksums
78a1a47fdbb7eb8ed5ef45c8d426dc227324e778d6c2e988a90a4425be9649e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page