# tropy/tropy: a desktop app for describing research photos so you can find the source later

> Tropy is an Electron and Node application for organising and describing research photographs, built as a single bundle with a SQLite database, a plugin system and a development loop that keeps its logs in a tmp directory you can view or tail. It is licensed AGPL-3.0-or-later, it requires Node 24 and npm 10, and it is currently shipping as a 1.18.0 beta series.

**tropy/tropy** — Research photo management

- Repository: https://github.com/tropy/tropy
- Website: https://tropy.org
- Stars: 1,156 · Forks: 68
- Language: JavaScript
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/tropy-tropy

## The problem is provenance, not storage

Tropy's own pitch is the clearest description of what it is for: bring order to your research, use the power of Tropy to organise and describe your research photos so you can find your sources whenever you need them.

That word, describe, is the important one. Tropy is not a photo viewer or a gallery. It is a tool for attaching structured information to an image, where that information is the point, and the image is the thing the information is about.

For a researcher, the situation is recognisable. You have a few thousand photographs, some of them scans, some of them photographs of objects, some of them screenshots of documents, and the thing that matters about each one is where it came from and what it shows, and a filename and a folder hierarchy is not enough to carry that. The topics in the repository reflect the model, with metadata, linked data, RDF and SQLite listed, which is a data model built around typed descriptions of objects rather than around images as pictures.

The project is a JavaScript and Electron application with a Node core, and the site is tropy.org, with the user's manual at docs.tropy.org and discussion on the forums. The README also points at a Mastodon account for important announcements, which is a sensible choice for a project whose users are mostly academics.

The licence is AGPL-3.0-or-later in the package metadata, which is a strong copyleft licence and a deliberate fit for a tool whose value is in being extended and shared.

## Install routes, and the Flatpak recommendation

The installation section is a list of options, and it is worth noticing which one the project recommends.

You can download the latest version from tropy.org or from the release page, and there are package manager routes through Homebrew, winget and the AUR. For Linux users the project recommends installing Tropy with the Flatpak, and there is a Flathub badge for the app under the id `org.tropy.Tropy`.

The Flatpak recommendation is a design position rather than a convenience. Tropy is an application that keeps a local database and an image library, it pulls in native image processing through libvips, and it writes into a user data directory. Distributing it as a sandboxed package means the native dependency and the data directory are handled consistently, and for a project with a small team and a wide range of Linux distributions that is the cheapest way to avoid a support queue about missing libraries.

There is a second path for people who want to build it themselves, and that is the source installation.

## Building from source, and the two flags that catch people out

The source installation needs the latest version of Node.js, at least the version that ships with the current Electron release, plus all the dependencies required to use node-gyp on your platform.

Then there are three commands, and the first two are unusual enough to be worth reading twice.

```
$ npm install --ignore-scripts
$ npm rebuild electron
$ node scripts/rebuild.js --force
```

The `--ignore-scripts` on the install is there because the install scripts would otherwise try to build the native modules before the toolchain is ready. The `npm rebuild electron` then builds the Electron binary, and the rebuild script with `--force` runs the project's own native rebuild over the dependencies.

On Linux there is one more flag, and the documentation explains why. Use the `--global-libvips` flag when rebuilding to link against the system's libvips, which is the difference between a build that links the system image library and one that builds its own copy of it.

To confirm that everything works, the instruction is to run `npm test`, and to create a development build for your current platform you run `npm run build`, which puts a dev build of Tropy in the `dist` folder.

## The development loop, and the log commands

The development section is a list of commands, and a few of them are the kind of convenience that only exists in a project with a long history.

```
# Compile the production bundle (optionally in --watch mode)
$ npm run rollup -- --watch

# Run bundle in dev mode
$ npm start

# View or tail the log file
$ npm run log:view
$ npm run log:tail

# Run all tests
$ npm test

# Run individual tests in main/renderer process
$ npx spark test/common/db.test.js
$ npx spark --renderer test/common/db.test.js

# Collect test code coverage
$ npm run coverage
```

The bundle is built with Rollup, and the development server runs Electron with a `--dev` flag and with its data, cache and logs directories pointed at `tmp`, so a development run never touches your real library.

The log commands are the interesting pair. `npm run log:view` and `npm run log:tail` both pipe the log file through a remap script and then into a log viewer, so the output you read in the terminal is a processed view rather than the raw file, and the `log:debug` variant passes a flag to the remapper.

The test runner is called spark and runs with `--no-sandbox`, which is a normal accommodation for running a browser in a container. You can run the whole suite with `npm test` or a single file, and the renderer variant is a separate invocation because the two processes do not share a module system.

Coverage is collected with c8, writing both a text and an lcov report over the `src` directory.

## Plugins are a separate contract

Tropy can be extended with plugins, and the documentation treats that as a first class extension point rather than an afterthought.

To find out more you consult the plugin specification, which lives in the repository at `res/plugins/README.md`, and you clone the sample plugin to get started, which is a separate repository, `tropy/tropy-plugin-example`.

