{"id":12032,"library":"simple-plist","title":"simple-plist utility","description":"simple-plist is a wrapper utility for interacting with Apple Property List (plist) data, supporting both binary and XML formats. The current stable version is 1.3.1. While its release cadence is not rapid, the package demonstrates active maintenance, as evidenced by the recent v1.3.0 rewrite into TypeScript to provide strong typing. It offers a straightforward API for reading and writing plist files synchronously and asynchronously, as well as in-memory parsing and stringification. This package serves as a convenient abstraction over lower-level plist parsing libraries, making it easier to manage `.plist` files commonly found in macOS and iOS environments, without requiring direct interaction with the underlying `plist` or `bplist` packages.","status":"active","version":"1.3.1","language":"javascript","source_language":"en","source_url":"https://github.com/wollardj/simple-plist","tags":["javascript","plist","binary","bplist","xml","typescript"],"install":[{"cmd":"npm install simple-plist","lang":"bash","label":"npm"},{"cmd":"yarn add simple-plist","lang":"bash","label":"yarn"},{"cmd":"pnpm add simple-plist","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for parsing and building XML plist data.","package":"plist","optional":false},{"reason":"Core dependency for parsing binary plist data.","package":"bplist-parser","optional":false},{"reason":"Core dependency for creating binary plist data.","package":"bplist-creator","optional":false}],"imports":[{"note":"This is the recommended way to import all functions in ESM contexts, especially when using TypeScript, allowing access via `plist.readFile`, `plist.writeFileSync`, etc.","wrong":"import plist from 'simple-plist'; // Incorrect default import","symbol":"* as plist","correct":"import * as plist from 'simple-plist';"},{"note":"For specific synchronous file operations, named imports are efficient. Other common named exports include `readFile`, `writeFile`, `parse`, `stringify`, `readBinaryFileSync`, `writeBinaryFileSync`, etc.","wrong":"const { readFileSync, writeFileSync } = require('simple-plist'); // CommonJS, not ESM","symbol":"{ readFileSync, writeFileSync }","correct":"import { readFileSync, writeFileSync } from 'simple-plist';"},{"note":"This is the standard CommonJS import pattern. Access functions directly from the `plist` object, e.g., `plist.readFileSync`. This pattern is primarily for Node.js environments not configured for ESM.","wrong":"import plist from 'simple-plist'; // Incompatible with CommonJS modules","symbol":"require('simple-plist')","correct":"const plist = require('simple-plist');"},{"note":"Used for parsing plist content directly from a string or buffer into a JavaScript object. This function also supports TypeScript generics for type-safe parsing.","wrong":"import { parse: parsePlist } from 'simple-plist'; // Unnecessary alias if not conflicting","symbol":"parse","correct":"import { parse } from 'simple-plist';"}],"quickstart":{"code":"import { writeFileSync, readFileSync } from 'simple-plist';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nconst tempFilePath = path.join(process.cwd(), 'temp.plist');\n\ntype AppConfig = {\n  appName: string;\n  version: string;\n  debugMode: boolean;\n  settings: { theme: string; language: string };\n};\n\nconst config: AppConfig = {\n  appName: 'MyAwesomeApp',\n  version: '1.0.0',\n  debugMode: true,\n  settings: { theme: 'dark', language: 'en-US' },\n};\n\ntry {\n  // Write the object to an XML plist file\n  writeFileSync(tempFilePath, config);\n  console.log('Plist file written successfully:', tempFilePath);\n\n  // Read the plist file back into an object\n  const readConfig = readFileSync(tempFilePath) as AppConfig;\n  console.log('Plist file read successfully:', readConfig);\n  console.log('App Name:', readConfig.appName);\n  console.log('Version:', readConfig.version);\n} catch (error) {\n  console.error('An error occurred:', error);\n} finally {\n  // Clean up the temporary file\n  if (fs.existsSync(tempFilePath)) {\n    fs.unlinkSync(tempFilePath);\n    console.log('Temporary plist file cleaned up.');\n  }\n}","lang":"typescript","description":"Demonstrates how to write a JavaScript object to a plist file and then read it back, using synchronous file operations and TypeScript types."},"warnings":[{"fix":"Upgrade your Node.js runtime to version 8 or higher (or a currently supported LTS version).","message":"Support for Node.js 6 was dropped in version 1.1.0. Users on older Node.js versions must upgrade their Node.js runtime or remain on an older `simple-plist` version.","severity":"breaking","affected_versions":">=1.1.0"},{"fix":"Thoroughly test your application after upgrading. If using JavaScript, be mindful of stricter behavior that might stem from the underlying TypeScript types. Consider adopting TypeScript for better type safety.","message":"The `v1.3.0` release involved a complete rewrite of the codebase into TypeScript. While declared to have 'minimal risk' for existing JavaScript users, subtle behavioral changes or type inference issues might arise for projects not using TypeScript or those relying on implicit behaviors.","severity":"gotcha","affected_versions":">=1.3.0"},{"fix":"Use `const { promisify } = require('util'); const readFileAsync = promisify(plist.readFile);` to convert callback-based functions to return Promises for easier async/await usage.","message":"When using `simple-plist` in an asynchronous context, be aware that the asynchronous functions (e.g., `readFile`, `writeFile`) use Node.js-style callbacks. For promise-based workflows, you can wrap these functions using `util.promisify`.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are using `import * as plist from 'simple-plist';` for ESM, or `const plist = require('simple-plist');` for CommonJS. Alternatively, use named imports like `import { readFileSync } from 'simple-plist';`.","cause":"Attempting to access a function (e.g., `readFileSync`) directly from a default import or incorrectly requiring the module in an ESM context.","error":"TypeError: plist.readFileSync is not a function"},{"fix":"Verify the file path is correct and that the file actually exists. Use `path.join()` for robust path construction across different operating systems.","cause":"The specified plist file does not exist at the provided path, or the path is incorrect.","error":"Error: ENOENT: no such file or directory, open '/path/to/non-existent.plist'"},{"fix":"Inspect the plist content for structural correctness. Ensure it conforms to Apple's Property List DTD for XML plists or the binary plist specification. Tools like `plutil` (on macOS) can validate plist files.","cause":"The input string or file content is not a valid XML or binary plist format, or is malformed.","error":"Error: unable to parse plist"}],"ecosystem":"npm"}