Read a package.json file with enhanced error handling and data normalization
npx @tessl/cli install tessl/npm-read-pkg@9.0.00
# read-pkg
1
2
read-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.
3
4
## Package Information
5
6
- **Package Name**: read-pkg
7
- **Package Type**: npm
8
- **Language**: JavaScript (ES modules with TypeScript definitions)
9
- **Installation**: `npm install read-pkg`
10
11
## Core Imports
12
13
```typescript
14
import { readPackage, readPackageSync, parsePackage } from "read-pkg";
15
```
16
17
Note: This package is ES module only and does not support CommonJS `require()`.
18
19
## Basic Usage
20
21
```typescript
22
import { readPackage, readPackageSync, parsePackage } from "read-pkg";
23
24
// Read package.json from current directory (async)
25
const pkg = await readPackage();
26
console.log(pkg.name, pkg.version);
27
28
// Read from specific directory (async)
29
const otherPkg = await readPackage({ cwd: 'path/to/other/project' });
30
31
// Synchronous version
32
const pkgSync = readPackageSync();
33
34
// Parse existing package.json data
35
const packageData = { name: 'my-app', version: '1.0.0' };
36
const parsedPkg = parsePackage(packageData);
37
```
38
39
## Architecture
40
41
read-pkg is built around three core functions:
42
43
- **File Reading**: `readPackage` and `readPackageSync` handle filesystem operations and locate package.json files
44
- **Data Parsing**: All functions use `parse-json` for enhanced JSON parsing with better error messages
45
- **Data Normalization**: Optional integration with `normalize-package-data` to standardize package.json structure
46
- **Type Safety**: Full TypeScript support with function overloads based on normalization options
47
48
## Capabilities
49
50
### Asynchronous Package Reading
51
52
Read and parse a package.json file asynchronously from the filesystem.
53
54
```typescript { .api }
55
/**
56
* Asynchronously read and parse a package.json file
57
* @param options - Configuration options
58
* @returns Promise resolving to parsed package data
59
*/
60
function readPackage(options?: NormalizeOptions): Promise<NormalizedPackageJson>;
61
function readPackage(options: Options): Promise<PackageJson>;
62
63
interface Options {
64
/** Current working directory (default: process.cwd()) */
65
readonly cwd?: URL | string;
66
/** Normalize package data using normalize-package-data (default: true) */
67
readonly normalize?: boolean;
68
}
69
70
interface NormalizeOptions extends Options {
71
readonly normalize?: true;
72
}
73
```
74
75
**Usage Examples:**
76
77
```typescript
78
import { readPackage } from "read-pkg";
79
80
// Read from current directory with normalization (default)
81
const pkg = await readPackage();
82
console.log(pkg.name); // Normalized package name
83
84
// Read from specific directory
85
const otherPkg = await readPackage({ cwd: './other-project' });
86
87
// Read with URL path
88
const urlPkg = await readPackage({ cwd: new URL('file:///path/to/project') });
89
90
// Disable normalization to get raw package.json data
91
const rawPkg = await readPackage({ normalize: false });
92
console.log(rawPkg.name); // May contain extra whitespace if present in file
93
94
// Example of normalization effects:
95
// If package.json contains: { "name": "my-package ", "version": "1.0.0" }
96
const normalized = await readPackage(); // normalize: true (default)
97
const raw = await readPackage({ normalize: false });
98
console.log(normalized.name); // "my-package" (trimmed)
99
console.log(raw.name); // "my-package " (untrimmed)
100
console.log(normalized._id); // "my-package@1.0.0" (added by normalization)
101
```
102
103
### Synchronous Package Reading
104
105
Read and parse a package.json file synchronously from the filesystem.
106
107
```typescript { .api }
108
/**
109
* Synchronously read and parse a package.json file
110
* @param options - Configuration options
111
* @returns Parsed package data
112
*/
113
function readPackageSync(options?: NormalizeOptions): NormalizedPackageJson;
114
function readPackageSync(options: Options): PackageJson;
115
```
116
117
**Usage Examples:**
118
119
```typescript
120
import { readPackageSync } from "read-pkg";
121
122
// Synchronous read with normalization (default)
123
const pkg = readPackageSync();
124
125
// Read from specific directory
126
const otherPkg = readPackageSync({ cwd: './other-project' });
127
128
// Read without normalization
129
const rawPkg = readPackageSync({ normalize: false });
130
```
131
132
### Package Data Parsing
133
134
Parse package.json data from objects or JSON strings without filesystem access.
135
136
```typescript { .api }
137
/**
138
* Parse package.json data from object or string
139
* @param packageFile - Package.json object or JSON string to parse
140
* @param options - Parse configuration options
141
* @returns Parsed package data
142
* @throws TypeError for invalid input types (arrays, null, functions)
143
*/
144
function parsePackage(packageFile: PackageJson | string, options?: NormalizeParseOptions): NormalizedPackageJson;
145
function parsePackage(packageFile: PackageJson | string, options: ParseOptions): PackageJson;
146
147
interface ParseOptions {
148
/** Normalize package data using normalize-package-data (default: true) */
149
readonly normalize?: boolean;
150
}
151
152
interface NormalizeParseOptions extends ParseOptions {
153
readonly normalize?: true;
154
}
155
```
156
157
**Usage Examples:**
158
159
```typescript
160
import { parsePackage } from "read-pkg";
161
162
// Parse object with normalization (default)
163
const packageObj = { name: 'my-app ', version: '1.0.0' };
164
const normalized = parsePackage(packageObj);
165
console.log(normalized.name); // 'my-app' (whitespace trimmed)
166
console.log(normalized._id); // 'my-app@1.0.0' (added by normalization)
167
168
// Parse JSON string
169
const jsonString = JSON.stringify({ name: 'test-pkg', version: '2.0.0' });
170
const parsed = parsePackage(jsonString);
171
172
// Parse without normalization
173
const raw = parsePackage(packageObj, { normalize: false });
174
console.log(raw.name); // 'my-app ' (whitespace preserved)
175
176
// Error handling for invalid inputs
177
try {
178
parsePackage(['invalid', 'array']); // Throws TypeError
179
} catch (error) {
180
console.log(error.message); // "`packageFile` should be either an `object` or a `string`."
181
}
182
```
183
184
## Types
185
186
```typescript { .api }
187
interface Options {
188
/** Current working directory (default: process.cwd()) */
189
readonly cwd?: URL | string;
190
/** Normalize package data using normalize-package-data (default: true) */
191
readonly normalize?: boolean;
192
}
193
194
interface NormalizeOptions extends Options {
195
readonly normalize?: true;
196
}
197
198
interface ParseOptions {
199
/** Normalize package data using normalize-package-data (default: true) */
200
readonly normalize?: boolean;
201
}
202
203
interface NormalizeParseOptions extends ParseOptions {
204
readonly normalize?: true;
205
}
206
207
/** Raw package.json type from type-fest library - represents standard package.json structure */
208
type PackageJson = {
209
name?: string;
210
version?: string;
211
description?: string;
212
main?: string;
213
scripts?: Record<string, string>;
214
dependencies?: Record<string, string>;
215
devDependencies?: Record<string, string>;
216
// ... and all other standard package.json fields
217
};
218
219
/** Package.json type after normalize-package-data processing with additional normalized fields */
220
type NormalizedPackageJson = PackageJson & {
221
/** Package identifier added by normalize-package-data */
222
_id?: string;
223
/** Readme content extracted or processed by normalize-package-data */
224
readme?: string;
225
/** Additional fields that may be added during normalization process */
226
_resolved?: string;
227
_integrity?: string;
228
_from?: string;
229
/** Homepage URL potentially derived from repository */
230
homepage?: string;
231
/** Normalized bugs object potentially derived from repository */
232
bugs?: { url?: string; email?: string };
233
/** Repository object normalized to standard format */
234
repository?: { type: string; url: string };
235
};
236
```
237
238
## Error Handling
239
240
The library provides enhanced error handling through its dependencies:
241
242
- **JSON Parse Errors**: Enhanced error messages via `parse-json` library with line/column information
243
- **File System Errors**: Standard Node.js file system errors (ENOENT, EACCES, etc.)
244
- **Type Validation**: `parsePackage` throws `TypeError` for invalid input types (arrays, null, functions)
245
- **Input Validation**: Comprehensive validation ensures only objects or strings are accepted for parsing
246
247
**Common Error Scenarios:**
248
249
```typescript
250
import { readPackage, parsePackage } from "read-pkg";
251
252
try {
253
// File not found
254
await readPackage({ cwd: './nonexistent-directory' });
255
} catch (error) {
256
// Handle file system errors
257
console.log(error.code); // 'ENOENT'
258
}
259
260
try {
261
// Invalid JSON
262
parsePackage('{ invalid json }');
263
} catch (error) {
264
// Enhanced error message with position info
265
console.log(error.message); // Detailed JSON parse error
266
}
267
268
try {
269
// Invalid input type
270
parsePackage(null);
271
} catch (error) {
272
console.log(error.message); // "`packageFile` should be either an `object` or a `string`."
273
}
274
```