dutix (Default UTI eXtension handler manager) is a command-line tool for managing default application handlers for file types, UTIs (Uniform Type Identifiers), and URL schemes on macOS.
- 🎯 Set default applications for file extensions, UTIs, and URL schemes
- 🔄 Migrate all file associations from one app to another
- 📋 List and inspect installed applications and their capabilities
- 🔍 Query current default handlers for any file type or URL scheme
- 🛡️ Safe operations with preview, confirmation, and dry-run modes
- 📊 Multiple output formats (table, JSON, YAML)
- 🚀 Fast native macOS integration
- macOS 12.0 (Monterey) or later
- Go 1.25 or later (for building from source)
brew install jackchuka/tap/dutix# Go install
go install github.com/jackchuka/dutix/cmd/dutix@latest
# Clone and build
git clone https://github.com/jackchuka/dutix.git
cd dutix
go build -o dutix ./cmd/dutix/# Set VS Code as default for text files
dutix set "Visual Studio Code" --extensions txt,md,json
# Check what handles .txt files
dutix targets show txt
# Migrate all file associations from one app to another
dutix apps migrate TextEdit "Visual Studio Code"
# List all installed applications
dutix apps listAvailable on all commands:
| Flag | Short | Description |
|---|---|---|
--debug |
— | Enable debug logging |
--quiet |
-q |
Suppress non-essential output |
--output |
-o |
Output format: table, json, or yaml |
Set default application for file extensions, UTIs, or URL schemes.
Flags:
--extensions- Comma-separated file extensions (e.g.,txt,md,json)--utis- Comma-separated UTI identifiers (e.g.,public.plain-text)--schemes- Comma-separated URL schemes (e.g.,http,https)--dry-run- Preview changes without applying--yes- Skip confirmation prompt
Examples:
# Set default for file extensions
dutix set "Visual Studio Code" --extensions txt,md,json
# Set default for URL schemes
dutix set Safari --schemes http,https
# Preview changes first
dutix set TextEdit --extensions txt --dry-run
# Skip confirmation
dutix set Finder --extensions zip,tar --yesList all installed applications.
Flags:
--filter- Filter by name or path (case-insensitive)
Examples:
# List all applications
dutix apps list
# Find specific app
dutix apps list --filter "Visual"
# JSON output
dutix apps list --output jsonShow detailed information about an application including supported file types and UTIs.
Examples:
dutix apps show "Visual Studio Code"
dutix apps show Safari --output jsonMigrate all file type associations from one application to another.
Flags:
--dry-run- Preview migration without applying changes--yes- Skip confirmation prompt
Examples:
# Preview migration
dutix apps migrate TextEdit "Visual Studio Code" --dry-run
# Migrate with confirmation
dutix apps migrate TextEdit "Visual Studio Code"
# Auto-migrate without prompts
dutix apps migrate "Old App" "New App" --yesShow current default handler for a file extension, UTI, or URL scheme.
The command automatically detects the target type:
- Extensions:
txt,json,pdf - UTIs:
public.plain-text,public.json - Schemes:
http,https,mailto
Examples:
# Check file extension
dutix targets show txt
# Check UTI
dutix targets show public.plain-text
# Check URL scheme
dutix targets show httpList file extensions discovered across all installed applications, along with the UTI each extension resolves to and the current default application for that UTI.
An optional pattern filters extensions by case-insensitive substring.
Examples:
# List all discovered extensions
dutix targets list
# Filter by substring
dutix targets list txt
# Machine-readable output
dutix targets list --output json --quietDisplay version information including git commit and build date.
dutix version# Set VS Code as default for common development files
dutix set "Visual Studio Code" --extensions \
"txt,md,json,yaml,yml,toml,ini,conf,\
js,ts,jsx,tsx,mjs,\
py,rb,go,rs,java,c,cpp,h,hpp,\
html,css,scss,sass"
# Preview first with dry-run
dutix set "VS Code" --extensions txt,md --dry-run# Migrate everything from TextEdit to VS Code
dutix apps migrate TextEdit "Visual Studio Code"
# Preview the migration first
dutix apps migrate Safari Chrome --dry-run# Set Safari as default browser
dutix set Safari --schemes http,ftp,ftps
# Set Chrome
dutix set "Google Chrome" --schemes http# What opens .txt files?
dutix targets show txt
# What opens HTTP links?
dutix targets show http
# Get JSON output for scripting
dutix targets show txt --output json --quiet# See what file types an app supports
dutix apps show "Visual Studio Code"
# Find apps by name
dutix apps list --filter code
# Get machine-readable output
dutix apps show Safari --output jsonHuman-readable formatted tables:
dutix apps listMachine-parseable JSON output:
dutix apps list --output json
dutix targets show txt --output json | jq '.defaultApp'Structured YAML output:
dutix apps show "Visual Studio Code" --output yamldutix/
├── cmd/dutix/ # Application entry point
├── internal/
│ ├── cli/ # CLI commands and subcommands
│ ├── domain/ # Business logic (planner, applier)
│ ├── formatter/ # Output formatters (table, JSON, YAML)
│ ├── logger/ # Logging utilities
│ └── macos/ # macOS bridge layer
export CGO_ENABLED=1
# Build
go build -o dutix ./cmd/dutix/
# Test
go test ./...
# Lint
golangci-lint run ./...
# Generate mocks
go generate ./...dutix relies on macos-apphandlers-bridge to interface with macOS AppKit APIs for querying and setting default application handlers.
The tool uses a three-phase approach:
- Plan - Resolves targets and queries current defaults
- Preview - Shows what will change before applying
- Apply - Makes the changes to system defaults
- Some system-protected defaults (like http) may require user confirmation in System Settings
- Changes to certain defaults may not be reflected immediately in all applications
- Requires running as the logged-in user (not sandboxed)
- Some system-internal UTIs are automatically filtered out during migration
public.htmlUTI cannot be set programmatically and is automatically skipped- Extensions not declared by any installed application resolve to dynamic (
dyn.*) UTIs, which cannot be assigned a default handler and are automatically skipped
Contributions welcome! See docs/DEVELOPMENT.md for development guidelines.
Inspired by:
- duti - Command-line default handler manager
Built with:
- Cobra - CLI framework
- tablewriter - Table formatting
- macos-apphandlers-bridge - macOS integration

