simple-plist utility
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.
Common errors
-
TypeError: plist.readFileSync is not a function
cause Attempting to access a function (e.g., `readFileSync`) directly from a default import or incorrectly requiring the module in an ESM context.fixEnsure 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';`. -
Error: ENOENT: no such file or directory, open '/path/to/non-existent.plist'
cause The specified plist file does not exist at the provided path, or the path is incorrect.fixVerify the file path is correct and that the file actually exists. Use `path.join()` for robust path construction across different operating systems. -
Error: unable to parse plist
cause The input string or file content is not a valid XML or binary plist format, or is malformed.fixInspect 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.
Warnings
- breaking 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.
- gotcha 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.
- gotcha 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`.
Install
-
npm install simple-plist -
yarn add simple-plist -
pnpm add simple-plist
Imports
- * as plist
import plist from 'simple-plist'; // Incorrect default import
import * as plist from 'simple-plist';
- { readFileSync, writeFileSync }
const { readFileSync, writeFileSync } = require('simple-plist'); // CommonJS, not ESMimport { readFileSync, writeFileSync } from 'simple-plist'; - require('simple-plist')
import plist from 'simple-plist'; // Incompatible with CommonJS modules
const plist = require('simple-plist'); - parse
import { parse: parsePlist } from 'simple-plist'; // Unnecessary alias if not conflictingimport { parse } from 'simple-plist';
Quickstart
import { writeFileSync, readFileSync } from 'simple-plist';
import * as path from 'path';
import * as fs from 'fs';
const tempFilePath = path.join(process.cwd(), 'temp.plist');
type AppConfig = {
appName: string;
version: string;
debugMode: boolean;
settings: { theme: string; language: string };
};
const config: AppConfig = {
appName: 'MyAwesomeApp',
version: '1.0.0',
debugMode: true,
settings: { theme: 'dark', language: 'en-US' },
};
try {
// Write the object to an XML plist file
writeFileSync(tempFilePath, config);
console.log('Plist file written successfully:', tempFilePath);
// Read the plist file back into an object
const readConfig = readFileSync(tempFilePath) as AppConfig;
console.log('Plist file read successfully:', readConfig);
console.log('App Name:', readConfig.appName);
console.log('Version:', readConfig.version);
} catch (error) {
console.error('An error occurred:', error);
} finally {
// Clean up the temporary file
if (fs.existsSync(tempFilePath)) {
fs.unlinkSync(tempFilePath);
console.log('Temporary plist file cleaned up.');
}
}