Unterlumen v0.8.0 — Libraries, Publish to Channels, and a Leap Forward

Unterlumen v0.7.0 and v0.8.0 land today as the largest update since the initial release. The headline is an optional Digital Asset Management system — a local, searchable library built entirely from your own files — but there is a lot more besides. Here is what is new.

Libraries — optional DAM, fully local

Unterlumen has always worked without any database. That stays true. The new Libraries mode is entirely opt-in: you can use Unterlumen exactly as before and never touch it.

If you do want it, Libraries indexes a folder of your choosing into a local SQLite database — no CGo, no external process, no cloud. Each photo is identified by its SHA-256 content hash, which means metadata survives external renames without losing the record. From there you get:

Re-indexing progress streams live to the browser via Server-Sent Events so you always know where a scan stands. Missing photos are marked rather than deleted, so their metadata and thumbnails are preserved until you clean them up explicitly.

Publish to Channels

This one also lives inside Libraries mode. Once your photos are indexed, you can record where and when each photo was published — to Instagram, Mastodon, your own website, or any custom destination.

Publishing writes an XMP sidecar file (.xmp) alongside the original using a custom xmlns:ul namespace, so the record travels with the photo and is non-destructive. A cached copy is kept in the library database for fast search. Photos in a single publish action share a PostID, so carousel posts stay grouped.

Three built-in channel presets cover the most common targets — Instagram at 1080 px, Mastodon at 1920 px, and a website export at 2400 px — all fully editable. You can configure named sub-accounts per channel and pick one at publish time. A "Website" channel type goes further: each publish generates a self-contained HTML gallery alongside the exported photos, and a multi-album mode accumulates albums into a full static website you can rsync to any host.

Slideshow

The browse toolbar now has a Slideshow button. Select photos, pick a delay (1–60 s), a transition (Fade, Slide, Zoom, or Instant), and a layout (single image, Ken Burns, 2-up, or 4-up). You can optionally point it at a folder of audio tracks. A minimal HUD autohides after three seconds; Space pauses, arrow keys navigate, Escape closes. Works on selected files or the whole current folder if nothing is selected. Selecting folder entries in the grid adds all photos from those folders recursively.

Crop tool

Crop is now available directly in the fullscreen viewer. Open a photo, click Crop in the toolbar, draw a rectangle, and choose an aspect ratio — freehand, standard ratios, or cinema formats. Press Enter to apply. The crop saves in place and preserves all metadata, including Fujifilm film simulation data, via exiftool.

Desktop app install

Running ./unterlumen -desktop-install launches an interactive wizard that installs Unterlumen as a native app launcher — a .app bundle in ~/Applications on macOS, a .desktop entry on Linux, and a Start Menu shortcut on Windows. After that it appears in Spotlight, Launchpad, or the application grid just like any other app. A companion -desktop flag opens the app in a Chrome/Chromium window without the URL bar, and the server shuts down automatically when the window is closed.

Dependency check

Settings now includes a "Check dependencies" entry that lists the status of ffmpeg, exiftool, and sips (macOS). Missing or misconfigured tools are flagged with a plain-language explanation and platform-specific install instructions — no more guessing why geolocation editing is not working.

Performance and cache improvements

Several areas got meaningful speed work alongside the new features:

Get the update

Install or update as a desktop app:

./unterlumen -desktop-install

Or run with Docker — ffmpeg and exiftool included:

docker run -p 8080:8080 -v /path/to/photos:/photos ghcr.io/bjblazko/unterlumen:latest

All release assets are on the product page and the GitHub repository.

← Back to blog