github LibrePhotos/librephotos 1.3.0
1.3.0 - October 2026

3 hours ago

This release makes one open model, OpenCLIP, do all tagging and semantic search, ports the speed work from the Rust and TypeScript backend experiments back to Django so search, the API and scans get a lot faster on less memory, adds a timeline filter to keep screenshots and documents out of the way, makes videos play in every browser, and fixes a set of reported security issues, including two code execution bugs. Every instance should upgrade, and multi-user instances should upgrade right away. Here is an overview of all the new features, improvements, and bug fixes since the last release.

After you upgrade:

  • Run strip_thumbnail_metadata once. Thumbnails created by 1.2.1 and older still carry the original photo's EXIF and XMP, including the GPS position, and public links serve those thumbnails. The command removes that metadata and keeps the pixels and the colour profile, so it is safe to run again: docker compose exec backend python manage.py strip_thumbnail_metadata (single container: docker exec librephotos python manage.py strip_thumbnail_metadata, Windows standalone: start /wait librephotos.exe manage strip_thumbnail_metadata). See After upgrading from 1.2.1 or older.
  • A Calculate Clip Embeddings job re-embeds and re-tags every photo with OpenCLIP once, in the background. Nothing is deleted first: semantic search covers the photos converted so far, and the Things albums fill up again as photos are re-tagged.
  • Kubernetes: the manifests in deploy/k8s are now pinned to 1.3.0 and PostgreSQL 16 (before, they pinned 2023w31 and PostgreSQL 13). Read the Kubernetes README before you apply them to an existing install.

Upstream:

🚀 LibrePhotos: One Open Model for Tags and Search

Tags, semantic search, and similar photos now all come from OpenCLIP ViT-B/32, trained by LAION on DataComp-XL and released under the MIT licence. It replaces CLIP ViT-B/32 for search and the separate tagging model, so a scan runs one vision model per photo: tagging a photo produces its search embedding in the same pass. The separate clip_embeddings service is gone, and so are the model choices in the site settings, because there is nothing left to choose. Captions (LFM2.5-VL) and faces (InsightFace) are unchanged. See Semantic search.

🚀 LibrePhotos: Faster Search, API, and Scans on Less Memory

The Rust and TypeScript backend experiments were much faster than Django, and most of the difference turned out to be queries, app-layer work, and ML memory rather than the language. Every optimization that applies to Django is now in LibrePhotos. On a 50,000 photo library, text search takes about half the time (1.19 s down to 0.56 s), album lists, the date list, user details, site settings, and thumbnails answer faster with fewer queries, and duplicate detection finishes in 27 seconds instead of running for hours. The idle API server uses about half the memory and starts in 3 seconds, heavy libraries load only when they are needed, and a scan with machine learning committed 2.25 GB instead of 10.7 GB in our test.

🚀 LibrePhotos: Timeline Filter and Category Correction

