What Is a PLIST? Apple's Property List Format
The Short Answer: A Structured Container for App Data
A PLIST file — short for Property List — is a structured data format Apple uses to store configuration settings, preferences, and serialized objects across macOS, iOS, iPadOS, watchOS, and tvOS. The format has been part of Apple's ecosystem since the NeXTSTEP days in the late 1980s, and it remains the backbone of how Apple apps remember your choices, how system daemons load their configurations, and how Xcode projects describe build targets. Every Mac user has hundreds of PLIST files on their machine without realizing it. Open Terminal and run `ls ~/Library/Preferences/` and you'll see files like `com.apple.finder.plist`, `com.apple.dock.plist`, and dozens more — one for almost every app you've ever opened. These files tell the Finder how wide your sidebar should be, tell the Dock where your icons live, and tell Safari which tabs were open when you last quit. The format supports a fixed set of data types: strings, integers, floating-point numbers, booleans, dates, binary data (Data), arrays, and dictionaries. That's it — no custom types, no inheritance, no schemas. This simplicity is deliberate. Apple wanted a format that could be read and written by the operating system itself with minimal overhead, and that could survive being edited by humans without corrupting application state.
XML vs. Binary vs. JSON: Three Flavors of the Same Format
PLIST files come in three distinct encodings, and mixing them up is a common source of confusion. **XML PLIST** is the human-readable form. Open any XML PLIST in a text editor and you'll see a DOCTYPE declaration pointing to `http://www.apple.com/DTDs/PropertyList-1.0.dtd`, followed by nested tags like `<dict>`, `<key>`, `<string>`, `<integer>`, and `<true/>`. This is the format Xcode uses for project files (`project.pbxproj` is technically a variant), and it's what you get when you export preferences for backup or inspection. The downside is verbosity — a simple dictionary of 20 keys can easily run to 150 lines. **Binary PLIST** (bplist) is what macOS actually writes to disk when an app calls `[NSUserDefaults synchronize]` or saves a preferences file. It starts with the magic bytes `bplist00` and is significantly more compact and faster to parse than XML. A 150-line XML PLIST might compress to 400 bytes in binary form. You cannot read binary PLISTs in a standard text editor — they'll appear as garbled characters. **JSON PLIST** is a newer addition, supported since macOS 10.7. It uses standard JSON syntax but is constrained to the same PLIST data types. Because JSON doesn't natively distinguish between integers and floats, or have a dedicated Date type, this encoding has subtle limitations. Apple's own tools rarely produce JSON PLISTs; you're more likely to encounter them when third-party build tools or CI pipelines generate configuration files. You can convert between all three formats using Apple's built-in `plutil` command-line tool. For example, `plutil -convert xml1 com.apple.dock.plist -o dock_readable.plist` produces a human-readable copy of your Dock preferences without modifying the original.
Where PLIST Files Live and What They Control
Understanding the directory structure Apple uses for PLIST files helps enormously when you're troubleshooting app behavior or migrating settings between machines. **User preferences** live in `~/Library/Preferences/`. These are per-user settings — your personal Dock layout, your Terminal color scheme, your Xcode key bindings. The filenames follow reverse-DNS naming: `com.apple.Terminal.plist`, `com.googlecode.iterm2.plist`, `org.mozilla.firefox.plist`. **System-wide preferences** live in `/Library/Preferences/`. These apply to all users on the machine and typically require administrator privileges to modify. Network configuration, time zone settings, and energy saver defaults often live here. **Launch Agents and Launch Daemons** — the macOS equivalent of scheduled tasks and background services — are defined entirely by PLIST files in `/Library/LaunchAgents/`, `/Library/LaunchDaemons/`, and their `~/Library/` counterparts. A LaunchDaemon PLIST specifies the executable path, the arguments to pass, whether to restart on crash, and the schedule if it runs periodically. The `launchctl` tool reads these files directly. **Application bundles** contain an `Info.plist` inside every `.app` package. This file declares the app's bundle identifier, minimum OS version, required device capabilities, URL schemes it handles, and the permissions it needs (camera, microphone, location). Right-click any app in Finder, choose Show Package Contents, and navigate to `Contents/Info.plist` to inspect it. On iOS, this file is what the App Store and the operating system read to decide whether your app can run on a given device. Modifying PLIST files in `~/Library/Preferences/` while an app is running is generally safe for reading but risky for writing — the app may overwrite your changes when it next saves its state. Always quit the app first, make your edits, then relaunch.
Reading and Editing PLIST Files: Your Practical Options
Apple provides several ways to read and modify PLIST files, ranging from graphical to fully scriptable. **Xcode's built-in PLIST editor** is the most polished option. Open any PLIST file in Xcode and you get a structured tree view with type-aware editing — checkboxes for booleans, date pickers for Date values, expandable arrays and dictionaries. You can add, delete, and reorder keys without touching raw XML. For developers working on iOS or macOS apps, this is the standard workflow for editing `Info.plist` and entitlement files. **The `plutil` command-line tool** ships with macOS and handles validation, conversion, and key-level editing. `plutil -lint myfile.plist` checks for syntax errors. `plutil -replace NSHighResolutionCapable -bool YES MyApp.app/Contents/Info.plist` sets a single key without opening a text editor. This is invaluable in shell scripts and CI/CD pipelines. **The `defaults` command** is specifically for user preferences. `defaults read com.apple.finder ShowPathbar` returns the current value; `defaults write com.apple.finder ShowPathbar -bool TRUE` enables the path bar in Finder. Many macOS power-user customizations are distributed as one-liner `defaults write` commands for exactly this reason. **Third-party editors** like PlistEdit Pro (around $12 on the Mac App Store as of 2025) add features Xcode lacks: side-by-side comparison, binary PLIST editing without conversion, and batch operations across multiple files. **Text editors** work fine for XML PLISTs but will corrupt binary PLISTs. If you open a binary PLIST in VS Code or BBEdit, convert it to XML first with `plutil -convert xml1` and convert it back with `plutil -convert binary1` after editing.
Converting PLIST Files: What CocoConvert Can and Can't Do
CocoConvert handles the most common PLIST conversion scenarios web users actually encounter: converting XML PLIST files to JSON, converting JSON to XML PLIST, and converting binary PLIST files to XML so they can be read without developer tools installed. For XML-to-JSON conversion, CocoConvert maps PLIST types to their JSON equivalents as faithfully as possible. Strings, integers, arrays, and dictionaries convert cleanly. Booleans become JSON `true` and `false`. Dates are serialized as ISO 8601 strings (e.g., `2024-11-03T14:22:00Z`). Binary data (`<data>` elements) are base64-encoded in the output, which preserves the content but means the resulting JSON is not directly human-readable for those fields. For binary-to-XML conversion, CocoConvert parses the bplist format and produces a readable XML PLIST. This is useful if you've exported a preferences backup from an iPhone via a third-party tool and want to inspect its contents without installing Xcode. Here's where honesty matters: CocoConvert cannot convert PLIST files back to binary format. Binary PLIST generation requires precise byte-level offset tables that are trivial to produce on macOS with Apple's libraries but complex to implement correctly in a web service. If you need to write a modified binary PLIST back to disk — for example, to restore edited iPhone preferences — you'll need `plutil` on a Mac or a native tool like PlistEdit Pro. Attempting to drop an XML PLIST where the system expects a binary one will often work (macOS can read both), but some apps explicitly check for the binary format and will reject or ignore XML versions. CocoConvert also doesn't validate PLIST semantics — it checks structure, not meaning. A PLIST with a malformed bundle identifier or an incorrect minimum OS version will convert without errors, because those are application-level concerns, not format-level ones.
Common PLIST Problems and How to Diagnose Them
PLIST corruption is rare but real, and it's one of the more frustrating macOS troubleshooting scenarios because the symptoms — an app that won't launch, preferences that reset on every reboot, a system service that silently fails — rarely point directly to the cause. **Corruption from improper writes** is the most common cause. If macOS crashes or loses power while an app is writing its preferences, the PLIST on disk can end up truncated or partially written. Run `plutil -lint ~/Library/Preferences/com.example.app.plist` to check. A healthy file returns `OK`; a corrupted one returns a parse error with a line number or byte offset. **Permission problems** are the second most common issue. A PLIST owned by root in a user's `~/Library/Preferences/` folder will cause the app to silently fall back to defaults on every launch. Check with `ls -l ~/Library/Preferences/com.example.app.plist` — the owner should be your username, not `root` or `_unknown`. Fix with `sudo chown $(whoami) ~/Library/Preferences/com.example.app.plist`. **Cached preferences** are a subtler problem. macOS caches preference values in `cfprefsd`, a background daemon. Even if you edit a PLIST on disk, the app may keep reading the cached version. Force a cache flush with `killall cfprefsd` — the daemon restarts automatically. This is why `defaults write` changes sometimes don't take effect until you run this command or log out and back in. **Xcode build failures** often trace back to a malformed `Info.plist`. The error message usually says something like "The data couldn't be read because it isn't in the correct format," which is Xcode's way of saying the file failed to parse. Run `plutil -lint` on the file, or check whether a merge conflict left stray `<<<<<<<` markers in the XML. For any PLIST you didn't create yourself — one exported from a device backup, downloaded from a repository, or received from a colleague — running `plutil -lint` before doing anything else takes three seconds and saves a lot of confusion.
PLIST in the Broader Apple Development Workflow
Beyond storing preferences, PLIST files are load-bearing infrastructure in Apple's development toolchain in ways that aren't obvious until something breaks. Every iOS and macOS app's code signing relies on an entitlements PLIST — a file that declares exactly which capabilities the app is permitted to use: iCloud, push notifications, App Groups, Keychain sharing, and so on. This file is embedded in the app's code signature at build time. If the entitlements PLIST doesn't match the provisioning profile, the app won't install on a device. Apple's `codesign` tool reads and validates this file directly. Xcode's build system uses PLIST files extensively for xcconfig alternatives and scheme configurations. The `*.xcscheme` files inside `.xcodeproj/xcshareddata/xcschemes/` are PLISTs describing which targets to build, what arguments to pass at launch, and which environment variables to set. These are safe to commit to version control and diff between branches. App Store submission metadata — the privacy manifest introduced in Xcode 15, required for most apps submitted after May 2024 — is a PLIST file called `PrivacyInfo.xcprivacy`. It declares which APIs your app uses that could be used to fingerprint users, and why. Getting this file wrong causes App Store review rejection, not a build error, which makes it particularly annoying to debug. For anyone building cross-platform tools that need to read Apple configuration files — CI systems, MDM solutions, backup utilities — understanding the PLIST format at the byte level is unavoidable. The format specification is documented in Apple's `CFPropertyList` reference, and the binary format has been reverse-engineered thoroughly enough that open-source parsers exist for Python (`plistlib`, in the standard library since Python 3.4), Ruby, Go, and Rust. The Python parser handles all three encodings and is reliable enough for production use in scripts that process device backups or Xcode project files.