How to Move a File in Node.js?
To move a file using Node.js you can use the fs.rename
function:
// Using the fs Promises API
import fs from 'node:fs/promises';
const oldPath = '/path/to/file.txt';
const newPath = '/path/to/another/directory/file.js';
try {
// Top level await is available without a flag since Node.js v14.8
await fs.rename(oldPath, newPath);
// Handle success (fs.rename resolves with `undefined` on success)
console.log('File moved successfully');
} catch (error) {
// Handle the error
console.error(error);
}
Note: If the destination path already exists, it will be overwritten.
Handle non-existent destination directory
If the destination directory does not exist, you will get an error with the code ENOENT
(no such file or directory), so we have to take this case into consideration.
import fs from 'node:fs/promises';
import path from 'node:path';
const oldPath = '/path/to/file.js';
const newPath = '/path/to/another/directory/file.js';
// Create a helper function
async function moveFile(oldPath, newPath) {
// 1. Create the destination directory if it does not exist
// Set the `recursive` option to `true` to create all the subdirectories
await fs.mkdir(path.dirname(newPath), { recursive: true });
// 2. Rename the file (move it to the new directory)
// Return the promise
return fs.rename(oldPath, newPath);
}
try {
await moveFile(oldPath, newPath);
// Handle success
console.log('File moved successfully');
} catch (error) {
// Handle the error
console.error(error);
}
Handle moving files across different mount points
The rename
function does not work across different mount points, you will get the error code EXDEV
(cross-device link not permitted), for example when using Docker volumes you will hit this error.
As per the rename manual page :
EXDEV oldpath and newpath are not on the same mounted filesystem. (Linux permits a filesystem to be mounted at multiple points, but rename() does not work across different mount points, even if the same filesystem is mounted on both.)
To handle this case, you can fallback to copying the file to the new path and deleting the original file:
import fs from 'node:fs/promises';
import path from 'node:path';
const oldPath = '/path/to/file.js';
const newPath = '/path/to/another/directory/file.js';
// The final version of the move function
async function moveFile(oldPath, newPath) {
// 1. Create the destination directory
// Set the `recursive` option to `true` to create all the subdirectories
await fs.mkdir(path.dirname(newPath), { recursive: true });
try {
// 2. Rename the file (move it to the new directory)
await fs.rename(oldPath, newPath);
} catch (error) {
if (error.code === 'EXDEV') {
// 3. Copy the file as a fallback
await fs.copyFile(oldPath, newPath);
// Remove the old file
await fs.unlink(oldPath);
} else {
// Throw any other error
throw error;
}
}
}
try {
await moveFile(oldPath, newPath);
// Handle success
console.log('File moved successfully');
} catch (error) {
// Handle the error
console.error(error);
}