Node.js bindings for macOS Spotlight's
mdutilcommand
The mdutil utility manages Spotlight indexing. Features include:
- Check indexing status
- Enable/disable indexing
- Erase and rebuild index
- List index contents
- Volume and directory support
- Root privilege handling
import { getIndexingStatus, setIndexing, eraseAndRebuildIndex } from 'mdfind-node'
// Check indexing status
const status = await getIndexingStatus('/Volumes/External')
// Enable indexing
await setIndexing('/Volumes/External', true)
// Rebuild index
await eraseAndRebuildIndex('/Volumes/External')The getIndexingStatus function returns detailed information:
interface IndexStatus {
state: 'enabled' | 'disabled' | 'unknown' | 'error'
enabled: boolean
status: string
scanBaseTime: Date | null
reasoning: string | null
volumePath: string
isSystemVolume: boolean
}const status = await getIndexingStatus('/Users')
console.log('State:', status.state)
console.log('Enabled:', status.enabled)
console.log('Last scan:', status.scanBaseTime)
console.log('System volume:', status.isSystemVolume)
if (status.reasoning) {
console.log('Reason:', status.reasoning)
}Check status of all volumes:
import { getAllVolumesStatus } from 'mdfind-node'
const volumes = await getAllVolumesStatus({
verbose: true,
excludeSystemVolumes: true,
excludeUnknownState: true
})
for (const volume of volumes) {
console.log(`${volume.volumePath}: ${volume.state}`)
}| Option | Type | Default | Description |
|---|---|---|---|
verbose |
boolean |
false |
Include additional details |
resolveRealPath |
boolean |
true |
Resolve symlinks to real paths |
excludeSystemVolumes |
boolean |
false |
Filter out system volumes |
excludeUnknownState |
boolean |
false |
Filter out unknown states |
The utility provides detailed error information through the MdutilError class:
import { getIndexingStatus, MdutilError } from 'mdfind-node'
try {
await getIndexingStatus('/System')
} catch (error) {
if (error instanceof MdutilError) {
console.error('Failed:', error.message)
console.error('Output:', error.stderr)
if (error.requiresRoot) {
console.error('Root privileges required')
}
}
}Many operations require root privileges:
try {
await setIndexing('/Volumes/External', true)
} catch (error) {
if (error instanceof MdutilError && error.requiresRoot) {
console.error('Please run with sudo')
}
}// Enable indexing for external drive
try {
await setIndexing('/Volumes/External', true)
console.log('Indexing enabled')
} catch (error) {
if (error instanceof MdutilError) {
if (error.requiresRoot) {
console.error('Root privileges required')
} else {
console.error('Failed:', error.message)
}
}
}// Erase and rebuild index
try {
await eraseAndRebuildIndex('/Volumes/External')
console.log('Index rebuild started')
} catch (error) {
if (error instanceof MdutilError) {
if (error.requiresRoot) {
console.error('Root privileges required')
} else {
console.error('Failed:', error.message)
}
}
}// Get status of all volumes
const volumes = await getAllVolumesStatus({
verbose: true,
excludeSystemVolumes: true
})
// Print status summary
for (const volume of volumes) {
const status = volume.enabled ? 'enabled' : 'disabled'
const time = volume.scanBaseTime ? volume.scanBaseTime.toLocaleString() : 'never'
console.log(`${volume.volumePath}:`)
console.log(` Status: ${status}`)
console.log(` Last scan: ${time}`)
if (volume.reasoning) {
console.log(` Reason: ${volume.reasoning}`)
}
console.log()
}The removeFromSpotlight function provides a convenient way to remove directories from Spotlight indexing:
import { removeFromSpotlight, type MdutilError } from 'mdfind-node'
// Remove a directory from Spotlight indexing
try {
await removeFromSpotlight('/path/to/directory')
console.log('Directory removed from Spotlight')
} catch (error) {
if (error instanceof Error && (error as MdutilError).requiresRoot) {
console.error('Root privileges required')
} else {
console.error('Failed:', (error as Error).message)
}
}The function performs several operations:
- Checks if the directory is indexed by Spotlight.
- If indexed, it removes the directory from Spotlight indexing.
- If the directory is not indexed, it does nothing.
- Most operations require root privileges
- System volume operations may be restricted
- Index rebuilding can take significant time
- Status checks are always allowed
- Some volumes may report unknown state
- mdfind Documentation - Search for files
- mdls Documentation - Get metadata for files
- macOS mdutil Manual
- Spotlight Architecture Overview