or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-libnpmdiff

The registry diff library for comparing npm package versions via tarballs

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/libnpmdiff@8.0.x

To install, run

npx @tessl/cli install tessl/npm-libnpmdiff@8.0.0

0

# libnpmdiff

1

2

libnpmdiff is a registry diff library that compares different versions of npm packages by fetching registry tarballs and generating unified diff outputs. It provides a Promise-based API for analyzing package changes with extensive configuration options for diff formatting and file filtering.

3

4

## Package Information

5

6

- **Package Name**: libnpmdiff

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install libnpmdiff`

10

11

## Core Imports

12

13

```javascript

14

const diff = require("libnpmdiff");

15

```

16

17

## Basic Usage

18

19

```javascript

20

const diff = require("libnpmdiff");

21

22

// Compare two package versions

23

const patch = await diff([

24

"abbrev@1.1.0",

25

"abbrev@1.1.1"

26

]);

27

console.log(patch);

28

29

// Compare with options

30

const coloredPatch = await diff([

31

"lodash@4.17.20",

32

"lodash@4.17.21"

33

], {

34

color: true,

35

diffUnified: 5,

36

diffFiles: ["package.json", "lib/**/*.js"]

37

});

38

```

39

40

## Architecture

41

42

libnpmdiff follows a modular architecture with distinct phases for package comparison:

43

44

- **Manifest Resolution**: Uses `pacote.manifest()` to resolve package specifications and extract version metadata

45

- **Tarball Fetching**: Downloads package tarballs from the registry using the `getTarball` module

46

- **File Extraction**: The `untar` module extracts and filters files from tarballs based on configuration options

47

- **Diff Generation**: The `formatDiff` module generates unified diff patches using the `diff` library with customizable formatting

48

- **File Filtering**: Built-in support for glob patterns and file matching using `minimatch`

49

50

The library operates asynchronously throughout, using Promise-based APIs for all network operations and file processing. Each phase can be configured independently through the options parameter.

51

52

## Capabilities

53

54

### Main Diff Function

55

56

Compares two npm package specifications and returns a unified diff string.

57

58

```javascript { .api }

59

/**

60

* Compare two npm package specifications and generate a unified diff

61

* @param {string[]} specs - Array of exactly 2 npm package specs to compare

62

* @param {DiffOptions} opts - Optional configuration options

63

* @returns {Promise<string>} Unified diff patch string

64

* @throws {TypeError} EDIFFARGS error if specs length is not exactly 2

65

*/

66

function diff(specs, opts = {});

67

```

68

69

**Parameters:**

70

71

- `specs` (Array): Array of exactly 2 npm package specifications. Supports all npm spec formats:

72

- Version specs: `"package@1.0.0"`

73

- Version ranges: `"package@^1.0.0"`

74

- Git URLs: `"git+https://github.com/user/repo.git"`

75

- Local paths: `"file:/path/to/package"`

76

- Tarball URLs: `"https://registry.npmjs.org/package/-/package-1.0.0.tgz"`

77

78

- `opts` (Object, optional): Configuration options for diff generation

79

80

**Returns:** Promise that resolves to a string containing unified diff patches

81

82

**Throws:** TypeError with code 'EDIFFARGS' if specs array length is not exactly 2

83

84

### Configuration Options

85

86

The diff function accepts extensive configuration options:

87

88

```javascript { .api }

89

interface DiffOptions {

90

// Diff formatting options

91

color?: boolean; // Add ANSI colors to output (default: false)

92

tagVersionPrefix?: string; // Prefix for version numbers (default: "v")

93

diffUnified?: number; // Lines of context before/after each diff (default: 3)

94

diffNameOnly?: boolean; // Print only file names, no patch content (default: false)

95

diffNoPrefix?: boolean; // Skip prefixes in filenames (default: false)

96

diffSrcPrefix?: string; // Prefix for source files (default: "a/")

97

diffDstPrefix?: string; // Prefix for destination files (default: "b/")

98

diffText?: boolean; // Treat all files as text, including binary (default: false)

99

diffIgnoreAllSpace?: boolean; // Ignore whitespace changes (default: false)

100

101

// File filtering options

102

diffFiles?: string[]; // Only show patches for specified files/globs

103

104

// Pacote options

105

cache?: string; // Cache directory path

106

registry?: string; // Registry URL

107

where?: string; // Working directory

108

// ... other pacote options

109

}

110

```

111

112

## Usage Examples

113

114

### Basic Package Comparison

115

116

```javascript

117

const diff = require("libnpmdiff");

118

119

const patch = await diff([

120

"express@4.17.0",

121

"express@4.18.0"

122

]);

123

console.log(patch);

124

```

125

126

### Colored Output with Context

127

128

```javascript

129

const coloredDiff = await diff([

130

"react@17.0.0",

131

"react@18.0.0"

132

], {

133

color: true, // Enable ANSI colors

134

diffUnified: 5 // Show 5 lines of context

135

});

136

```

137

138

### File Filtering with Globs

139

140

```javascript

141

const filtered = await diff([

142

"webpack@5.0.0",

143

"webpack@5.1.0"

144

], {

145

diffFiles: [

146

"package.json", // Specific file

147

"lib/**/*.js", // Glob pattern

148

"*.md" // All markdown files

149

]

150

});

151

```

152

153

### Name-Only Mode

154

155

```javascript

156

const fileNames = await diff([

157

"@babel/core@7.0.0",

158

"@babel/core@7.1.0"

159

], {

160

diffNameOnly: true // Only show changed file names

161

});

162

```

163

164

### Local File Comparison

165

166

```javascript

167

const localDiff = await diff([

168

"file:/path/to/package1",

169

"file:/path/to/package2"

170

], {

171

diffNoPrefix: true, // Remove a/ and b/ prefixes

172

diffText: true // Force text mode for binary files

173

});

174

```

175

176

### Whitespace-Insensitive Comparison

177

178

```javascript

179

const cleanDiff = await diff([

180

"prettier@2.0.0",

181

"prettier@2.1.0"

182

], {

183

diffIgnoreAllSpace: true, // Ignore whitespace changes

184

tagVersionPrefix: "" // Remove version prefix

185

});

186

```

187

188

### Custom Registry and Caching

189

190

```javascript

191

const diff = await diff([

192

"private-pkg@1.0.0",

193

"private-pkg@1.1.0"

194

], {

195

registry: "https://npm.example.com",

196

cache: "/tmp/npm-cache",

197

where: process.cwd()

198

});

199

```

200

201

## Error Handling

202

203

### EDIFFARGS Error

204

205

Thrown when the specs array doesn't contain exactly 2 elements:

206

207

```javascript

208

try {

209

await diff(["single-package@1.0.0"]);

210

} catch (error) {

211

console.log(error.code); // "EDIFFARGS"

212

console.log(error.message); // "libnpmdiff needs two arguments to compare"

213

}

214

```

215

216

### EDIFFUNTAR Error

217

218

Thrown when tarball extraction fails during processing:

219

220

```javascript

221

try {

222

await diff(["corrupt-package@1.0.0", "corrupt-package@2.0.0"]);

223

} catch (error) {

224

console.log(error.code); // "EDIFFUNTAR"

225

console.log(error.message); // "failed to read files"

226

}

227

```

228

229

## Types

230

231

```javascript { .api }

232

// Error types

233

interface EDiffArgsError extends TypeError {

234

code: "EDIFFARGS";

235

message: "libnpmdiff needs two arguments to compare";

236

}

237

238

interface EDiffUntarError extends Error {

239

code: "EDIFFUNTAR";

240

message: "failed to read files";

241

}

242

```