npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mangod33/syncgo

v1.0.0

Published

SyncGo is a single-process, single-port web app that syncs or transfers tracks from a **public** Spotify playlist into Navidrome (Subsonic API). The backend (Fastify) and frontend (React + Vite) run together on `localhost:3000` by default.

Readme

SyncGo

SyncGo is a single-process, single-port web app that syncs or transfers tracks from a public Spotify playlist into Navidrome (Subsonic API). The backend (Fastify) and frontend (React + Vite) run together on localhost:3000 by default.

Requirements

  • Node.js 18+
  • pnpm
  • Navidrome with Subsonic API enabled
  • Spotify API Client Credentials (public playlists only)

Setup

pnpm install
cp .env.example .env

Fill in .env with your Spotify app credentials (optional), Navidrome URL (optional), and database path.

SPOTIFY_CLIENT_ID=...
SPOTIFY_CLIENT_SECRET=...

If you do not set Spotify credentials in .env, SyncGo will start and prompt for them after Navidrome login. The credentials entered in the UI are used only for the current session and are not saved. If you set NAVIDROME_URL in .env, the login screen will auto-fill it (unless you already have a saved cookie), and you can also tap the link icon to apply the default.

Environment

  • PORT - server port (default 3000)
  • NODE_ENV - development or production
  • NAVIDROME_URL - optional; default Navidrome URL for the login screen
  • DATABASE_URL - SQLite file path (default ./data/syncgo.db)
  • SPOTIFY_CLIENT_ID / SPOTIFY_CLIENT_SECRET - optional; if omitted, the UI will ask per session

Development (single port)

pnpm dev

Fastify starts on http://localhost:3000 and serves the Vite frontend through middleware.

Production (single port)

pnpm build
NODE_ENV=production pnpm start

Vite builds the frontend to dist/client and Fastify serves both the API and static UI from the same port.

Hosting on a domain

SyncGo is a single-port app, so you can run it on an internal port and put a reverse proxy in front of it for TLS.

  1. Point your domain to the server (DNS A/AAAA record).
  2. Open ports 80/443 on the server firewall.
  3. Run SyncGo on an internal port (for example 3000) with NODE_ENV=production.
  4. Put a reverse proxy in front of it to terminate TLS and forward traffic.

NODE_ENV=production enables secure cookies, so be sure to serve SyncGo behind HTTPS in production.

Example: Caddy (recommended for automatic TLS)

yourdomain.com {
  reverse_proxy 127.0.0.1:3000
}

Example: Nginx

server {
  listen 80;
  server_name yourdomain.com;

  location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

Then enable TLS (for example with Certbot) and reload Nginx.

Service tips

  • Run SyncGo under a process manager (systemd, pm2) so it stays up.
  • Keep DATABASE_URL on persistent storage.
  • Protect the SQLite file; it stores active Navidrome session credentials.
  • If you deploy to a public server, always use HTTPS.

User flow (required order)

  1. Navidrome login (URL, username, password)
  2. Choose mode (sync or transfer)
  3. Validate Spotify playlist (URL or ID)
  4. Run job and review results / export failures

Features

  • Sync / transfer modes: Sync adds missing matches; transfer creates a new Navidrome playlist.
  • Dry run + apply: Dry runs do not create or modify playlists. You can apply changes after review.
  • Run history: Session-only run history and summaries (no extra storage).
  • Manual match: Open a failed track, search Navidrome, and add/remove a match manually.
  • Preview: Spotify embed preview for the selected Spotify track and Navidrome stream previews for search results (requires Subsonic streaming enabled).
  • Match tuning: Adjust fuzzy match threshold and exact duration tolerance per run.

Common troubleshooting

  • INVALID_NAVIDROME_CREDENTIALS: the username/password is wrong or Subsonic API is disabled.
  • NAVIDROME_UNREACHABLE: the URL is invalid, unreachable, or the server did not return JSON.
  • SPOTIFY_NOT_CONFIGURED: SPOTIFY_CLIENT_ID/SPOTIFY_CLIENT_SECRET missing.
  • SPOTIFY_PRIVATE_OR_UNAVAILABLE: playlist is not public or cannot be accessed with client credentials.

Notes

  • Sync mode never removes tracks; it only adds missing matches and can update the playlist public/private flag when toggled.
  • Transfer mode creates a new Navidrome playlist.
  • Matching order: ISRC → exact (title/artist + duration within tolerance; default 25s, adjustable 0–60s) → fuzzy (weighted title/artist; default threshold 82%).
  • Failed matches can be exported from the results panel as JSON or CSV.