Papra: a self-hosted archive for documents you would otherwise lose
The minimalistic document archiving platform.
At a glance
- What is it?
- Papra is an AGPL-3.0 TypeScript document archiving platform you run yourself, with email and folder ingestion, full-text search and an API. It is a filing cabinet, not a DMS, and the licence is the first thing to check before you deploy it.
- Who is it for?
- Adopt Papra if you want a personal or small-team document archive that you host yourself, and you are comfortable with a Docker container, a Postgres-style backend and an AGPL-3.0 licence. Do not adopt it if you need retention policies, legal hold, audit trails or workflow approvals, because none of those appear in the README.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Papra solves is retrieval, not storage
Most people do not have a storage problem. They have a retrieval problem. The warranty PDF for a phone bought two years ago exists somewhere, on a laptop, in a downloads folder, or attached to an email nobody will find again. Papra's pitch, stated plainly in its README, is that you can "easily store, forget, and retrieve your documents whenever you need them." The word that matters is forget. A system that only works when you remember to file things correctly is not an archive, it is a second inbox. Papra's answer is to make ingestion automatic and search the retrieval mechanism, so the filing step is optional rather than mandatory. The target user is an individual or a small group: the README describes organizations as a way to "manage documents with family, friends, or colleagues," which is a household or small-team scale, not a corporate records department. Anyone evaluating it against SharePoint or a document management system with retention schedules is looking at the wrong category.
Ingestion pipelines are the core mechanism
The feature list is really a list of ways documents enter the system. Email ingestion generates an address you forward mail to; folder ingestion watches a directory and imports what appears in it. Both exist so that a document can land in the archive without a human opening the web UI. Once inside, content extraction pulls text out of images and scanned documents, and that extracted text is what full-text search queries against. Tagging rules then apply tags automatically based on conditions you define, which is the piece that replaces manual filing: instead of deciding where a document belongs, you write a rule once and every matching document inherits the tag. Custom properties let an organization define extra fields beyond the built-in metadata. The architecture is split into a client and a server, with the backend built on HonoJS, Drizzle as the ORM, Better Auth for authentication, and CadenceMQ, a job queue the same author maintains, for background work. That queue is what makes ingestion asynchronous: an email arrives, a job is enqueued, extraction and tagging happen out of band. The README does not document queue failure handling, retry semantics or what happens to a document whose extraction job dies, and that is a gap worth probing before you rely on ingestion for anything you cannot re-upload.
Running it: one Docker command, then the parts the README does not show
The quick start is a single command: docker run -d --name papra -p 1221:1221 -e AUTH_SECRET=a-dummy-secret-for-testing-purposes-only ghcr.io/papra-hq/papra:latest. That is genuinely the whole documented path to a running instance, and the README is explicit that the dummy secret is only for kicking the tires. For a real deployment it points you at openssl rand -hex 48 to generate your own. The README then defers everything else to the self-hosting documentation at docs.papra.app/self-hosting/using-docker, which is where the configuration surface lives. That deferral matters for evaluation: the repository you are looking at tells you the container exists and the port is 1221, but not which database it expects, where uploaded files are written, how to configure SMTP for the email ingestion address, or how to set the watched folder path. Those are the keys you will actually spend an afternoon on, and they are not in the README. Treat the one-liner as a smoke test and the linked docs as the real installation guide. The demo at demo.papra.app is client-side local storage only, so it demonstrates the interface without exercising the server, the queue or extraction.
Where Papra is the wrong tool
Papra has no visible retention policy engine, no legal hold, no audit log and no approval workflow in the material provided. If your requirement is "prove who accessed this contract and when, and keep it for seven years regardless of deletion requests," Papra does not address that, and the README does not claim it does. The feature list also shows document requests, mobile, desktop, browser extension and AI features as coming soon or coming maybe one day, which means the current release is web-only for upload outside the ingestion paths. That is a real constraint for anyone who photographs receipts on a phone and expects them to sync. The demo being backend-free is a second signal: the project is comfortable shipping a client that runs standalone, but it also means you cannot evaluate server behaviour, extraction quality or queue reliability without deploying the container yourself. Finally, the AGPL-3.0 licence is a boundary, not a footnote. If you modify Papra and let users interact with it over a network, the licence's source-availability obligation applies to your modified version. For an internal household instance this is irrelevant. For a company that wants to fork Papra into a product, it is the deciding factor, and it is worth reading the LICENSE file rather than a summary. Nothing here is legal advice.
How it differs from Paperless-ngx and plain cloud storage
The obvious comparison is Paperless-ngx, the long-standing self-hosted document archive. Both ingest scanned documents, both extract text, both search it. The difference in approach is where the intelligence sits. Paperless-ngx is built around a document consumption pipeline with a strong emphasis on OCR and machine-classified correspondents and document types, and it has a heavier configuration surface as a result. Papra's README frames the project around minimalism and describes tagging rules as explicit user-defined conditions rather than inferred classification, with AI features listed only as a possibility. So Papra asks you to write the rule; Paperless-ngx tries to guess it. Which is better depends on whether you trust your own rules more than a classifier. The other comparison is a synced cloud folder. Dropbox or Drive gives you storage and a filename, and nothing else. Papra adds a database, extracted text, tags, custom properties and an API with webhooks and an SDK, which is what turns a pile of files into something queryable. The cost of that is a server to run, back up and upgrade. If your documents are few enough that you can remember their names, Papra is over-engineering.
Upgrade and maintenance cost
Papra ships on a versioned release cadence, with the app package at 26.6.2 in the supplied release list and a separate webhooks package at 0.3.4. The app and webhooks version numbers move independently, which tells you the API surface and the core application are released separately and that a webhook consumer may need to track its own package. The documented upgrade path is a container image tag, ghcr.io/papra-hq/papra:latest in the quick start, and pinning to a specific version instead of latest is the difference between a controlled upgrade and a surprise. The material does not describe database migration behaviour between versions, so before upgrading a populated instance you should confirm from the self-hosting docs whether migrations run automatically on container start and whether a downgrade is possible. Backups are your responsibility: the README says nothing about export formats, so verify that your documents and their metadata can be extracted from the database and storage volume without Papra running. That check is cheap now and expensive later. Development is funded through GitHub Sponsors and Buy me a coffee, which is worth knowing when you assess how the project is sustained.
The API surface is the reason to pick Papra over a folder
The README lists an API, an SDK and webhooks, and there is a dedicated @papra/webhooks package in the release list. That combination is what separates Papra from a well-organised directory tree. A webhook means an external system can react when a document is added, which makes Papra usable as a component: a script that files a contract, a bot that notifies a channel, a small internal tool that queries the archive. The CLI covers the same ground for manual or scripted management without touching the web UI. If you never intend to call the API or receive a webhook, you are paying the operational cost of a server and a database for a feature set you will use as a web form, and a synced folder plus a good search tool would serve you better. The API is also where the AGPL-3.0 question becomes concrete: building a separate application that talks to Papra over its API is not the same act as modifying Papra itself, and the distinction is worth understanding before you design around it.
Editorial conclusion
Adopt Papra if you want a personal or small-team document archive that you host yourself, and you are comfortable with a Docker container, a Postgres-style backend and an AGPL-3.0 licence. Do not adopt it if you need retention policies, legal hold, audit trails or workflow approvals, because none of those appear in the README. Before deploying, verify three things: that the ingestion paths you need (email forwarding, folder watching) exist in the current release and not only on the roadmap, that the storage backend can be pointed at the volume or bucket you already operate, and that your organisation can live with AGPL-3.0, since running a modified Papra as a network service triggers the source-availability obligation. Generate the AUTH_SECRET with openssl rand -hex 48 rather than reusing the dummy value from the quick-start command.
Community notes