I have a folder of Switch dumps I made myself, and for a long time that folder was the library. I wasn’t always sure which updates I had or which game a DLC file belonged to, and homebrew NROs were mixed in with everything else. Getting a title onto the console meant copying files around by hand, or relying on tools that wanted to be more of a shop than a file manager.
So I built NSLibrary. It’s a self-hosted library for content you already dumped from your own console and your own cartridges. Point it at your folders, open the web UI, and it groups base games, updates, DLC, and homebrew — then lets a paired Switch claim install jobs over the LAN (or USB).
NSLibrary has no download sources or shop scraping. Optional keys (prod.keys) come from your own console and stay on the server.
From folder to console
Run the server (Docker is the fastest path), open http://localhost:8465, create the admin account, and add a library folder. NSLibrary walks that folder read-only, watches for changes, and builds a catalog. The web UI shows the library, homebrew, problems (missing updates, duplicates, orphans), paired devices, folders, and settings.
On the Switch side, a small homebrew client (C++ / Borealis) browses the same catalog and installs NSP, NSZ, XCI, and XCZ straight to SD or NAND — streaming the file rather than copying the whole thing to the SD card first. You can connect over LAN HTTP or USB.
“Send to Switch” from the web UI doesn’t push. It queues a job. The console always initiates; it picks the job up with a long poll. Same device API over HTTP and USB, so the install engine doesn’t care which transport you used.
Why self-hosted
I wanted to manage the files I already had, on my own machine or NAS, without contacting an external service.
Library roots are read-only. The server never writes into them. Remove a file and it’s marked missing, then purged after 30 days. Identity is (root, rel_path, size, mtime) — a file is re-parsed only when one of those changes. You can force polling for NFS/SMB mounts where inotify is unreliable.
Docker image covers linux/amd64 and linux/arm64. There’s an Electron desktop build too (tray, native folder picker, USB), and signed releases for macOS, Windows, and Linux if you’d rather not compose anything.
Reading metadata
Container listings and tickets need no keys. Names, icons, firmware requirements, and NCA hashes need prod.keys dumped from a console you own. Without keys the library still lists files from containers, tickets, and filenames — it just labels that metadata as unverified.
Optional titledb (a URL or file you supply) fills in names, which game DLC belongs to, and latest-version numbers. It’s off by default; you bring your own source.
Key material is never returned by the API, never logged, and never sent to a device. The server reports which key names are present.
Finding the gaps
The catalog flags missing or superseded updates, duplicate (title id, version) pairs, and updates or DLC without a matching base game. It also shows which titles are missing from a paired console and which require newer firmware.
Verification can check just the headers or the full NCA hashes. NCZ decoding is streamed, so a large title doesn’t have to be materialised first.
How the Switch finds you
Discovery is UDP NSLIB?1 on port 8466, plus mDNS _nslibrary._tcp so the server shows up in Bonjour/Avahi browsers. You can always type an IP by hand. Pairing is a short-lived 6-digit code from the web UI; the device gets a bearer token that can read the catalog and its own jobs, and nothing else — no settings, no key upload, no library writes. Tokens are revocable.
Technically
It’s a pnpm monorepo. Shared Zod schemas in @nslib/shared. Pure format parsers in @nslib/formats (PFS0, HFS0/XCI, NCA, CNMT, NACP, ticket, NCZ, NRO, keyset) that read through a RandomAccessReader and never write. Fastify + SQLite (Drizzle, WAL) for the server. React + Vite + TanStack Query for the web UI. A CLI device simulator (nslib-sim) that talks to a running server the way a Switch would. Host-native C++ tests for the Switch client against the same golden fixtures as TypeScript.
HTTP and USB carry identical messages behind one DeviceApiService, so the install engine uses the same interface for both transports. The Switch initiates the requests in either case.
Demo data ships with synthetic containers and a fake keyset, so the UI is usable without real dumps. No copyrighted content in the repo.
Project scope
NSLibrary is not a shop. It will not help you obtain games, keys, or firmware, and requests to add that are out of scope permanently. It is a file manager and a transfer tool for dumps you already made.
It is also an independent, unofficial project — not affiliated with Nintendo. Dumping content you own is treated differently in different countries; downloading or sharing content you do not own is not something this project supports. Running modified system software can get a console banned from online services. What you do with it is your responsibility.
Try it
Source, docs, and releases are on github.com/tuckerwales/nslibrary. Latest release is v0.4.0.
Docker:
git clone --recursive https://github.com/tuckerwales/nslibrary.git
cd nslibrary
docker compose up --build
Open http://localhost:8465. The first run asks for a setup token, which the server prints to its log. Mount your dumps read-only, add the path under Folders, and pair a Switch when you’re ready.
I’d be interested to hear how it handles your library, especially any files it fails to identify.