The decision to keep the specification in the repository rather than only on the website is a good one for a project with plugin authors, since the spec is then versioned with the code it describes. And the existence of a separate example repository means the minimum viable plugin is something you can read end to end rather than something you infer from an API listing.

The repository tree reflects the whole structure. There is `src/` for the application code, `db/` for the database layer and its migrations, `res/` for resources including the plugin specification and the templates, `test/` for the test suite, `vendor/` for the vendored dependencies, and `scripts/` for the build, pack, devtools, legal, rebuild and log helper scripts, alongside a Rollup configuration, a Babel configuration, an ESLint configuration, a Stylelint configuration and a `.nvmrc` pinning the Node version.

## Packaging details worth reading before you build

A few entries in the package manifest describe how the project is put together, and they are unusual enough to be worth noting.

The package is ESM, with `type` set to `module`, and it uses an `imports` map so that internal modules can be addressed by a stable prefix. `#tropy/*.js` resolves to `./src/*.js` and `#vendor/*.js` to `./vendor/*.js`, which means source files can import each other by a name that does not change when the directory layout does, and the vendored code is reachable without a relative path that climbs out of the tree.

The engines are strict, Node 24 or newer and npm 10 or newer, and the entry point is `lib/main/index.js`, which is the Rollup output rather than the source, so a consumer of the built application never loads the unbundled tree.

The scripts show the release discipline. `preversion` runs the lint and the test suite before a version bump, and `prebuild` cleans and rebuilds the bundle. There is a separate `legal` script, which is what a project with a licence file and third party notices needs, and a `pack` script distinct from `build`.

There is also a `CITATION.cff` file in the repository, which is the format that lets a project be cited by DOI, and for a research tool that is a small thing with a large effect on how a paper credits the software.

## Where this is the wrong choice

The first wrong case is general photo management. Tropy's model is built around research sources and their descriptions, and the metadata, linked data and RDF machinery exists to support that. If you want a photo library to look at, this is the wrong shape of tool.

The second is a deployment where an Electron application does not belong, which for a research tool is rarely true but is worth stating, since the alternative is a web application with a server.

The third is a project that needs a stable release. The current version is `1.18.0-beta.6`, and the recent tags are a beta series, with 1.18.0-beta.4 from July 2026, beta.5 from August and beta.6 from September. A beta line means the plugin API and the data format can still move, and a plugin you write today may need attention in a month.

The fourth is a team that cannot accept AGPL-3.0-or-later. The copyleft is a reasonable choice for academic software that is meant to be shared and extended, and it is also a constraint on a product that wants to incorporate it.

On the state of the project, the last push was on 2026-10-15 with the repository not archived, and the release tags in the recent history are all beta builds. There is an AUTHORS file and a CITATION.cff, and the forum and the Mastodon account are the channels the project points at for announcements, which tells you the audience it expects.

## Conclusion

Adopt Tropy if you work with a large body of research photographs that need provenance, because a tool built around describing an image so you can find its source later is not something a general file manager or a photo app does for you. Do not adopt it as a general photo catalogue for a family or a business, because the whole model is built around research sources and their metadata. Verify first which build you are installing, since the current release line is a 1.18.0 beta series rather than a stable tag, that the Flatpak or package manager build suits your platform, and that you read the plugin specification before writing an extension, because the plugin API is a separate contract from the application itself.

## FAQ

### What is Tropy used for?

It is for organising and describing research photos so you can find your sources later. The model is built around structured metadata and linked data attached to images, with a SQLite store, rather than around viewing or organising pictures.

### How do I install Tropy?

Download the latest version from tropy.org or the release page, or use a package manager: Homebrew, winget or the AUR. For Linux users the project recommends the Flatpak from Flathub, with the app id `org.tropy.Tropy`.

### How do I build Tropy from source?

You need the latest Node.js, at least the version shipping with the current Electron release, and the node-gyp dependencies for your platform. Then run `npm install --ignore-scripts`, `npm rebuild electron` and `node scripts/rebuild.js --force`, adding `--global-libvips` on Linux to link against the system libvips, and confirm with `npm test`.

### How do I run the Tropy development environment?

Compile the bundle with `npm run rollup -- --watch` and run it with `npm start`, which starts Electron in dev mode with its data, cache and logs directories under `tmp`. The log commands `npm run log:view` and `npm run log:tail` pipe the log file through a remapper into a viewer, and `npm run build` produces a dev build in the `dist` folder.

### Can I extend Tropy with plugins?

Yes. The plugin specification lives in the repository at `res/plugins/README.md`, and there is a separate sample plugin repository, `tropy/tropy-plugin-example`, to clone and work from. The plugin API is a separate contract from the application, and the current 1.18.0 release line is a beta series, so an API you build against today can still move.

## Sources

- [Issues](https://github.com/tropy/tropy/issues)
- [Project website](https://tropy.org)
- [README](https://github.com/tropy/tropy/blob/main/README.md)
- [Releases](https://github.com/tropy/tropy/releases)
- [tropy/tropy on GitHub](https://github.com/tropy/tropy)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tropy-tropy
