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

reelsort

v0.3.1

Published

CLI to rename, organize, and manage your movie and TV library — Plex-compatible naming, hardlink support, and automated watch mode.

Downloads

2,174

Readme

ReelSort

A CLI to organize and manage your media library. Renames messy download filenames into clean, consistent formats, moves files into the right destination folders, tracks everything in a local SQLite database, and keeps your library inspectable with a single command.

Works on macOS, Windows, and Linux.

Installation

npm install -g reelsort

Prerequisites

  • Node.js >= 18
  • ffmpeg — optional, required only for reelsort probe

Quick Start

# Tell ReelSort where your downloads land and where your library lives
reelsort config add source ~/Downloads
reelsort config set dest movie /Volumes/Media/Movies
reelsort config set dest tv /Volumes/Media/TV

# Preview what would be imported without touching anything
reelsort --dry-run scan

# Import
reelsort scan

Global Options

--dry-run (-n) and --verbose (-v) are top-level flags that work with any command:

reelsort --dry-run scan        # preview an import without touching anything
reelsort --dry-run watch       # run the watcher in observe-only mode
reelsort --dry-run undo        # see what would be reversed
reelsort --verbose scan        # show skipped items alongside imported ones

Because these are root-level flags, they go before the subcommand name.


Commands

reelsort config

Manage configuration stored at ~/.config/reelsort/config.json.

reelsort config add source <dir>          # add a source directory
reelsort config remove source <dir>       # remove a source directory
reelsort config set dest movie <dir>      # set movie destination
reelsort config set dest tv <dir>         # set TV destination
reelsort config set dest ps3 <dir>        # set PS3 destination
reelsort config set language <code>       # subtitle language (default: eng)
reelsort config set tmdb-key <key>        # TMDb API key
reelsort config set format movie <fmt>    # movie naming format
reelsort config set format episode <fmt>  # episode naming format
reelsort config set format season <fmt>   # season folder format
reelsort config show                      # print current config

Multiple sources are supported — useful if your torrent client and browser downloads land in different folders:

reelsort config add source ~/Downloads
reelsort config add source /Volumes/External/uTorrent/Completed

reelsort add <name>

