An open, version-archived database of psychoactive substance information —
routes of administration, dosing, durations, interactions, tolerance, and
safer-use notes — packaged as a single substances.json file.
It is the shared data source embedded by the PsychonautWiki Journal apps and compatible clients, and it is designed to be extended and corrected by the community.
| Path | Contents |
|---|---|
working/substances.json |
The maintained database. This is the file clients embed. |
vendor/ |
Pristine, unmodified snapshots of the data from each upstream app release (e.g. v15.5.json), kept for archival and diffing. |
vendor/BASELINE |
The upstream version working/ is currently based on. |
tools/ |
Scripts for extracting, updating, and embedding the data + a v11 → v15 journal-export converter. |
samples/ |
Small synthetic journal-export files used as schema references and test fixtures. |
docs/ |
Format references — v15-export-schema.md documents the journal export format. |
The tools need Python 3 and git (the vendor merge uses git merge-file).
If you use Nix, a dev shell with both is provided:
nix developEdits are made directly to working/substances.json — it's plain JSON, sorted
alphabetically by substance name. You can add missing routes, fix a dose range,
correct an interaction, add tolerance timing, or add a whole new substance.
- Edit
working/substances.json. - Commit your change with a short description of what you added or fixed.
- Open a pull request.
Because every change is tracked in git, the history and reasoning behind each fact stays visible.
substances.json has two top-level arrays:
substances— one object per substance, with its routes of administration, dose ranges, durations, tolerance, and cross-tolerance/interaction lists.categories— descriptions and reference links for substance classes (e.g. stimulant, benzodiazepine).
Both arrays are sorted alphabetically by name.
New versions of the app ship updated substance data. The tools/ scripts fold
those updates into working/ while preserving community edits, using an
ordinary three-way merge.
cd tools
python3 update_vendor.py --apk /path/to/Journal.apk --version 15.6
# or: --ipa /path/to/Journal.ipaThis archives the new release under vendor/v15.6.json and merges upstream
changes into working/substances.json:
- Fields only the community changed are kept.
- Fields only upstream changed are updated.
- Fields both sides changed produce a normal git conflict marker to resolve by hand (rare, since most community edits fill gaps upstream doesn't have).
On a clean merge, vendor/BASELINE advances automatically. On a conflict,
resolve the markers in working/substances.json, then set vendor/BASELINE to
the new version.
extract.py sorts substances and categories alphabetically before saving.
Upstream ships them in a curated order that reshuffles between releases, which
would make every update an unreadable diff. Sorting turns "N substances added"
into clean line insertions, which keeps the three-way merges reliable.
tools/inject.py copies working/substances.json into a client's build tree.
cd tools
# Compose Multiplatform app
python3 inject.py --compose-app /path/to/composeApp
# Android (apktool decompile tree)
python3 inject.py --apk-decomp /path/to/decompiled
# iOS (unzipped IPA payload — updates the app and its widget extension)
python3 inject.py --ipa-payload /path/to/PayloadSeparate from the substance database: tools/convert_v11_to_v15.py upgrades a
PsychonautWiki Journal v11.x export — including PsyLog exports, which use
the identical v11 schema — to the v15 import format.
cd tools
python3 convert_v11_to_v15.py <input-v11.json> <output-v15.json>The v11 → v15 change is purely additive: v15 added fields on experiences and
ingestions plus top-level exportSource/customUnits. A raw v11 file is
rejected by v15 because the parser requires those fields; the script fills them
with the defaults observed in a real v15 export.
The target format is documented field by field in
docs/v15-export-schema.md — including the enum
wire values (which are not always the enum names), what the importer requires,
and the legacy v11.11 shape.
The v15 "new" import format has no customSubstances field; including it
makes the importer classify the file as legacy and reject it, so the script
drops those definitions and reports what it dropped. Ingestions that reference
them still import fine — you only lose the standalone definitions (their units
and descriptions), which can be re-added in-app. (Possible future improvement:
map them into v15's customUnits.)
samples/v15-minimal.json is a tiny hand-made v15 export (2 experiences) kept
as a schema reference and as a round-trip test fixture for clients.
| Script | Purpose |
|---|---|
extract.py |
Pull and canonicalize substances.json from an APK or IPA. |
update_vendor.py |
Archive a new release and merge it into working/. |
inject.py |
Copy working/substances.json into a client build tree. |
convert_v11_to_v15.py |
Convert a v11.x / PsyLog journal export to the v15 import format. |
The substance data originates from the PsychonautWiki Journal project. See that project for licensing of the underlying data.