Skip to content

Repository files navigation

altero

Your Zotero library. Your server.

CI License: AGPL-3.0-or-later Python 3.14+ GitHub stars Documentation

altero is a self-hosted synchronization server for Zotero. Point an unmodified Zotero desktop application at it and keep your libraries, groups, notes, annotations, attachments and full text on infrastructure you control.

It speaks the same Zotero Web API that the desktop client uses and deliberately reproduces upstream behavior where compatibility matters.

📖 The documentation is at https://eseifert.github.io/altero/ — installation, connecting a client, deployment, administration and the compatibility reference.

  • Use the normal Zotero desktop app — no patched client or custom build
  • Self-host the whole sync service — not only attachment files
  • Run a small stack — one application, one database, one attachment store
  • Use SQLite or PostgreSQL — from a personal installation to a shared server
  • Get a web interface — libraries, groups, search, account settings, imports, exports and administration
  • Integrate institutional identity — OpenID Connect and SAML 2.0 for browser sign-in
  • Connect other applications — scoped, expiring OAuth 2.0 access instead of handing out an API key
  • Stay in control — altero is licensed under the GNU AGPL v3 or later

Warning

altero is under active development. Do not yet use it as the only home of a library you care about.

Test it with a separate Zotero profile or a library you can recreate. Synchronization writes client data to the server, and Zotero does not officially support third-party sync servers.

Why altero?

Zotero is excellent software, and zotero.org is the right sync service for most users. altero exists for people and institutions that need a different deployment model: one where the synchronization service itself runs on infrastructure they operate.

That is more than WebDAV offers. According to Zotero's synchronization documentation, WebDAV carries attachment files for a personal library; library data still goes through Zotero's service, and group libraries cannot use WebDAV at all. altero replaces the data and file synchronization endpoints themselves, for personal and group libraries alike, along with the accounts and authentication behind them.

Nothing else is required to run it: no cache, search cluster, queue or object store. Attachments live in a normal directory, so a backup is a database backup plus that directory.

See Why altero exists.

What works

Ordinary desktop synchronization in both directions: items, collections, tags, saved searches, notes, annotations, attachments and their files, full-text upload and search, group libraries, deleted objects, live updates through the streaming API, citations, bibliographies and Zotero's export formats. On top of that come a browser interface, OIDC and SAML sign-in, an OAuth 2.0 and OpenID Connect authorization server, passkeys and second factors, and importing a personal library from zotero.org.

The official iOS and Android applications are not supported. They compile the Zotero API host into the application and offer no runtime setting to replace it, so supporting them would require patched mobile clients. The desktop application has hidden preferences for both the API and the streaming server, so it needs no patching.

The implementation status documents the API surface feature by feature, including deliberate differences and remaining omissions.

Quick start with Docker

Docker Compose is the easiest way to try altero. It starts PostgreSQL, altero and persistent attachment storage. The image is published, so this needs no checkout and no build:

mkdir altero && cd altero
curl -fsSLO https://raw.githubusercontent.com/eseifert/altero/master/docker/compose.yaml

docker compose up -d
docker compose exec altero altero user add <username>
docker compose exec altero altero user password <username>

user add creates the account without a password, which is what user password then sets. The alternative is to open http://localhost:8000/app/ and register: the browser opens registration while an instance has no accounts, and the account that claims it administers the instance.

The server is published on the loopback interface by default. An idle instance uses around 125 MB of memory; attachments are what grows.

For anything beyond local testing, read Deployment before exposing it. In particular, put a TLS terminator or reverse proxy in front of altero and set a real PostgreSQL password.

To run without Docker you need Python 3.14 or newer and uv; SQLite is the default database. See Deployment.

Point Zotero at altero

In Zotero Desktop, open Settings → Advanced → Config Editor and set both preferences:

extensions.zotero.api.url = http://localhost:8000/
extensions.zotero.streaming.url = ws://localhost:8000/stream

The trailing slash on api.url matters.

Important

Set the streaming URL as well as the API URL. Zotero resolves the streaming service separately. Leaving it at the built-in default can send the altero API key to zotero.org, where it is not valid.

Restart Zotero, then open Settings → Sync → Link Account. Zotero opens altero in your browser; sign in and approve the client. The desktop application receives its API key and synchronization begins normally.

For the full walkthrough, including running two test clients at once, see Connecting a Zotero client.

More than a clone of zotero.org

Compatibility comes first, but running your own server also makes features possible that are difficult or unavailable in the hosted service:

Web interface

The browser application at /app/ covers registration and sign-in, account settings, API keys, connected applications, library browsing, search, item details and citations, groups, My Publications, shared links, imports and exports, and the administration screens. It is translated into twelve languages, held in fifteen catalogs, and takes item types, fields and creator types from Zotero's own schema translations so the two applications read as one vocabulary.

It is not intended to replace Zotero Desktop as a full reference manager: editing bibliographic fields remains the desktop client's job. See The web interface.

Compatibility over purity

altero reimplements a protocol spoken by software that already exists. That changes the engineering priority:

The right behavior is the behavior the Zotero client expects.

When the published API documentation, the reference data server and observed server behavior disagree, altero favors compatibility with the actual server behavior. Upstream quirks are copied deliberately when clients depend on them, and deliberate departures are documented in the compatibility reference.

Help test altero

The project especially needs testers. You do not need to write Python to make a useful contribution. A successful test on a configuration nobody has tried before is valuable evidence — a recent Zotero release, another operating system, two desktop installations sharing a library, group libraries with several accounts, PostgreSQL, a reverse proxy, your identity provider, or an installation on a platform nobody has documented yet. Reviewing the documentation as a first-time installer, and improving translations, help just as much.

If something works against zotero.org but not against altero, open an issue. Include your Zotero version, operating system, database, how altero is deployed, what you expected, what happened instead, and logs or a reproduction with no private library data or API keys in them.

For code, a development checkout is:

uv sync
uv run pre-commit install
cp config.example.py config.py
uv run alembic upgrade head
uv run pytest

The core architectural rule is that the web framework stays at the API boundary, so domain behavior remains testable without an HTTP request. Read CONTRIBUTING.md for the code layout, the testing approach and the compatibility rules before changing protocol behavior.

Documentation

The documentation is published at https://eseifert.github.io/altero/.

Section What it covers
Overview What altero is and why it exists
Get started Install locally, connect Zotero, first sync
Using altero Web interface, groups, sharing
Running altero Deployment, configuration, administration, applications, email
Reference Compatibility, implementation status, database schema
Contributing Development and testing

Relationship to Zotero

altero is an independent project. It is not an official Zotero server distribution and is not supported by the Zotero project.

It depends on the openness of the Zotero ecosystem: the published Web API, the open-source desktop client and the AGPL-licensed Zotero data server make it possible to study and reproduce the protocol.

This project does not argue that everybody should stop using zotero.org. Hosted Zotero synchronization is convenient and helps fund Zotero's development. altero provides another option for users and institutions that need to operate their own synchronization infrastructure.

License

altero is free software licensed under the GNU Affero General Public License v3 or later.

About

Self-hosted sync server for Zotero — keep libraries, groups, notes and attachments on your own infrastructure using the unmodified desktop client

Topics

Resources

Contributing

Stars

75 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages