Read a package.json file with enhanced error handling and data normalization
npx @tessl/cli install tessl/npm-read-pkg@9.0.0read-pkg is a robust JavaScript library for reading and parsing package.json files with enhanced error handling and data normalization. It provides both asynchronous and synchronous APIs for reading package.json files from the filesystem, with automatic JSON parsing using better error messages and optional package data normalization.
npm install read-pkgimport { readPackage, readPackageSync, parsePackage } from "read-pkg";Note: This package is ES module only and does not support CommonJS require().
import { readPackage, readPackageSync, parsePackage } from "read-pkg";
// Read package.json from current directory (async)
const pkg = await readPackage();
console.log(pkg.name, pkg.version);
// Read from specific directory (async)
const otherPkg = await readPackage({ cwd: 'path/to/other/project' });
// Synchronous version
const pkgSync = readPackageSync();
// Parse existing package.json data
const packageData = { name: 'my-app', version: '1.0.0' };
const parsedPkg = parsePackage(packageData);read-pkg is built around three core functions:
readPackage and readPackageSync handle filesystem operations and locate package.json filesparse-json for enhanced JSON parsing with better error messagesnormalize-package-data to standardize package.json structureRead and parse a package.json file asynchronously from the filesystem.
/**
* Asynchronously read and parse a package.json file
* @param options - Configuration options
* @returns Promise resolving to parsed package data
*/
function readPackage(options?: NormalizeOptions): Promise<NormalizedPackageJson>;
function readPackage(options: Options): Promise<PackageJson>;
interface Options {
/** Current working directory (default: process.cwd()) */
readonly cwd?: URL | string;
/** Normalize package data using normalize-package-data (default: true) */
readonly normalize?: boolean;
}
interface NormalizeOptions extends Options {
readonly normalize?: true;
}Usage Examples:
import { readPackage } from "read-pkg";
// Read from current directory with normalization (default)
const pkg = await readPackage();
console.log(pkg.name); // Normalized package name
// Read from specific directory
const otherPkg = await readPackage({ cwd: './other-project' });
// Read with URL path
const urlPkg = await readPackage({ cwd: new URL('file:///path/to/project') });
// Disable normalization to get raw package.json data
const rawPkg = await readPackage({ normalize: false });
console.log(rawPkg.name); // May contain extra whitespace if present in file
// Example of normalization effects:
// If package.json contains: { "name": "my-package ", "version": "1.0.0" }
const normalized = await readPackage(); // normalize: true (default)
const raw = await readPackage({ normalize: false });
console.log(normalized.name); // "my-package" (trimmed)
console.log(raw.name); // "my-package " (untrimmed)
console.log(normalized._id); // "my-package@1.0.0" (added by normalization)Read and parse a package.json file synchronously from the filesystem.
/**
* Synchronously read and parse a package.json file
* @param options - Configuration options
* @returns Parsed package data
*/
function readPackageSync(options?: NormalizeOptions): NormalizedPackageJson;
function readPackageSync(options: Options): PackageJson;Usage Examples:
import { readPackageSync } from "read-pkg";
// Synchronous read with normalization (default)
const pkg = readPackageSync();
// Read from specific directory
const otherPkg = readPackageSync({ cwd: './other-project' });
// Read without normalization
const rawPkg = readPackageSync({ normalize: false });Parse package.json data from objects or JSON strings without filesystem access.
/**
* Parse package.json data from object or string
* @param packageFile - Package.json object or JSON string to parse
* @param options - Parse configuration options
* @returns Parsed package data
* @throws TypeError for invalid input types (arrays, null, functions)
*/
function parsePackage(packageFile: PackageJson | string, options?: NormalizeParseOptions): NormalizedPackageJson;
function parsePackage(packageFile: PackageJson | string, options: ParseOptions): PackageJson;
interface ParseOptions {
/** Normalize package data using normalize-package-data (default: true) */
readonly normalize?: boolean;
}
interface NormalizeParseOptions extends ParseOptions {
readonly normalize?: true;
}Usage Examples:
import { parsePackage } from "read-pkg";
// Parse object with normalization (default)
const packageObj = { name: 'my-app ', version: '1.0.0' };
const normalized = parsePackage(packageObj);
console.log(normalized.name); // 'my-app' (whitespace trimmed)
console.log(normalized._id); // 'my-app@1.0.0' (added by normalization)
// Parse JSON string
const jsonString = JSON.stringify({ name: 'test-pkg', version: '2.0.0' });
const parsed = parsePackage(jsonString);
// Parse without normalization
const raw = parsePackage(packageObj, { normalize: false });
console.log(raw.name); // 'my-app ' (whitespace preserved)
// Error handling for invalid inputs
try {
parsePackage(['invalid', 'array']); // Throws TypeError
} catch (error) {
console.log(error.message); // "`packageFile` should be either an `object` or a `string`."
}interface Options {
/** Current working directory (default: process.cwd()) */
readonly cwd?: URL | string;
/** Normalize package data using normalize-package-data (default: true) */
readonly normalize?: boolean;
}
interface NormalizeOptions extends Options {
readonly normalize?: true;
}
interface ParseOptions {
/** Normalize package data using normalize-package-data (default: true) */
readonly normalize?: boolean;
}
interface NormalizeParseOptions extends ParseOptions {
readonly normalize?: true;
}
/** Raw package.json type from type-fest library - represents standard package.json structure */
type PackageJson = {
name?: string;
version?: string;
description?: string;
main?: string;
scripts?: Record<string, string>;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
// ... and all other standard package.json fields
};
/** Package.json type after normalize-package-data processing with additional normalized fields */
type NormalizedPackageJson = PackageJson & {
/** Package identifier added by normalize-package-data */
_id?: string;
/** Readme content extracted or processed by normalize-package-data */
readme?: string;
/** Additional fields that may be added during normalization process */
_resolved?: string;
_integrity?: string;
_from?: string;
/** Homepage URL potentially derived from repository */
homepage?: string;
/** Normalized bugs object potentially derived from repository */
bugs?: { url?: string; email?: string };
/** Repository object normalized to standard format */
repository?: { type: string; url: string };
};The library provides enhanced error handling through its dependencies:
parse-json library with line/column informationparsePackage throws TypeError for invalid input types (arrays, null, functions)Common Error Scenarios:
import { readPackage, parsePackage } from "read-pkg";
try {
// File not found
await readPackage({ cwd: './nonexistent-directory' });
} catch (error) {
// Handle file system errors
console.log(error.code); // 'ENOENT'
}
try {
// Invalid JSON
parsePackage('{ invalid json }');
} catch (error) {
// Enhanced error message with position info
console.log(error.message); // Detailed JSON parse error
}
try {
// Invalid input type
parsePackage(null);
} catch (error) {
console.log(error.message); // "`packageFile` should be either an `object` or a `string`."
}