@aminzer/normalize-file-names
v1.3.2
Published
Utility for file name normalization
Maintainers
Readme
normalize-file-names
Overview
Node.js utility for file name normalizing based on embedded or inferred creation dates.
It helps bring order to media files originating from various devices or apps by renaming them into a unified, chronological format.
Why
Different devices and apps use inconsistent file naming conventions. For example:
Smartphone camera:
IMG_20250715_114509.jpgMessenger app (e.g., Viber):
viber_image_2025-07-15_11-45-09.jpgWhen you merge files from multiple sources into a single folder, chronological sorting can break - especially if the original creation / modification timestamps were lost during transfer.
This utility renames files into a consistent format that encodes the date and time:
2025_07_15__11_45_09_000.jpgThis way, sorting by file name = sorting by time.
Installation
npm install @aminzer/normalize-file-namesProgrammatic usage
import { normalizeFileNames } from '@aminzer/normalize-file-names';
await normalizeFileNames({
inputDirPath: '/path/to/input',
outputDirPath: '/path/to/output',
});normalizeFileNames parameters
inputDirPath(string, required) — Path to the input directory containing files to rename. Files in nested subdirectories are also processed. The original files are not modified — copies are created in the output directory.outputDirPath(string, required) — Path to the output directory where renamed files are written. All files with recognized names are copied directly into this directory's root (subdirectory structure is flattened).outputFileNameFormat(string, required) — Format of the output file names, using date-fns format.unrecognizedFilesOutputDirPath(string, optional, default:<outputDirPath>/_UNRECOGNIZED) — Path to the directory where files with unrecognized names are copied.recognizedFromFsFilesOutputDirPath(string, optional, default:<outputDirPath>/_RECOGNIZED_FROM_FS) — Path to the directory where files recognized via filesystem metadata are copied.isFileSystemMetadataFallbackEnabled(boolean, optional, default:false) — If enabled, files with unrecognized names will fall back to using filesystem metadata: the earlier of the file's creation (birthtime) and modification (mtime) timestamps.isDryRun(boolean, optional, default:false) — If enabled, files are not copied. Instead, the planned name changes are logged. Useful for testing recognition logic.logger(LoggerInterface, optional, default:NoopLogger) — Logger instance for progress and diagnostic output.
The package also exports LoggerInterface and StdoutLogger.
LoggerInterface defines the logging contract expected by normalizeFileNames:
log(message: string): void— logs a message on a new line.logSingleLine(message: string): void— logs a message by overwriting the current line (used for progress indicators).clearSingleLine(): void— clears the current single-line output.
StdoutLogger is a built-in implementation that writes progress and diagnostics to stdout:
import { normalizeFileNames, StdoutLogger } from '@aminzer/normalize-file-names';
await normalizeFileNames({
inputDirPath: '/path/to/input',
outputDirPath: '/path/to/output',
logger: new StdoutLogger(),
});You can provide your own implementation of LoggerInterface for custom logging behavior.
CLI usage
npm install --global @aminzer/normalize-file-namesnormalize-file-names --input <path> --output <path> [options]Flags
| Flag | Parameter |
| --- | --- |
| -i, --input <path> | inputDirPath |
| -o, --output <path> | outputDirPath |
| --output-file-name-format <fmt> | outputFileNameFormat |
| --fs-metadata-fallback | isFileSystemMetadataFallbackEnabled |
| --dry-run | isDryRun |
Example:
normalize-file-names \
--input ~/photos/raw \
--output ~/photos/normalized \
--fs-metadata-fallbackUsage from project root
git clone [email protected]:aminzer/normalize-file-names.git
cd normalize-file-names
npm installArguments are provided via environment variables or a .env file:
| Name | Parameter |
| --- | --- |
| INPUT_DIR_PATH | inputDirPath |
| OUTPUT_DIR_PATH | outputDirPath |
| OUTPUT_FILE_NAME_FORMAT | outputFileNameFormat |
| FS_METADATA_FALLBACK | isFileSystemMetadataFallbackEnabled |
| DRY_RUN | isDryRun |
Inline:
INPUT_DIR_PATH=~/photos/raw \
OUTPUT_DIR_PATH=~/photos/normalized \
FS_METADATA_FALLBACK=true \
npm start.env file in the project root:
INPUT_DIR_PATH=/path/to/input
OUTPUT_DIR_PATH=/path/to/output
FS_METADATA_FALLBACK=true
DRY_RUN=falsenpm startResult
Before:
viber_image_2025-07-15_11-45-09.jpg
IMG_20250716_231551.png
20250717.mp4After:
2025_07_15__11_45_09_000.jpg
2025_07_16__23_15_51_000.png
2025_07_17__00_00_00_000.mp4Now, simply sorting by name reflects the chronological order of your files.
