Skip to main content

macmaint

PyPI version Python 3.13+ License: MIT

A macOS maintenance CLI that keeps your system clean and up-to-date with a single command. Run macmaint to update Homebrew packages, the Mac App Store, uv-managed tools, clear caches, trim log files, vacuum Mail.app, flush DNS, and show you which apps you haven't opened in months.

Everything is idempotent and safe to run as a daily cron job. Use --dry-run to preview every action before it executes.

Install

uv tool install macmaint

Or with pipx:

pipx install macmaint

Prerequisites

Requirement Notes
macOS 13 Ventura or later macOS-only by design
Python 3.13+ Installed automatically by uv/pipx
Homebrew Optional — needed for update and cleanup brew tasks
mas Optional — brew install mas for App Store updates
uv Optional — for uv tool upgrade --all in update
bun Optional — for bun update -g (global JS CLIs installed via bun) in update
npm Optional — for npm update -g (global JS CLIs like @openai/codex) in update and npm cache cleanup in cleanup
Docker Optional — cleanup prunes this if available

Quick start

# Check which tools are wired up on your machine
macmaint doctor

# Preview all maintenance tasks without executing anything
macmaint --dry-run

# Run everything
macmaint

Subcommands

Command What it does
macmaint update Homebrew update/upgrade/cleanup + Mac App Store upgrades + uv tool upgrade --all + bun update -g + npm update -g + npm audit on ~/package.json
macmaint cleanup Empty trash, clear user caches, purge pip/npm/uv caches, remove Xcode DerivedData, npm prune on ~/package.json, prune Docker, delete old logs
macmaint maintenance Flush DNS cache, vacuum Mail.app envelope index, repair user permissions, rebuild Spotlight index, free APFS purgeable space
macmaint apps Show all installed apps sorted by last used date (GUI apps, Homebrew formulae, Steam games)
macmaint doctor Check which optional tools are available and what macmaint can do

Common flags

# Preview mode — show what would run, no changes
macmaint --dry-run
macmaint cleanup --dry-run

# Skip specific tasks
macmaint update --no-brew          # skip Homebrew
macmaint update --no-mas           # skip App Store
macmaint update --no-uv-tools      # skip uv tool upgrade --all
macmaint update --no-bun           # skip bun update -g
macmaint update --no-npm-globals   # skip npm update -g
macmaint update --no-npm-audit     # skip npm audit on ~/package.json
macmaint update --no-extras        # skip user-defined extras
macmaint cleanup --no-caches       # skip user caches
macmaint cleanup --no-npm-prune    # skip npm prune on ~/package.json
macmaint cleanup --no-docker       # skip Docker prune

# App usage filtering
macmaint apps --days 90            # highlight apps unused for 90+ days
macmaint apps --unused             # show only unused apps
macmaint apps --size               # include disk footprint column

Configuration

Create ~/.config/macmaint/config.toml to override defaults. All keys are optional.

[cleanup]
# Which cache directories under ~/Library/Caches/ to clear.
# Defaults to a curated safe list (Safari, Chrome, VSCode, JetBrains IDEs, etc.)
cache-allowlist = [
    "com.apple.Safari",
    "com.google.Chrome",
    "com.apple.WebKit.WebContent",
    "pip",
    "com.spotify.client",
    "com.microsoft.VSCode",
    "com.jetbrains.intellij",
    "PyCharm",
    "CLion",
    "Rider",
    "WebStorm",
    "DataGrip",
]

# Remove log files older than this many days from ~/Library/Logs/
# Default: 7
log-retention-days = 7

[apps]
# Glob patterns for Steam library volumes to scan in addition to ~/Library.
# Default: ["/Volumes/*"]
steam-volumes = ["/Volumes/*"]

[[extras]]
# Run after built-in tasks for this phase: update | cleanup | maintenance
phase = "update"
name = "dcg"
cmd = "curl -fsSL 'https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh?$(date +%s)' | bash -s -- --easy-mode --quiet"

[[extras]]
phase = "maintenance"
name = "custom-health-check"
cmd = "~/bin/health-check"
when = "command_exists:health-check"

Extras hooks

[[extras]] lets you register your own commands for update, cleanup, or maintenance. macmaint runs them after the built-in tasks for that phase.

  • Use --dry-run to print the extra command without executing it.
  • Use --no-extras to skip all configured extras for that invocation.
  • A false when = "command_exists:foo" gate skips the extra cleanly.
  • If one extra fails, macmaint logs the error and continues with the remaining extras.

For the current dcg workaround, put the update extra above into ~/.config/macmaint/config.toml and run macmaint update. macmaint will keep handling brew/mas/uv/bun/npm first, then reinstall dcg via the upstream curl | bash flow.

Caveats

  • Mac App Store (mas upgrade) requires sudo. macmaint runs sudo mas upgrade; you will be prompted for your password. This is a mas limitation.

  • macmaint apps uses the Screen Time database (knowledgeC.db) for last-used dates. This database is protected by macOS privacy controls. For accurate results, grant Full Disk Access to the terminal app running macmaint (System Settings → Privacy & Security → Full Disk Access). Without access, macmaint falls back to Spotlight metadata, which is less accurate.

  • macmaint apps --size is slow for large app libraries. It runs du on each app bundle plus associated Library directories. Expect 30–120 seconds for 100+ apps.

  • macOS-only. macmaint uses macOS-specific tools (mdls, tmutil, dscacheutil, diskutil, sqlite3) and will not run on Linux or Windows.

  • npm audit and npm prune only run when ~/package.json exists. If you install JS CLIs into ~/node_modules via a top-level ~/package.json, macmaint update will surface high-severity advisories there and macmaint cleanup will remove orphaned installed packages no longer declared in the manifest. With no ~/package.json, both tasks are no-ops.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

macmaint-2026.7.0.tar.gz (56.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

macmaint-2026.7.0-py3-none-any.whl (19.7 kB view details)

Uploaded Python 3

File details

Details for the file macmaint-2026.7.0.tar.gz.

File metadata

  • Download URL: macmaint-2026.7.0.tar.gz
  • Upload date:
  • Size: 56.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for macmaint-2026.7.0.tar.gz
Algorithm Hash digest
SHA256 067145e1962739f5ec20103966e2e2acc4a6a1343a6990e44d3a59aa4b9bb0ce
MD5 451c76545118a62cf8df89418f5af8c4
BLAKE2b-256 691518c93756d0917c0087b2364fe9530b79f19f6e6d0d8581a38b3bf32e79b3

See more details on using hashes here.

File details

Details for the file macmaint-2026.7.0-py3-none-any.whl.

File metadata

  • Download URL: macmaint-2026.7.0-py3-none-any.whl
  • Upload date:
  • Size: 19.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for macmaint-2026.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e27e6a1eb949ab6ff7903537aab22fac6842c54bf286c5691e0fc9e5f0573d4f
MD5 8bbea288f1bc450e9bbd81c6ad05de65
BLAKE2b-256 524c3b0118a9e754d232cce13065d6c43f11aaf52ccc1e5316e1b99ec7d3b518

See more details on using hashes here.

Release history Release notifications | RSS feed

2026.7.1

2 files

This release

2026.7.0 This release

2 files

2026.4.10

2 files

2026.4.8

2 files

2026.4.7

2 files

2026.4.6

2 files

2026.4.5

2 files

2026.4.4

2 files

2026.4.3

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page