Open-source project
pulsejet/memories avatar
pulsejet/memories

Memories for Nextcloud: a photo management suite that runs as an app

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

3,847 stars172 forksPHPAGPL-3.0

At a glance

What is it?
Memories is an AGPL-3.0 Nextcloud app that adds a timeline, albums, maps, AI tagging and HLS video transcoding on top of your existing files. It is aimed at self-hosters who already run Nextcloud and want their photo library to stay in it.
Who is it for?
Adopt Memories if you already run Nextcloud and want the photo experience to stay inside it, with your files living in Nextcloud storage rather than a separate library. Do not adopt it if you want a standalone gallery with no Nextcloud dependency, or if you cannot run the recommended configuration steps and the indexing command.
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 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Memories adds to a Nextcloud instance

Nextcloud stores files well and browses photos poorly. The default file view is a directory tree, and the Photos app that ships alongside it is a thin layer over that tree. Memories is a separate app that reads the same storage but presents it as a photo library: a timeline sorted by the date taken, parsed from Exif data, rather than by folder or upload time. That distinction matters when your originals are scattered across directories that were never organised for browsing.

The intended user is someone who already runs a Nextcloud instance and wants photos to live there permanently. The README describes the project as a "batteries-included" photo management solution for Nextcloud, and lists albums, external sharing, bulk metadata editing, an archive folder, a map view with reverse geocoding, migration paths from Nextcloud Photos and Google Takeout, and video transcoding. The performance claim in the README is that it has been tested on instances with over a million photos. That is a statement from the project, not an independent measurement, and it says nothing about the hardware involved.

Because it is an app rather than a server, it inherits Nextcloud's accounts, permissions and sharing model. You do not create a second user database, and you do not move files into a new directory structure. The app points at a directory you choose inside Nextcloud and treats what is there as the library.

The monorepo behind the app: PHP, Vue and a Go transcoder

The repository is organised as a monorepo with distinct packages, and the split tells you where the work happens. lib holds the backend and database migrations in PHP. src holds the frontend for all platforms in Vue. go-vod is an on-demand video transcoder written in Go. android is a Kotlin implementation of something the README calls NativeX. l10n holds translations managed through Transifex.

