A browser-based batch file renaming workspace with live preview, rule chains, presets, and local ZIP export.
Import files or folders, build rename operations, review every result, and export selected renamed copies.
Batch File Renamer is a client-side web application for renaming many files at once. Files are loaded into a workspace, rename operations are applied in sequence, and a preview table shows the result before anything is exported. The app creates a ZIP archive containing renamed copies of the selected files. Your original files remain untouched.
All processing happens in the browser. Files are not uploaded to a server.
- File and Folder Import: Import individual files, entire folders, and dropped subfolders when supported by the browser
- Live Rename Preview: See original names, new names, file size, status, and validation messages before exporting
- Selectable File Queue: Keep files in the workspace while choosing which files are included in validation and export
- Operation Pipeline: Combine multiple rename operations and apply them in a predictable top-to-bottom order
- Drag and Drop Reordering: Reorder files for numbering operations and reorder operations for precise processing
- Quick Presets: Apply common rename workflows such as numbering, date prefixes, cleanup, lowercase conversion, music formatting, and episode formatting
- Custom Presets: Save reusable operation chains with a name, description, and icon
- Undo and Redo: Revert operation changes with toolbar buttons or keyboard shortcuts
- Validation: Detect invalid filename characters, empty names, reserved Windows device names, trailing spaces or periods, long filenames, and duplicate selected output names
- Advanced Mode: Reveal power-user operations such as Regex and Remove Characters
- Local ZIP Export: Export selected renamed files as a ZIP archive using browser-side ZIP generation
- Responsive Interface: Works on desktop and mobile layouts with touch-friendly controls
- Open Source: MIT licensed and ready for review, contribution, and reuse
- Live Demo
- Getting Started
- How It Works
- Available Operations
- Built-in Presets
- User Guide
- Validation Rules
- Architecture Overview
- Technical Stack
- Project Structure
- Build and Deployment
- GitHub Actions
- Privacy and Browser Support
- Troubleshooting
- Contributing
- License
- Screenshots
Try Batch File Renamer directly in your browser:
https://berndhagen.github.io/Batch-File-Renamer
No installation or registration required.
- Visit the Live Demo
- Drag files or folders into the import area, or use Import Files / Import Folder
- Select a preset or add custom operations
- Review the preview table and file status badges
- Deselect any files you want to skip
- Click Export to create a ZIP archive with the selected renamed files
# Clone the repository
git clone https://github.com/BerndHagen/Batch-File-Renamer.git
# Navigate to project directory
cd Batch-File-Renamer
# Install dependencies
npm install
# Start development server
npm run devThe application will be available at:
http://localhost:5173/Batch-File-Renamer/
The /Batch-File-Renamer/ base path is intentional. It matches the GitHub Pages deployment path configured in vite.config.ts.
Batch File Renamer does not rename files directly on disk. Browsers do not allow arbitrary file system writes for security reasons, and this app intentionally avoids modifying source files.
Instead, the workflow is:
- The user imports files or folders into the browser workspace
- The app stores references to the original
Fileobjects in memory - Enabled operations are applied to each file name in order
- The preview table shows the computed output name and validation state
- The user exports selected valid files
- The app creates a ZIP archive where each file entry uses the computed new name
The source files on your computer remain unchanged.
Batch File Renamer provides 10 rename operations. Operations can be combined and reordered.
| Operation | Description | Example |
|---|---|---|
| Find & Replace | Replace matching text, with optional case sensitivity, regex mode, and replace-all behavior | photo to image |
| Add Prefix | Add text at the beginning of the filename, optionally with a counter | file.txt to 2026_file.txt |
| Add Suffix | Add text before the extension, optionally with a counter | report.docx to report_final.docx |
| Remove Characters | Remove first/last N characters, a range, specific characters, or a regex pattern | IMG_001.jpg to 001.jpg |
| Change Case | Convert to uppercase, lowercase, title case, sentence case, camelCase, snake_case, or kebab-case | My File to my_file |
| Numbering | Add sequential numbers with configurable start, step, padding, separator, and format | song.mp3 to 001_song.mp3 |
| Date/Time | Add the current date or file modification date as prefix, suffix, or replacement | photo.jpg to 2026-06-01_photo.jpg |
| Regex | Advanced pattern replacement using JavaScript regular expressions | Custom patterns |
| Trim & Clean | Trim whitespace, collapse duplicate spaces, remove configured special characters, and optionally replace spaces | file (1).txt to file_1.txt |
| Extension | Lowercase, uppercase, change, add, or remove file extensions | .JPG to .jpg |
Operations are applied to the filename stem first. Extension changes are handled separately by the Extension operation.
Quick presets cover common rename jobs:
| Preset | What It Does |
|---|---|
| Number Files | Adds sequential 3-digit numbers as a prefix |
| Date Prefix | Adds the current date in YYYY-MM-DD format |
| Clean Filenames | Removes configured special characters, replaces spaces, and converts names to lowercase |
| Music Files | Adds 2-digit track numbers with a - separator |
| Episode Format | Adds an S01E prefix with 2-digit episode numbers |
| Lowercase All | Converts filenames to lowercase |
| Replace Spaces | Replaces spaces with underscores |
Custom presets can be saved from the current operation chain and reused later.
- Drag and Drop: Drag files, folders, or nested folders into the import area
- Import Files: Open a file picker and select one or more files
- Import Folder: Open a folder picker and import a directory tree when supported by the browser
Duplicate source files are ignored based on path/name, size, and last modified timestamp.
Every file row has a checkbox. Selected files are included in:
- queued file counts
- validation checks
- duplicate output detection
- ZIP export
Deselected files stay visible in the workspace but are skipped. This is useful when you import a large folder and only want to export part of it.
- Click Add operation to add a new rename operation
- Configure the operation fields
- Use the enable toggle to temporarily skip an operation
- Drag the operation handle to change execution order
- Remove operations that are no longer needed
- Use Advanced Mode to show Regex and Remove Characters operations
Drag files by the handle to change their order. This matters for operations that use file position, especially Numbering and counters.
When the operation chain is useful for repeated work:
- Build the operation chain
- Click the save preset control in the Operations header
- Enter a preset name and optional description
- Choose an icon
- Save the preset
Custom presets are stored in browser local storage through Zustand persistence.
Operation changes are stored in history:
- Undo: Click Undo or press
Ctrl+Z - Redo: Click Redo, press
Ctrl+Y, or pressCtrl+Shift+Z
The history stack is limited to 50 operation states.
- Review the preview table
- Resolve any selected file issues
- Make sure at least one selected valid file has a changed name
- Click Export
- Save or download the generated ZIP archive
Export includes selected valid files. The files inside the ZIP use their preview names.
The app validates selected output names before export.
| Rule | Reason |
|---|---|
| Invalid characters are rejected | Windows does not allow characters such as `< > : " / \ |
| Empty names are rejected | A filename stem cannot be blank |
| Names ending in a space or period are rejected | Windows treats these names inconsistently |
| Reserved device names are rejected | Names such as CON, PRN, AUX, NUL, COM1, and LPT1 are reserved |
| Names over 255 characters are rejected | Common filesystem filename length limit |
| Duplicate selected output names are rejected | Prevents ZIP entries from colliding |
Deselected files are not included in duplicate checks or export blocking.
Batch File Renamer is a static React application. There is no backend service.
Browser
|-- React UI
| |-- workspace layout
| |-- import controls
| |-- preview table
| |-- presets and operations
|
|-- Zustand Store
| |-- files
| |-- operations
| |-- presets
| |-- undo/redo history
|
|-- Rename Processor
| |-- apply enabled operations
| |-- validate output names
| |-- detect selected duplicate names
|
`-- Export
|-- client-zip stream/blob generation
`-- browser save/download
main.tsxmounts the React app withHashRouterApp.tsxrenders the workspace routeDropZoneimports files and foldersstore/index.tsconverts imported files intoFileItemrecordsOperationsList,PresetList, andAddOperationButtonupdate the operation chainprocessFiles()recalculates preview names after relevant changesFileListdisplays previews, selection, status, and export controlsExportButtoncreates a ZIP archive from selected valid files
The global Zustand store contains:
| State | Purpose |
|---|---|
files |
Imported file records with original name, new name, selection, validation, and source File |
operations |
Current rename operation chain |
presets |
Built-in preset definitions |
customPresets |
User-saved presets persisted in local storage |
showAdvanced |
Toggles advanced operations in the operation menu |
history / historyIndex |
Undo and redo snapshots for operation changes |
Only custom presets and the advanced-mode preference are persisted. Imported files are not persisted.
The rename processor:
- Splits each filename into stem and extension
- Applies enabled operations to the stem in order
- Applies extension operations to the extension
- Recombines stem and extension
- Validates the final name
- Performs duplicate checks among selected valid files
All processing is synchronous and local.
File import supports two browser paths:
- Standard file input and drag/drop files
- Directory input and dropped folder entries through WebKit directory APIs where available
For dropped folders, the directory reader recursively walks nested entries and tags imported files with a relative path when possible. This helps avoid incorrectly treating same-named files from different folders as duplicate source files.
Export uses client-zip.
Supported export paths:
- File System Access API save picker when available
- Blob download fallback for browsers without the save picker
The generated archive name uses an ISO-style timestamp:
renamed-files-YYYY-MM-DDTHH-mm-ss.zip
| Technology | Purpose |
|---|---|
| React 18 | Component-based UI framework |
| TypeScript 5.6 | Type-safe application code |
| Vite 6 | Development server and production build |
| Tailwind CSS 3.4 | Utility classes alongside custom CSS |
| Zustand 5 | Global state, persistence, and undo/redo history |
| @dnd-kit | Accessible drag and drop sorting |
| client-zip | Browser-side ZIP generation |
| Lucide React | Icon library |
| React Router | Workspace, Help, and License routes |
| ESLint 9 | Static analysis |
Batch-File-Renamer/
|-- .github/
| `-- workflows/
| |-- deploy.yml # GitHub Pages deployment
| `-- update-release.yml # Release update automation
|-- img/ # README and release screenshots
|-- public/
| |-- favicon.svg
| |-- img_icon.png
| `-- img_logo.png
|-- src/
| |-- components/
| | |-- AddOperationButton.tsx # Operation menu
| | |-- DropZone.tsx # File and folder import
| | |-- ExportButton.tsx # ZIP export
| | |-- FileList.tsx # Preview table and file selection
| | |-- HelpPage.tsx # In-app documentation
| | |-- Layout.tsx # Header and footer
| | |-- LicensePage.tsx # MIT license page
| | |-- OperationsList.tsx # Operation cards and config forms
| | |-- PresetList.tsx # Built-in and custom presets
| | |-- SavePresetModal.tsx # Custom preset creation
| | `-- Tooltip.tsx # Portal tooltip
| |-- store/
| | `-- index.ts # Zustand state and rename processing
| |-- types/
| | `-- index.ts # Shared TypeScript types
| |-- App.tsx # Main workspace route
| |-- main.tsx # Router and React entry point
| `-- index.css # Global styles and UI system
|-- index.html # HTML entry point
|-- package.json # Scripts and dependencies
|-- tailwind.config.js # Tailwind theme extension
|-- tsconfig*.json # TypeScript configuration
`-- vite.config.ts # Vite config and GitHub Pages base path
# Start the development server
npm run dev
# Type-check and build for production
npm run build
# Run ESLint
npm run lint
# Preview the production build
npm run preview
# Build and deploy dist/ to GitHub Pages
npm run deploynpm run build runs:
tsc -b && vite buildBuild output is written to dist/.
The app is configured for GitHub Pages with:
base: '/Batch-File-Renamer/'Routing uses HashRouter, so direct refreshes work on static hosting.
The repository includes workflow files under .github/workflows/:
| Workflow | Purpose |
|---|---|
deploy.yml |
Builds and deploys the app to GitHub Pages |
update-release.yml |
Supports release update automation |
- Files are processed locally in the browser
- Files are not uploaded to a server
- Original files are not modified
- Exported ZIP files contain renamed copies
- Custom presets are stored in browser local storage
| Feature | Browser Support |
|---|---|
| File import | Supported by modern browsers |
| Folder picker | Best supported in Chromium-based browsers |
| Dropped folder recursion | Uses WebKit directory entry APIs where available |
| Save file picker | Uses File System Access API where available |
| ZIP fallback download | Used when save picker is unavailable |
Check that:
- Files are imported
- At least one file is selected
- At least one operation is configured
- At least one selected valid file has a changed name
- No selected file has a validation issue
Two or more selected files produce the same output name. Change the operation chain, reorder files if numbering is involved, or deselect files that should not be exported.
Folder import support depends on browser APIs. Chromium-based browsers provide the best support. If folder picking is not available, select files manually or drag supported folders into the import area.
This is expected. Browser apps cannot safely rename arbitrary local files in place. Batch File Renamer exports renamed copies inside a ZIP archive.
Contributions are welcome. Helpful areas include:
- Additional rename operations
- Better validation rules for more platforms
- Accessibility improvements
- Browser compatibility improvements
- Tests for rename processing
- Documentation and screenshot updates
- Follow the existing component and store structure
- Keep UI changes consistent with the current workspace layout
- Add concise comments only where logic is not obvious
- Run
npm run buildandnpm run lintbefore opening a pull request - Update README and in-app Help when behavior changes
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-change - Make your changes
- Run the build and lint checks
- Commit with a clear message
- Push your branch
- Open a pull request
Open an issue with:
- A clear description of the problem or request
- Steps to reproduce
- Expected behavior
- Actual behavior
- Browser and operating system
- Screenshots or sample filenames when useful
This project is licensed under the MIT License. See the LICENSE file for details.
You are free to use, modify, and distribute this software for personal and commercial purposes, provided the license notice is included where required by the MIT License.
The following screenshots demonstrate the core functionality of Batch File Renamer, including the file import interface, live rename preview, operation configuration, and duplicate detection.
| Batch File Renamer - Startup Interface | Batch File Renamer - File Preview |
|---|---|
![]() |
![]() |
| Batch File Renamer - Operations Panel | Batch File Renamer - Duplicate Detection |
![]() |
![]() |




