Loom is a self hosted file manager for your own server or NAS. You point it at a folder of photos, videos, and documents you already have and it gives you a proper web app to browse, search, and stream them from anywhere, without ever touching or reorganizing the actual files on disk. I built it because I have a Samsung T7 drive full of a decade of family photos and every app I tried wanted to import everything into its own library and rename stuff. Loom just reads whatever folder structure you already have and works with that.
.
Under the hood it’s three Docker containers, a Next.js app for the UI and API, a separate worker that indexes the filesystem and makes thumbnails, and Postgres for metadata only, never file content. It has a full file browser with grid and list views, a photo and video viewer, drag and drop uploads, trash with recovery, multiple user accounts with per folder permissions, and an audit log. There’s also a public demo you can try without installing anything, it’s a completely fake version running with no backend at all, everything happens in your browser.
.
The hardest part by far was video playback. Browsers only play a handful of video formats natively, so anything else, HEVC from an iphone, old MOV and AVI files, needed converting on the fly. I didn’t want to transcode an entire two hour video before someone could watch even the first second of it, so I built a system that only converts the exact chunk of video someone is actually watching or seeking to, in six second pieces, and shares the work if two people ask for the same part at once. Getting that to not corrupt itself when someone seeks around took a lot of debugging.
.
The other really annoying stretch was making the demo version work. It’s a static build with literally no server, and the entire fake backend is done by intercepting fetch requests in the browser. I got it fully built and deployed and it looked fine, every page loaded, every request returned 200, and it was completely broken underneath, folders showed up empty and buttons did nothing. Turned out the code that fakes the backend was never actually running in the browser at all because of how Next.js bundles server components, and curl and normal build checks couldn’t catch it since everything technically responded fine. I only found it by scripting an actual headless browser to click through the site.
.
What I’m most proud of is probably the idle drive design. A lot of self hosted apps for photos and files constantly watch your disk or hash every file on every scan, and I really didn’t want that for a drive that spins down. Loom only reads file size and modified time to check for changes, and only actually opens a file’s content the first time something genuinely needs to, like making a thumbnail. A full rescan of a library that hasn’t changed barely touches the disk at all.
.
To test it, the easiest way is the live demo, no install needed, any username and password works and there’s a button that fills in the demo login for you. From there you can click into the sample folders (they go a few levels deep on purpose), open a photo or video, try renaming or trashing something and refresh the page to see it stuck around, and check out the settings pages for users, permissions, and the scanner. If you want to run the real thing, it’s a single script install with Docker, clone the repo and run the install script and it walks you through the rest.
- 13 devlogs
- 100h