The timeline has a Filter button: show photos, videos, or both, hide screenshots, hide documents, or show only favorites, and Save as default to make that your timeline (#2130). Select all acts on exactly what the timeline shows. When the automatic detection gets a photo wrong, fix its category in the lightbox (a badge says whether it was detected or set by you, with Undo) or mark a whole selection as photo, screenshot, or document from the selection menu. The sidebar is tidier too: Memories now appear as a strip on top of the timeline, the organizing pages moved into the Photos menu, and background jobs show as a progress ring around your avatar.

🚀 LibrePhotos: Videos That Play in Every Browser

Each video is now probed once during the scan, and its codec, pixel format, and colour transfer are stored. The web app uses that to ask the browser whether it can play the file, and converts only the videos it cannot play (for example HEVC in Firefox), instead of leaving "Always transcode videos" as the only way to play them (#477, #714). HDR videos get an HDR badge on their tiles and correctly tonemapped thumbnails, and a Probe Videos job fills in videos scanned before this release. (Implemented by dotanm)

🚀 LibrePhotos: Security Fixes

This release fixes several reported vulnerabilities, so please upgrade. A person name containing a line break could inject options into ExifTool when face tags were written to files, which let a logged-in user run code on the server (GHSA-x465-w9j9-42rp). ExifTool tag names in a user's own date and burst detection rules could do the same in the exif service (GHSA-cgq8-jvp9-r3j7). On the unified image and the Windows standalone build, a crafted /media/ URL could read files outside the media folder (GHSA-cf3f-2fmg-mjj6). Thumbnails kept the original photo's GPS position and camera details, so public links leaked the location even with "Share location information" off (GHSA-j84j-mc98-7wq3). Nextcloud server addresses are now validated on the host the connection really uses, which closes a bypass of the check added in 1.2.0 (GHSA-xq77-cj4c-42qr). The advisory for the album and select_all owner scope fix that shipped in 1.2.0 is published too (GHSA-phvg-g65q-rhq3). Thanks to wk-cs, Seven11Eleven, and dotanm for the responsible disclosure.

  • ✨ Frontend: Lock a user album to protect which photos are in it: locked albums cannot gain or lose photos until you unlock them (#867) (Implemented by krisnaparahita)
  • ✨ LibrePhotos: User settings show where web uploads are stored, and an admin can set a user's upload folder (#2033) (Implemented by dchaudhari7177)
  • ✨ LibrePhotos: Star ratings set in the mobile app are saved on the server and written to the file
  • ✨ Frontend: The lightbox shows the photo's category as a badge on the file row
  • ✨ Frontend: React 19, Mantine 9, zod 4, Vite 8, and TypeScript 6, with strict types across the web app
  • ✨ LibrePhotos: Node.js 24 everywhere, and many Renovate dependency updates
  • ✨ Docs: The README shows real screenshots of the app
  • 🔨 LibrePhotos: Owners can open their own hidden and trashed photos in the lightbox again, and hidden and trashed photos are left out of user, public, place, and folder albums
  • 🔨 LibrePhotos: Deleting a user turns off their public album links, photo links, and public photos (also for users deleted earlier), and deleting a second user no longer fails
  • 🔨 LibrePhotos: Sidecar and other non-media files (RawTherapee .pp3, .aae, Takeout .json) no longer mark a scan as failed, users without a scan folder no longer stop the scan for everyone after them, and --scan-files assigns a file only to the user whose scan folder really contains it
  • 🔨 LibrePhotos: Scan follow-up jobs no longer overwrite photo edits made at the same time (Implemented by dotanm)
  • 🔨 LibrePhotos: Logout works from any page, even when the server refuses the request (Implemented by dotanm)
  • 🔨 Backend: Numeric photo keywords such as years are kept instead of breaking the keyword import (#2152) (Implemented by Boulea7)
  • 🔨 LibrePhotos: Video thumbnails survive a failed rebuild, MKV and WebM videos get a duration, and a person with only video faces no longer empties the People page
  • 🔨 LibrePhotos: Zip downloads stream to disk and work on the unified image, the Windows build, and native installs; uploads are no longer read into memory twice
  • 🔨 Frontend: Day headers show the photo's own date instead of the viewer's time zone, the info panel no longer saves a date edit to the previous photo, Nextcloud settings can be typed into again, renaming an album to an existing name no longer crashes, and grids refresh after favorite, hide, or trash
  • 🔨 Frontend: Photo grid preferences save for users with an avatar, and settings pages show server errors instead of swallowing them
  • 🔨 LibrePhotos: Event titles no longer read "Unknown - Other", and several pages that returned errors (missing albums, expired public links, rotating a photo with a duplicate) are fixed
  • 🔒 LibrePhotos: Person names are written to files on a single line, and ExifTool refuses any value with a line break
  • 🔒 Backend: ExifTool tag names in date and burst detection rules are validated when they are saved and again in the exif service
  • 🔒 LibrePhotos: Direct-mode media serving refuses paths with .. or backslashes and checks that every file stays inside the media folder
  • 🔒 LibrePhotos: Thumbnails keep only the colour profile, with no EXIF, GPS, or XMP, and strip_thumbnail_metadata cleans the existing ones
  • 🔒 LibrePhotos: Nextcloud addresses are checked on the host the connection actually uses
  • 🔒 Backend: The admin delete-user endpoint only deletes: it no longer lists user records or changes scan folders without validation

Full changelog: 1.2.1...1.3.0


If you are interested in how I develop this application, you can watch me develop features live on my channel


Sponsoring development:

My work is sponsored by 1 awesome person!

If you like the work I do, then you can support me via GitHub sponsors or via PayPal

Don't miss a new librephotos release

NewReleases is sending notifications on new releases.