Tweak Formats
A tweak is a dynamic library the loader injects into matching processes. It
can be packaged either as a bundle or as a bare .dylib. Bundles
are preferred: they carry resources, and their filter lives inside them.
Bundles
Installed to /Library/TweakInject/Tweaks/Bundles/.
MyTweak.bundle/
└── Contents/
├── Info.plist
├── MacOS/
│ └── MyTweak <- the executable
└── Resources/
├── Filter.plist <- which processes to load into
├── Root.plist <- optional, a declarative settings pane
└── icon.svg <- optional
The loader takes the first file in Contents/MacOS as the
executable, so the bundle name and the binary name do not have to match. The
filter is read from Contents/Resources/Filter.plist, or from a
Filter dictionary in Info.plist.
Plain dynamic libraries
Installed to /Library/TweakInject/Tweaks/DynamicLibraries/, with
a .plist of the same name beside it holding the filter.
/Library/TweakInject/Tweaks/DynamicLibraries/ ├── MyTweak.dylib └── MyTweak.plist
Simpler, but there is nowhere to put resources and nowhere for a settings pane to live. Use a bundle unless you have a reason not to.
Disabled tweaks
Disabling moves a tweak rather than deleting it, to
/Library/TweakInject/DisabledTweaks/, keeping the same Bundles
and DynamicLibraries split. The loader does not look there, so a disabled
tweak is inert without being lost.
Architecture
A tweak only loads into a process whose architecture it was built for, and is
skipped quietly for any other rather than failing loudly. Building for both
arm64 and arm64e covers Apple silicon; add
x86_64 if you want to reach Rosetta 2 processes.