Register a TV show for scanning. Searches TMDb by name, shows an interactive picker when multiple results are found (with a clickable link to each candidate's TMDb page), and creates the show folder in your TV destination.

reelsort add Severance
reelsort add "The Bear"

TV episodes are only imported during reelsort scan if the show is registered. Use reelsort link to register shows that already exist on disk.


reelsort scan

Import media from all configured sources into their destinations. Parses raw download filenames, renames files, creates folder structure, and records every import in the database.

reelsort scan                  # move files to destinations
reelsort scan --hardlink       # hardlink instead of moving (great for seeders)
reelsort scan --type movie     # only process movies
reelsort scan --auto           # auto-register unrecognised TV shows instead of skipping
reelsort scan --interactive    # prompt when a duplicate is ambiguous
reelsort scan --force          # replace all duplicates without prompting
reelsort --dry-run scan        # preview without touching anything
reelsort --verbose scan        # show skipped items

TV episodes are skipped unless the show has been registered via reelsort add or reelsort link. --auto restores the old behaviour: unregistered shows are created on the fly without prompting.

Duplicate handling

When a file already exists at the destination, ReelSort compares quality automatically:

  • Clear upgrade (higher resolution, or better codec at the same resolution, e.g. x265 replacing x264) — the existing file is trashed and the new one takes its place, no prompt.
  • REPACK / PROPER tagged files — always auto-replace, same as a quality upgrade.
  • Ambiguous (same quality, or quality can't be determined from the filename) — skipped silently by default. Pass --interactive to get a prompt:
Duplicate: The Dark Knight (2008)
  A — keep existing  [1080p x264]
  B — keep incoming  [1080p x264]
  Skip

--force skips the comparison entirely and replaces every duplicate unconditionally.

TV output creates the full folder structure:

TV/
  Severance (2022)/
    Season 2/
      2x01.mkv

Season folders are matched by number if they already exist under any naming convention. New season folders are created using your configured format.


reelsort watch

Watch all configured sources continuously and auto-import new files as they arrive. Same logic as scan, triggered per item with a debounce to handle large downloads that arrive in chunks.

reelsort watch
reelsort watch --hardlink
reelsort watch --auto
reelsort --dry-run watch       # observe what would be imported without moving anything
reelsort --verbose watch       # show skipped items

--dry-run is especially useful before you commit to automated importing — run it for a while to build confidence that ReelSort is routing everything correctly, then restart without the flag when you're ready.

Press Ctrl+C to stop.


reelsort clean

Remove source files that were already imported via hardlink or copy. Safe to run while seeding — if a file is locked by your torrent client, it is skipped and left for the next run.

reelsort clean                       # remove imported source files
reelsort clean --older-than 14d      # only clean imports older than 14 days
reelsort --dry-run clean             # preview what would be removed

--older-than accepts d (days), h (hours), or m (minutes).


reelsort rename

Rename media files in-place inside a directory. Useful for cleaning up an existing library that wasn't imported through scan.

reelsort rename <dir>
reelsort rename <dir> --type movie
reelsort rename <dir> --type tv
reelsort rename <dir> --type ps3
reelsort --dry-run rename <dir>
reelsort --verbose rename <dir>

Renames folders and their primary video file to match your configured movie format. Keeps one subtitle file (matching your configured language) and removes everything else.


reelsort reset

Rename episode files inside a season folder to match your configured episode format. Useful for seasons that were copied in without going through scan.

reelsort reset <dir>            # e.g. "TV/Severance/Season 2"
reelsort reset <dir> --double   # episodes are double-length (1x01-1x02)
reelsort --dry-run reset <dir>  # preview renames without applying them

The season number is detected automatically from the folder name. The show title is read from the parent folder.


reelsort split

Split a flat directory of absolutely-ordered episodes into season folders, renaming files to your configured episode format along the way. Useful for anime and other shows that distribute episodes with a single running number rather than per-season numbering.

Provide the directory followed by the number of episodes in each season, in order:

reelsort split ./yuyuhakusho 12 10 12 20 24
# Season 1: 12 episodes, Season 2: 10, Season 3: 12, Season 4: 20, Season 5: 24

ReelSort validates that the total of all counts matches the number of video files in the directory before touching anything. If the numbers don't add up, it exits with an error and nothing is moved.

reelsort --dry-run split ./yuyuhakusho 12 10 12 20 24   # preview first
reelsort split ./yuyuhakusho 12 10 12 20 24              # then apply

Files are sorted alphabetically before splitting, so the sort order must match episode order. Season folders are created using your configured season format. No TMDb key required.


reelsort probe

Index your library using ffprobe to get accurate codec and resolution for every video file. Results are stored in SQLite and used by reelsort list. Run this once to populate your existing library, then re-run whenever you add files outside of scan.

reelsort probe                  # index all destinations
reelsort probe --type movie     # index only movies
reelsort probe --force          # re-probe files already indexed
reelsort --verbose probe        # show each file as it is probed

Requires ffmpeg to be installed. If ffprobe is not found, the command tells you rather than silently doing nothing.


reelsort list

Display your library in a table, sorted by year. Codec and resolution come from the probe index (populated by reelsort probe) if available, otherwise fall back to parsing the original download filename from import history.

reelsort list                       # list all configured destinations
reelsort list --type movie          # list only movies
reelsort list --missing-subs        # only show items without subtitles
reelsort list --codec x265          # filter by codec
reelsort list --resolution 1080p    # filter by resolution
reelsort list --sort title          # sort alphabetically (default: year)

Example output:

MOVIE  /Volumes/Media/Movies
──────────────────────────────────────────────────────────────────────
Title                     Year    Res     Codec   Size        Sub
──────────────────────────────────────────────────────────────────────
Dune Part Two             2024    2160p   x265    58.2 GB     ✓
Oppenheimer               2023    1080p   x264    22.1 GB     ✗
The Dark Knight           2008    —       —       14.8 GB     ✓
──────────────────────────────────────────────────────────────────────
3 of 3 items

reelsort link

Register TV shows that already exist on disk — useful when migrating an existing library or after manually organising files. Walks your TV destination, looks up each unregistered folder in TMDb, and prompts when multiple matches are found (with a clickable link to each candidate's TMDb page).

reelsort link           # register all unlinked shows
reelsort link --force   # re-link shows that are already registered

Shows with a single TMDb match are linked automatically. Shows not found in TMDb are skipped with a warning. Once registered, shows work with reelsort scan and reelsort missing.


reelsort ended

Mark a show as ended so it is excluded from reelsort missing. Run it again with --remove to restore a show to active.

reelsort ended           # pick a show to mark as ended
reelsort ended --remove  # pick an ended show to restore

An interactive picker lists your tracked shows. Ended shows are skipped in reelsort missing and a count is shown at the bottom of that output.


reelsort shows

List all registered TV shows with their TMDb link, size on disk, and ended status.

reelsort shows

Example output:

SHOWS  /Volumes/Media/TV  (3 registered)
────────────────────────────────────────────────────────
Title                          Size        Linked    Status
────────────────────────────────────────────────────────
Severance (2022)               28.4 GB     ✓ tmdb    active
The Bear (2022)                14.1 GB     ✓ tmdb    active
White Lotus (2021)             9.7 GB      ✗         ended
────────────────────────────────────────────────────────
3 shows  ·  2 linked  ·  1 ended

reelsort stats

Show library statistics — total counts and size per destination.

reelsort stats

reelsort missing

Check your TV library against TMDb and report any episodes that have aired but aren't on disk. Requires a TMDb API key. Shows must be linked (via reelsort scan or reelsort link) to appear.

reelsort missing                      # check all shows
reelsort missing --show Severance     # check a specific show

Example output:

Severance (2022)
  S01E04 — The You You Are
  S01E07 — Defiant Jazz

2 missing episodes total
2 ended shows skipped

Only episodes with a past air date are reported — future episodes are ignored. Ended shows are excluded entirely.


reelsort history

Show rename or import history grouped by session.

reelsort history                  # rename history
reelsort history --imports        # import history (what scan/watch moved)
reelsort history --limit 5        # show last 5 sessions (default: 10)
reelsort history --imports --limit 3

reelsort undo

Reverse the last reelsort rename session, or undo the last batch of imports from reelsort scan or reelsort watch.

reelsort undo
reelsort --dry-run undo   # see what would be reversed without doing it

ReelSort picks whichever session is more recent — rename or import — and undoes it:

  • Rename sessions — every file and folder rename is reversed in place.
  • Import sessions (movies, PS3, books) — the destination folder is moved back to its original source path.
  • Import sessions (TV) — the episode file (and any companion subtitle) is sent to the Trash. The original download folder is not restored since it was deleted during import.

Hardlink and copy imports are not reversed (the source file was never touched).


reelsort diff

Compare two directories and show what's in one but not the other.

reelsort diff <dir1> <dir2>
reelsort diff <dir1> <dir2> --only mkv
reelsort diff <dir1> <dir2> --ignore nfo jpg

Configuration Reference

Naming Formats

All formats use token substitution. Unrecognized tokens are left as literals.

Movie format

| Token | Description | |---|---| | {title} | Movie title (required) | | {year} | Release year | | {edition} | Plex edition tag, e.g. {edition-Director's Cut} |

reelsort config set format movie "{title} ({year})"           # default
reelsort config set format movie "{title} ({year}){edition}"  # Plex editions

Detected editions: Director's Cut, Final Cut, Extended, Theatrical, Unrated, Anniversary Edition, Collector's Edition, Special Edition.

Episode format

| Token | Description | |---|---| | {s} | Season number, no padding | | {ss} | Season number, 2-digit padded | | {sss} | Season number, 3-digit padded | | {e} {ee} {eee} | Episode number, same padding options | | {title} | Show title | | {name} | Episode title (from TMDb, requires API key) |

reelsort config set format episode "{s}x{ee}"             # 1x01 (default)
reelsort config set format episode "S{ss}E{ee}"           # S01E01
reelsort config set format episode "S{ss}E{ee} - {title}" # S01E01 - Severance

Season folder format

Uses the same {s} / {ss} / {sss} tokens.

reelsort config set format season "Season {s}"   # Season 1 (default)
reelsort config set format season "Season {ss}"  # Season 01
reelsort config set format season "S{ss}"        # S01

Subtitle Language

Set the preferred subtitle language code. When multiple subtitle files are present, the one matching this language is kept. Falls back to the first subtitle found.

reelsort config set language eng   # default
reelsort config set language fre
reelsort config set language spa

TMDb Integration

When a TMDb API key is configured, reelsort scan looks up each title before naming it. This corrects capitalization, fills in missing years, and resolves ambiguous names — the canonical TMDb title and year are used instead of whatever was in the download filename.

reelsort config set tmdb-key <your-key>

Movie lookup — automatically uses the top result.

TV show lookup — if only one show matches, it is used automatically. If multiple shows share the same name, an interactive picker is shown so you can choose the right one:

◆ Multiple shows found for "Severance":
  > 1. Severance (2022) — In a corporation, a group of employees have... <
    2. Severance (2006) — Six office workers on a corporate retreat...
    0. Skip

Arrow keys or number keys to select, Enter to confirm. Choosing 0 or Skip falls back to the parsed filename as-is. If TMDb is unreachable or returns no results, ReelSort falls back silently and continues.

Episode names — TMDb also supplies the episode title for each file. Use the {name} token in your episode format to include it:

reelsort config set format episode "S{ss}E{ee} - {name}"
# produces: S01E01 - Good News About Hell.mkv

The TMDb ID is stored alongside every import in the database, which powers the reelsort missing command.

Getting a free API key:

  1. Create a free account at themoviedb.org
  2. Go to Settings → API
  3. Request a developer key — no credit card or approval needed, it's instant

Keys are stored locally in ~/.config/reelsort/config.json and never leave your machine.


Workflows

Hardlink mode (recommended for seeders)

Hardlinks let your torrent client keep seeding the original file while your library gets the clean, organized copy — no extra disk space used. Only works within the same filesystem.

reelsort scan --hardlink    # or reelsort watch --hardlink
# ... seed until done ...
reelsort clean              # remove source files once seeding is finished

If source and destination are on different filesystems, --hardlink automatically falls back to copy with a warning. Copied files are also tracked and cleaned up by reelsort clean.

One-time library cleanup

If you already have a library that was organized manually:

# Preview first, then apply
reelsort --dry-run rename /Volumes/Media/Movies
reelsort rename /Volumes/Media/Movies

# Index metadata
reelsort probe

# Inspect
reelsort list

Fully automated

reelsort config add source ~/Downloads
reelsort config set dest movie /Volumes/Media/Movies
reelsort config set dest tv /Volumes/Media/TV
reelsort watch --hardlink

Database

ReelSort stores its database at ~/.config/reelsort/reelsort.db. It tracks:

  • renameHistory — every rename performed by reelsort rename, used by reelsort undo
  • imports — every file imported by reelsort scan or reelsort watch, used by reelsort undo and reelsort clean
  • shows — one row per TV show folder, storing the TMDb series ID and ended flag. Populated by reelsort scan and reelsort link, used by reelsort missing and reelsort ended
  • mediaInfo — codec, resolution, and duration indexed by reelsort probe, used by reelsort list

Platform Support

| Platform | Supported | |---|---| | macOS | ✓ | | Windows | ✓ | | Linux | ✓ |

File watching on macOS uses FSEvents, Windows uses ReadDirectoryChangesW, and Linux uses inotify — all via chokidar.