Self-hosted viewer for Tumblr blog backup exports. Point it at an archive folder and browse your posts locally in a classic Tumblr-style theme. No account required, no data sent anywhere.
- Paginated feed, full-text search, tag cloud, date archive, and post type filters (photo, audio, video, text)
- Permalink pages with Open Graph previews, editable tags (saved to cache; original backup unchanged), photo lightbox, and Random post (
/random) - Keyboard shortcuts:
/search,j/knavigate posts,?show hints - View on Tumblr links and reblog context when export metadata includes them
- Legacy, modern, and tumblr-utils export formats; optional WordPress WXR export (each Tumblr post → individual WordPress Post)
- Auto-extract
posts.zip, background indexing with progress, persistent cache; Docker-first, fully offline
| Format | Source | Layout signature | Status |
|---|---|---|---|
| Legacy HTML backup | Tumblr (early export) | posts/html/*.html + media/ |
Supported |
| Official Tumblr ZIP | Settings → Export | posts/posts.xml + media/ |
Supported |
| tumblr-utils | bbolli/tumblr-utils | index.html + posts/*.html |
Supported |
| Privacy data JSON | Account settings download | JSON account dump | Out of scope |
Directory layouts, extraction notes, and format-specific behavior are documented in Export formats.
Prerequisites: Docker and Docker Compose
- Export your blog — Follow Tumblr's export guide, download the ZIP, and extract it (including
posts.zip→posts/if present). - Mount the archive — Place the extracted folder at
.tumblrbackup/in this repo, or update the volume path indocker-compose.yml. - Run —
docker compose up --build - Open — http://localhost:8862
First launch indexes posts in the background (often 20–30 seconds for a few thousand posts; large archives may take a few minutes). Later starts load from cache in under a second. See Performance for tuning large exports (~5 GB+).
| Variable | Default | Description |
|---|---|---|
ARCHIVE_PATH |
/archive |
Path to the backup inside the container |
CACHE_DIR |
/app/cache |
Writable directory for the JSON index cache |
BLOG_TITLE |
MyBlog |
Default blog title (overridable in Settings) |
INDEX_WORKERS |
4 |
Parallel workers when building the index |
BACKGROUND_IMAGE |
(empty) | Optional default background: HTTPS URL or file path under the archive/app root |
TAG_EDITING_ENABLED |
true |
Allow editing tags on permalink pages (saved to CACHE_DIR) |
Optional WordPress WXR export is disabled by default (WORDPRESS_EXPORT_ENABLED=false). Each Tumblr post imports as an individual WordPress Post (not one Page). See WordPress export for structure, import walkthrough, media staging, and env vars — or docker-compose.yml for a commented example.
Local run (no Docker):
pip install -r requirements.txt
set ARCHIVE_PATH=.tumblrbackup # Windows
export ARCHIVE_PATH=.tumblrbackup # macOS/Linux
python -m flask --app app.main run --debugForce index rebuild — delete cache files and restart:
docker compose exec tumbl rm -f /app/cache/index-*.json /app/cache/index-*.meta.json
docker compose restart tumblCache filenames are format-specific (index-legacy_html.json, index-modern_xml.json, etc.).
Tests:
docker compose exec tumbl python -m unittest discover -s tests -vHTML sanitization, zip guards, path validation, and security headers are documented in Security.
- Messaging / conversations viewer (
messages.xml)
Issues and pull requests are welcome. For larger changes, open an issue first to discuss approach.
Export format research informed by TEV and tumblr-utils.
Disclaimer: tumbl is an independent project and is not affiliated with, endorsed by, or sponsored by Tumblr, Yahoo!, or Automattic. Tumblr and related marks are trademarks of their respective owners.
