Skip to Content
DocumentationDocumentationProvidersduti

duti Provider

Uses duti  to manage “which app opens which file type” on macOS. Want every .md to open in VS Code, every .ts in Cursor, every image in IINA? That’s what this provider is for.

Platforms: macOS only

Usage

# Make VS Code the default for TypeScript files hams duti set com.microsoft.VSCode public.typescript editor # See what's managed hams duti list # Undo (reverts to system default) hams duti unset com.microsoft.VSCode public.typescript editor

Three positional arguments: the app’s bundle ID, the UTI (file type), and the role (viewer / editor / shell / all).

Hamsfile example

# macOS/duti.hams.yaml schema_version: 1 provider: duti groups: - tag: code items: - urn: "urn:hams:duti:vscode-ts" step: Open TypeScript files with VS Code bundle_id: com.microsoft.VSCode uti: public.typescript role: editor - urn: "urn:hams:duti:vscode-md" step: Open Markdown with VS Code bundle_id: com.microsoft.VSCode uti: net.daringfireball.markdown role: editor - tag: media items: - urn: "urn:hams:duti:iina-video" step: Open video with IINA bundle_id: com.colliderli.iina uti: public.movie role: viewer

Common UTIs

File typeUTI
Markdownnet.daringfireball.markdown
TypeScriptpublic.typescript
JavaScriptcom.netscape.javascript-source
JSONpublic.json
Image (generic)public.image
Video (generic)public.movie
PDFcom.adobe.pdf
Plain textpublic.plain-text

Want to know the UTI for a specific extension? duti -x md will tell you.

Finding an app’s bundle ID

# VS Code, for example osascript -e 'id of app "Visual Studio Code"' # com.microsoft.VSCode # Or with mdls mdls -name kMDItemCFBundleIdentifier /Applications/Visual\ Studio\ Code.app

How state is probed

For each entry, hams runs duti -x <ext> or duti -d <uti> to see which app macOS currently associates with that type, and compares against the Hamsfile’s bundle_id.

Bootstrap

Fresh Mac without duti? hams can install it for you via Homebrew. Pass --bootstrap to apply and hams runs brew install duti under your consent:

hams apply --bootstrap --from-repo=you/hams-store

On an interactive terminal without the flag, hams shows the exact command and asks [y/N/s]. See hams apply → About the bootstrap prompt for details. brew itself is also consent-gated — the fresh-Mac chain brew → duti can resolve in one hams apply --bootstrap call.

Or declare duti under Homebrew in the usual way:

# Homebrew.hams.yaml - app: duti intro: Set default applications for file types.

duti writes to the Launch Services database. Sometimes new associations only take effect after restarting Finder or logging out and back in. If apply finishes but nothing seems to change, a quick logout/login usually sorts it.

Last updated on