Node.js Touch Utility
The `touch` package for Node.js provides a cross-platform implementation of the Unix `touch(1)` command, enabling programmatic modification of file access and modification times, or the creation of new, empty files. Its current stable version is 3.1.1. The package offers both asynchronous (Promise-based and callback-based) and synchronous APIs, including `touch()`, `touch.sync()`, `touch.ftouch()`, and `touch.ftouchSync()`. A key differentiator is its dual API for file path and file descriptor manipulation, alongside a `nodetouch` CLI executable that mirrors the native `touch` utility. Release cadence is not explicitly stated, but the package maintains a stable API and provides consistent functionality across Node.js versions, focusing on reliable file system interaction.
Common errors
-
Error: EACCES: permission denied, open 'file.txt'
cause The Node.js process lacks the necessary write permissions for the specified file or directory.fixVerify and adjust file/directory permissions for the user running the Node.js application. On Unix-like systems, `chmod` or `chown` can be used. Consider running the process with appropriate user privileges. -
TypeError: Cannot read properties of undefined (reading 'sync')
cause The `touch` object was not correctly imported or initialized, often due to incorrect CommonJS `require` or ESM `import` syntax, or the module failed to load.fixEnsure you are importing the module correctly: `const touch = require('touch')` for CommonJS or `import touch from 'touch'` for ESM. Verify that `touch` is the default export and its methods are accessed correctly. -
Error: Invalid Date: 'SomeInvalidDateString'
cause The `time` option (or `atime`, `mtime`) was provided with a string that `Date.parse()` cannot interpret as a valid date.fixProvide a valid `Date` object, a string parseable by `Date.parse()` (e.g., ISO 8601 format), or an epoch millisecond number for time options.
Warnings
- gotcha When `atime` or `mtime` are specified, only the specified time is updated. If neither is set, both access and modification times are updated. This can be a source of confusion if only one time is intended for update but no specific option is passed.
- gotcha Mixing callbacks and Promises: The async functions return a Promise, but if a callback is provided, it's attached to the Promise. This can lead to dual handling or confusion if both patterns are used simultaneously.
- gotcha File permission errors: Operations might fail with `EACCES` or similar permission errors if Node.js does not have the necessary write permissions to the target directory or file.
Install
-
npm install touch -
yarn add touch -
pnpm add touch
Imports
- touch
import { touch } from 'touch'import touch from 'touch'
- touch (CommonJS)
const touch = require('touch') - touch.sync
import { sync } from 'touch'import touch from 'touch'; touch.sync('file.txt')
Quickstart
import touch from 'touch';
import { promises as fs } from 'fs';
const filename = 'my-file.txt';
const existingFilename = 'existing.txt';
async function runTouchExamples() {
console.log('--- Async Touch Example ---');
try {
// Create a new file or update timestamp if it exists
await touch(filename, { nocreate: false });
console.log(`Touched (or created) ${filename}`);
// Update only modification time of an existing file
await fs.writeFile(existingFilename, 'Some content.');
console.log(`Created ${existingFilename} for modification example.`);
const newModTime = new Date('2023-01-15T10:00:00Z');
await touch(existingFilename, { mtime: newModTime });
console.log(`Updated modification time of ${existingFilename} to ${newModTime.toISOString()}`);
} catch (error) {
console.error(`Async operation failed: ${error.message}`);
}
console.log('\n--- Sync Touch Example ---');
try {
const syncFilename = 'sync-file.txt';
touch.sync(syncFilename, { time: new Date() });
console.log(`Touched (or created) ${syncFilename} synchronously.`);
} catch (error) {
console.error(`Sync operation failed: ${error.message}`);
}
}
runTouchExamples().finally(async () => {
// Clean up created files
try {
await fs.unlink(filename).catch(() => {});
await fs.unlink(existingFilename).catch(() => {});
await fs.unlink('sync-file.txt').catch(() => {});
console.log('\nCleaned up example files.');
} catch (err) {
console.error(`Cleanup failed: ${err.message}`);
}
});