That Go transcoder is the part worth understanding before you install. Video playback in a browser is constrained by codec support, and phone footage is frequently in a codec the browser will not decode. go-vod transcodes on demand and serves HLS, which the README describes as being for maximal performance. On-demand means the server does work at playback time rather than pre-generating every variant, so the first play of an unconverted video costs CPU. Releases for that component are tagged separately, as go-vod/0.2.9 and go-vod/0.2.8, while the app itself uses v-prefixed tags such as v8.1.0. The README documents this convention explicitly: v* for overall releases, go-vod/* for transcoder releases, android/* for Android releases.

The frontend dependencies in package.json are almost entirely Nextcloud packages (@nextcloud/vue, @nextcloud/files, @nextcloud/upload, @nextcloud/dialogs and others) plus general-purpose libraries: leaflet and @vue-leaflet/vue-leaflet for the map, photoswipe for the lightbox, plyr for the video player, justified-layout for the grid, fuse.js for search, luxon for dates. Nothing here is exotic. The package version in the repository is 9.0.0-rc.1, which means the current development line is a release candidate, while the most recent overall release listed is v8.1.0.

Installing Memories and indexing an existing library

The README gives four steps, and the order matters. First, install the app from the Nextcloud app store. Second, perform the recommended configuration steps documented at memories.gallery/config. Third, run the indexing command below to generate metadata indices for photos that already exist on the instance. Fourth, open the Memories app in Nextcloud and set the directory containing your photos.

bash
php occ memories:index

Run that from the Nextcloud installation root, as the same user that owns the Nextcloud files. It is the step that makes an existing library usable: the timeline depends on Exif dates, and without the index the app has nothing to sort by. On a large library this is the long part, and the README does not document a rollback for a partial index, so plan to let it finish.

Setting the photo directory happens in the app's own settings after you open it. Point it at the directory inside Nextcloud that holds your originals, not at a folder of thumbnails or exports. If you are coming from Google Takeout, the README lists migration as a feature, and the practical sequence is to upload the Takeout archive into Nextcloud first, then set that directory, then index.

For automatic uploads from a phone, the README points at the official Nextcloud mobile apps rather than the Memories client. The Memories Android client is described as available in early access on Google Play, F-Droid and GitHub Releases. Read that as an early-access client, not a finished one.

If you want to build from source instead, the README documents a dev container and a manual path: clone the monorepo into the custom_apps folder, install Composer and Node.js 18, then run:

bash
make dev-setup
make watch-js

The first installs dependencies, the second builds and watches the UI. The app is then enabled through Nextcloud's app management. This path is for development, and the README treats it as such.

Where Memories is the wrong tool

The dependency on Nextcloud is total. There is no standalone mode, no separate server, no import path that leaves Nextcloud behind. If your reason for looking at photo tools is that you do not want to run Nextcloud, this project is not a candidate, and no amount of feature parity changes that.

Video is the second constraint. Transcoding is on demand, which means the server pays the cost when someone presses play. On a low-powered box, that first play of a large video will be slow, and the README does not offer a pre-transcode option or document a way to cap concurrent transcode jobs. The configuration page is where that would be addressed, and this article cannot confirm what it says.

Indexing is the third. The command is a one-shot pass over existing files, and the README does not describe incremental behaviour, scheduling, or what happens when a large import lands after the initial index. If you add photos continuously, you need to know how the app notices them. The README is silent on that.

Finally, the version situation deserves attention. The repository's package.json is at 9.0.0-rc.1 while the most recent overall release is v8.1.0. If you install from the app store, you get a released version, not the development line, and features described in the repository may not be in what you install.

How it compares with Nextcloud Photos and Immich

Nextcloud Photos is the closest comparison because it ships with the server. It reads the same files and needs no extra install, but it presents them largely as they are stored, with less emphasis on Exif-derived ordering, bulk metadata editing, and video transcoding. Memories is the heavier, more opinionated layer on the same data. Migrating between them is a supported path in the README, which is a reasonable signal that the project expects people to arrive from there.

Immich is the other obvious alternative and takes the opposite architectural position. It is a standalone photo server with its own database and its own mobile apps, not an app inside another platform. That means it does not require Nextcloud, and it also means your photos live in Immich's world rather than in your Nextcloud files. If your storage, sharing and backup already run through Nextcloud, adding Immich means running and backing up a second system. If you want a photo server and nothing else, Immich is the more direct answer.

The AI tagging in Memories is not self-contained either. The README states that grouping photos by people and objects is powered by recognize and facerecognition, two other Nextcloud apps. So the full feature set depends on installing and maintaining those separately, and their indexing runs are their own cost.

Licence, maintenance and what upgrades cost

Memories is licensed AGPL-3.0, and the package.json records the licence as "agpl". The AGPL's distinguishing feature is the network clause: if you modify the software and let users interact with it over a network, you are expected to offer them the corresponding source. Running an unmodified copy on your own instance does not trigger anything unusual, and this is not legal advice. If you plan to fork Memories and expose it to users outside your household, read the licence text in COPYING and talk to someone qualified.

The repository is not archived, and the last push was on 2026-09-10, which is recent. The release cadence visible in the repository is active: go-vod/0.2.9 and go-vod/0.2.8 both landed on 2026-09-08, and v8.1.0 on 2026-07-03. The project also carries unit test, e2e and static analysis workflows, and the Makefile exposes the corresponding targets.

Upgrade cost is not zero. The transcoder is versioned separately from the app, so a go-vod release can move independently of a v* release, and you should check both when you upgrade. The repository's Makefile shows the intended verification path for a source install: make lint runs php-lint, psalm and js-lint, and make php-test runs PHPUnit. For a store install, that is the maintainer's job, not yours. What is yours is the index: after a large import, php occ memories:index is the command that makes new files visible in the timeline, and the README does not describe an automatic alternative.

Editorial conclusion

Adopt Memories if you already run Nextcloud and want the photo experience to stay inside it, with your files living in Nextcloud storage rather than a separate library. Do not adopt it if you want a standalone gallery with no Nextcloud dependency, or if you cannot run the recommended configuration steps and the indexing command. Before committing, verify that the app version matches your Nextcloud release, that the directory you point it at is the one holding your originals, and that you are willing to run php occ memories:index after a bulk import.

Frequently asked questions

How do I install Memories for Nextcloud?

Install the app from the Nextcloud app store, perform the recommended configuration steps at memories.gallery/config, run php occ memories:index to index existing photos, then open the Memories app and set the directory containing your photos. The README lists these as four ordered steps.

Does Memories require the recognize and facerecognition apps?

Only for AI tagging. The README states that grouping photos by people and objects is powered by recognize and facerecognition, so those features depend on installing those apps separately. The timeline, albums, map and video transcoding do not.

What licence is Memories released under?

AGPL-3.0. The repository's package.json records the licence as "agpl", and the licence text is in the COPYING file at the repository root.

How is Memories versioned and released?

The README documents three tag families: v* for overall releases such as v1.0.0 or v1.0.0-beta.1, go-vod/* for transcoder releases, and android/* for Android releases. The most recent overall release listed is v8.1.0, while go-vod/0.2.9 and go-vod/0.2.8 were released on 2026-09-08.

Official sources

  1. License: AGPL-3.0
  2. Project website
  3. pulsejet/memories on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pulsejet-memories.svg)](https://hysenlabs.com/projects/pulsejet-memories)