Open-source project
pulsejet/memories avatar
pulsejet/memories

Memories: a Nextcloud photo suite that indexes your library instead of moving it

Fast, modern and advanced photo management suite. Runs as a Nextcloud app.

3,839 stars168 forksPHPAGPL-3.0

At a glance

What is it?
Memories is an AGPL-3.0 Nextcloud app that adds a timeline, albums, maps and on-demand video transcoding on top of files you already store in Nextcloud. Its core bet is an index built by occ commands, and that bet is also what decides whether it fits your instance.
Who is it for?
Adopt Memories if you already run Nextcloud, want photos to stay inside your existing file tree, and can afford the indexing and transcoding work that the app offloads to occ commands and a separate Go binary. Do not adopt it if you want a photo tool that stands alone from Nextcloud, or if you cannot run server-side video transcoding on the host.
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 PHP, 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 Memories solves is that Nextcloud stores photos but does not present them

Nextcloud is a file sync and share server. It has no strong opinion about what a photo is. Files land in folders, and the only way to browse them is the file list, sorted by name or modification time. Memories adds the missing presentation layer: a timeline sorted by the date taken, parsed from Exif data, plus albums, an archive folder, a map view and external sharing of individual albums. The audience is people who already run a Nextcloud instance and want their photos to stay inside it. That constraint drives everything else in the design. Memories does not import your library into a separate database of its own or copy files into a managed store. It reads the files that Nextcloud already holds and builds an index over them. If you are not a Nextcloud user, the app has nothing to attach to, and the README treats Nextcloud as a precondition rather than an option.

How the index and the transcoder split the work

The repository is a monorepo with four shipped components. The lib directory holds the PHP backend and the database migrations. The src directory holds a Vue frontend shared across platforms. The go-vod directory holds an on-demand video transcoder written in Go, released on its own tag line (go-vod/0.2.9 and go-vod/0.2.8 in September 2026, separate from the v8.1.0 app release in July 2026). The android directory holds a Kotlin client. That split matters operationally. The PHP side answers queries against an index of metadata, so the timeline does not walk your storage on every page load. The Go side does the expensive part, transcoding video and serving it over HLS, and it is on-demand, meaning work happens when a viewer requests a video rather than during a bulk pass. The README lists AI tagging as a feature, but the grouping itself is delegated: it is powered by the recognize and facerecognition apps, which are separate Nextcloud apps you install yourself. Memories does not ship its own face or object model.

Installation is three steps plus a directory choice

The README gives a short path. Install the app from the Nextcloud app store. Perform the recommended configuration steps linked at memories.gallery/config/. Then run php occ memories:index to generate metadata indices for photos that already exist, and open the Memories app to set the directory containing your photos. That last step is worth pausing on. The app does not assume your whole Nextcloud is a photo library; you point it at a directory. The occ command is the part that scales with the size of your existing collection rather than with the size of the install. The README also claims performance testing on instances with over a million photos, which is a statement about the authors' testing, not a guarantee for your hardware or storage backend. For development, the repository offers a dev container and a manual route: clone the monorepo into the custom_apps folder of a Nextcloud install, install Composer and Node.js 18, run make dev-setup, then make watch-js to build or watch the UI, and enable the app through Nextcloud's app management. Formatting and static analysis run through make php-cs-fixer and make psalm.

The indexing step is the failure mode to plan for

Because the timeline depends on an index rather than on live directory reads, anything the index misses will be invisible or misordered. Photos whose Exif data has no usable capture date cannot be sorted by date taken, which is the timeline's stated sort key. Files added directly to storage outside Nextcloud's own upload paths may need the index command re-run before they appear. The README presents php occ memories:index as an installation step for existing photos, but it does not describe how the index is kept current afterwards, so treat re-indexing as an operational task you will need to understand from the configuration page rather than from the README. The video path has its own dependency: transcoding and HLS playback require the go-vod binary to be available and working on the host, and go-vod is versioned and released separately from the app. A Nextcloud instance on constrained or shared hosting, where running an extra Go process and ffmpeg-class work is not realistic, is the wrong environment for the video features. The map view has a third dependency: accurate reverse geocoding, which is a network service concern, not something the app can conjure from Exif coordinates alone.

Migration and sharing assume you are leaving something else behind

The README names two migration sources: Nextcloud Photos and Google Takeout. The first is the obvious one, since Nextcloud Photos is the built-in gallery that Memories effectively replaces. The second is more interesting, because Google Takeout exports carry sidecar JSON metadata rather than Exif in every case, and the README does not spell out how faithfully dates and albums survive the trip. Test that on a sample export before committing a full library. External sharing is listed as a feature in its own right: sharing photos and videos with people outside your Nextcloud instance. This is a meaningful difference from a plain file share link, because an album has an ordering and a presentation that a folder of files does not. Albums can also be shared with other users on the instance. Both behaviours are documented as features rather than described in mechanism detail, so the exact permission model is something to confirm against the configuration page if sharing outside the instance is central to your use.

Where Memories is the wrong tool, and what to use instead

If you want a photo manager that owns its library, with its own database, its own import step and its own storage layout, Memories is not that. It deliberately stays a view over Nextcloud's files, which means your library is only as organised as your Nextcloud folders and your Nextcloud install is a hard dependency for every feature. A standalone self-hosted gallery such as Immich takes the opposite approach: it manages its own asset store and database, so it can control upload, deduplication and thumbnailing end to end, at the cost of being a second system to run alongside your files rather than a layer on top of them. The practical difference is what happens when you stop using the tool. With Immich, your photos live in its storage layout. With Memories, they remain ordinary Nextcloud files, and removing the app leaves the library intact. Pick based on which of those two properties you actually want, not on feature lists, which overlap heavily.

Licence, maintenance and the cost of staying current

Memories is AGPL-3.0. If you modify it and let users interact with it over a network, the AGPL's network clause is the part to read, since it differs from permissive licences in exactly the situation a self-hosted deployment creates. That is a pointer to the licence text, not legal advice. On maintenance, the release tags tell you the shape of the work. The app ships as v* tags (v8.1.0 in July 2026), the transcoder ships as go-vod/* tags (0.2.9 and 0.2.8 in September 2026), and the Android client ships as android/* tags. Three independent version streams mean a go-vod update can land between app releases, so an upgrade plan that only watches the Nextcloud app store will miss transcoder changes. The monorepo layout also means contributing requires PHP, Node.js 18 and Go toolchains if you touch more than one package. Budget for the configuration page at memories.gallery/config/ as required reading, not optional tuning, because the README treats it as a step in the installation sequence rather than an appendix.

Editorial conclusion

Adopt Memories if you already run Nextcloud, want photos to stay inside your existing file tree, and can afford the indexing and transcoding work that the app offloads to occ commands and a separate Go binary. Do not adopt it if you want a photo tool that stands alone from Nextcloud, or if you cannot run server-side video transcoding on the host. Verify first that the Nextcloud instance meets the recommended configuration steps at memories.gallery/config/, that php occ memories:index completes on your existing library, and that reverse geocoding and the recognize and facerecognition apps are actually installed if you expect people and object grouping to appear.

Official sources

  1. License: AGPL-3.0
  2. Project website
  3. pulsejet/memories on GitHub
  4. README
  5. Releases
Community notes

Community notes