-
Notifications
You must be signed in to change notification settings - Fork 0
Development
This page covers setting up a local development environment for app/
itself — as opposed to Installing (running the packaged
desktop build) or Deploying (running the containerized
production shape). See Architecture first for how the
pieces fit together.
npm install # installs the workspace (app/ + packages/gramps-date)
cp app/.env.example app/.env.local # points at a running gramps-web-api instance
npm run dev -w app # starts the Vite dev serverapp/ needs a real gramps-web-api backend to talk to — it's a pure
client, there's no mock-data mode. The lightest option is
dev-fixtures/layer2-local-cache/api-fixture-example/setup.sh (see
Dev fixtures below).
Every fixture runs gramps-web-api from a source checkout in the same
Python environment as the fixture script, so that environment needs:
pip install -e ~/gramps/gramps --no-deps # gramps itself
pip install -e ~/gramps/gramps-web-api --no-deps # + its deps, see below
python3 deploy/webapi-requirements.py ~/gramps/gramps-web-api/pyproject.toml \
| pip install -r /dev/stdingramps-web-api's const.py does gi.require_version("Gtk", "3.0") at
import time, so real PyGObject and the GTK3 typelibs have to be present
(apt install python3-gi gir1.2-gtk-3.0, or
conda install -c conda-forge pygobject gtk3); PyICU is optional but
silences a localization warning and fixes name sorting.
Note that the /api/<type>/query/ endpoints app/ is built on landed in
gramps-project/gramps-web-api master — an older fork or branch 404s on
every one of them.
dev-fixtures/ holds real gramps-web-api backends for running app/
against locally. They're not part of the shipped product — just what makes
local development possible without hand-configuring a server of your own.
Read a script before running it — none of them are idempotent against
an already-populated tree. Every fixture logs in as gramps/gramps.
-
layer2-local-cache/api-fixture-example/— the lightest option: a plain-SQLite instance on:5002loaded with Gramps' own officialexample.grampssample database, useful for real date variety (modifiers, quality, ranges/spans). SetVITE_API_BASE=http://localhost:5002inapp/.env.localto point at it. Live sync works against it too, since it's just a poll against/api/transactions/history/, not tied to Postgres. -
layer2-local-cache/api-fixture/— another plain-SQLite instance, loaded withgramps-bench-generated synthetic data instead, for scale testing against a large tree. -
layer3-sync/api-fixture/— a real Postgres (SharedPostgreSQL) -backed instance, useful for exercising genuinely concurrent multi-writer edits against the same tree. This is whatapp/.env.example's defaultVITE_API_BASEpoints at, and it needs a running Postgres plus theSharedPostgreSQLaddon in addition to everything the SQLite fixtures need.
Gramplets run Python in the browser under Pyodide, against
locally-built wheels that npm install's postinstall step skips (with a
log line) when they aren't there yet — leaving Gramplets failing at run
time with No known package with name 'gramps-gen-lib'. Build them once:
python3 scripts/build-stub-wheels.py # gi + orjson stand-ins for Pyodide
python3 scripts/build-gramps-wheel.py # gramps.gen.lib as a Pyodide wheel
node app/scripts/copy-wasm.mjs # registers them in public/pyodide/npm run test -w app # Vitest: pure store/sync logic, not full-app rendering
npm run typecheck -w app # tsc --noEmit
npm run test -w packages/gramps-date
pytest tests/ # GOQL built-in filter presets vs. real gramps-core rulesThe pytest suite (tests/gql_presets/, see its own README) checks
every built-in Filters preset (app/src/data/gqlFilterPresets.ts)
against the real gramps-core Rule class it's meant to port, run
against gramps-core's own bundled example tree — catching not just
"does this compile" but "does it select the same rows the desktop rule
would." Needs gramps/gramps-object-query-language importable
(already true anywhere gramps-web-api itself runs); no separate step
needed to keep its own JSON snapshot of the presets in sync, that
happens automatically.
app/'s UI strings go through t() (app/src/i18n/i18n.ts), which
mirrors gramps-web's own
approach — a plain {english: translated} lookup, no i18n library —
merged from two sources per language, chosen at setLanguage() time and
cached in-memory until the next language switch:
-
The Gramps desktop vocabulary — translated live, per request, by
POSTing the strings actually in use to
gramps-web-api's existingGET/POST /api/translations/<lang>endpoint, which runs them through the installedgrampspackage's own gettext catalog. No static copy to keep in sync; always as fresh as whatevergrampsversion the server has installed. The fixed list of which desktop-vocabulary strings to request lives ini18n.ts'sdesktopStringsarray — grown by hand, one entry per string, whenever a newly-wrappedt()call turns out to be real Gramps vocabulary rather than something gramps-connect-specific. -
gramps-web's own UI strings, and Gramps addons' strings — bootstrapped
as static
app/public/lang/{locale}.jsonfiles (tracked in git, so the app works without anyone needing a Weblate connection) byscripts/bootstrap-translations.py, which reads../gramps-web/lang/and../addons-source/*/po/*-local.po— sibling checkouts of this repo, not a network call. Run it (python3 scripts/bootstrap-translations.py, needspip install polib) whenever those sibling checkouts get updated and you want the static corpus refreshed; it's not wired into any build step, so nothing runs it automatically. Safe to re-run: without--forceit skips any locale.jsonthat already exists, and even with--forceit only ever overwrites files underapp/public/lang/— no network calls, no git operations, and any bad result is agit checkoutaway from undone.
Wrapping more of the app's own strings in t() is ongoing, incremental
work — app/scripts/wrap-translations.mjs is a one-time codemod (kept
around as a reusable tool) that mechanically wraps plain JSX text and a
safe attribute allowlist (label/title/placeholder); anything sourced
from a variable or object-literal property (view/column configs in
app/src/store/views.ts, dynamic API data, notifications.show() calls)
needs a manual t(...) at whatever component renders it instead.
Discussion happens on the Gramps Discourse forum; issues and pull requests against the gramps-connect repo are welcome.
AGPL-3.0-or-later, matching gramps-web-api and gramps-web.
packages/gramps-date translates GPL-2.0-or-later Gramps core code into
this project's AGPL-3.0-or-later codebase — see its own README (and
Architecture) for how those two licenses
combine.
Gramps Connect is part of the family of Gramps-based software.
Using the app
- Overview
- Installing
- Deploying
- Messaging
- GOQL (advanced search)
- Gramplets & Add-on Store
- Data Model & Editing
- FAQ
Building & contributing