Skip to main content
The loader keeps all of its configuration in a single settings.json file. This page lists every key the native loader reads or writes, what it defaults to when absent, and what changing it does.

File location

settings.json lives in the app’s documents directory, under an Unbound folder. On iOS you can reach it through the Files app at On My iPhone -> <App Name> -> Unbound, as described in the iOS page. If the file does not exist when the loader starts, it is created containing {}.

Structure

The root of the file is an object of stores. Each store is a namespace, and the loader reads exclusively from the store named unbound. Addons get their own store, keyed by their id, which is why an addon’s storage can never collide with the loader’s keys. See storage for the addon-facing side of the same file. Within a store, keys are dot-paths that map onto nested objects. loader.update.url is stored as:
settings.json
The unbound store is shared between the native loader and Unbound’s own JavaScript settings. Keys the loader does not recognise, such as staff-mode or toasts.*, belong to the client and are documented alongside the features that own them.

Keys

Every key below sits inside the unbound store.
boolean
default:"true"
Gates the entire loader. When this is false the loader logs Loader is disabled. Aborting. and hands the bundle load straight back to Discord, so no plugins, themes, fonts, updater, or hot reload run at all.This is the only key that is enabled by default. It is also the recovery lever: see disabling the loader.
boolean
default:"false"
Evaluates the bundled DevTools script into the JavaScript runtime before the main bundle, which is what makes React DevTools able to attach. Leave it off unless you are actively debugging.
object
Controls where the JavaScript bundle comes from and when it is refetched.
boolean
default:"false"
Recovery mode. When enabled the loader skips swizzling semantic colors, so themes stop being applied, and addons are started with an empty no-op instance instead of having their bundle evaluated. Addons still appear in the UI, so you can use a working app to disable whatever broke it. The toolbox toggles this key and reloads the app.
object
default:"{}"
Maps a font state name to the name of the font that should replace it. The native font layer resolves each override against both the custom fonts you have installed and the system fonts, and logs an error for any override whose font is not loaded, leaving that state untouched.This key is normally managed for you by Unbound’s font settings. See theme types and the addon manifest for how fonts are declared.
Three toggles are not in settings.json at all. The toolbox’s own switches are backed by NSUserDefaults, so editing settings.json will never change them:
  • UnboundShakeGestureEnabled (default on) opens the toolbox on a shake
  • UnboundThreeFingerGestureEnabled (default on) opens the toolbox on a three finger long press
  • UnboundAppIconEnabled swaps the app icon, and is only offered on non-App Store and non-TestFlight installs
The two gesture toggles are mutually protected: turning one off forces the other back on, so you can never lock yourself out of the toolbox.NSUserDefaults also holds UnboundDevOverlayButtonRelativeX and UnboundDevOverlayButtonRelativeY, which persist where you dragged the dev overlay button as a fraction of screen size.

External edits reload live

The loader watches settings.json for changes and reloads it in place, so you can edit the file from the Files app, over SSH, or with any other tool and the new values take effect without restarting the app. On each change the loader reparses the file and posts an internal change notification that the rest of the loader listens to.
Live reload updates the values the loader holds. It does not retroactively re-run work that already happened at startup, so keys read once during launch, such as loader.enabled and loader.devtools, still need an app restart to take effect.
Writes made from inside the app are debounced by 300ms before being flushed to disk, so a burst of changes results in one write.

Corrupt files are backed up, not fatal

If settings.json fails to parse, or parses into anything other than a JSON object, the loader does not crash the app. It copies the file to settings.json.corrupt-<timestamp> in the same directory, where <timestamp> is the Unix time in whole seconds, then resets settings.json to {} and carries on.
Your old configuration is still readable in that backup, so a bad hand edit costs you a restart at worst.

Disabling the loader

Setting loader.enabled to false is the cleanest way to turn Unbound off without uninstalling anything. Because the check happens before any plugin, theme, or bundle work, it takes the loader entirely out of the picture and gives you a stock app.
settings.json
Reach for this when a bad bundle or addon makes the app unusable and you cannot get far enough into the UI to fix it. If you only need addons out of the way, recovery is the lighter option. For a full list of the flags you can combine here, see configuration.