0
# Lerna Symlink Binary
1
2
An internal Lerna tool for symlinking binary executables from source packages to destination packages' node_modules/.bin directories. This utility enables cross-package executable access in monorepos by creating symbolic links for declared binaries, supporting Lerna's internal package management workflows.
3
4
## Package Information
5
6
- **Package Name**: @lerna/symlink-binary
7
- **Package Type**: npm
8
- **Language**: JavaScript (CommonJS)
9
- **Installation**: `npm install @lerna/symlink-binary`
10
- **Node.js Support**: ^14.15.0 || >=16.0.0
11
- **TypeScript**: No built-in types; uses JSDoc for type information
12
13
## Core Imports
14
15
```javascript
16
const { symlinkBinary } = require("@lerna/symlink-binary");
17
```
18
19
## Basic Usage
20
21
```javascript
22
const { symlinkBinary } = require("@lerna/symlink-binary");
23
const { Package } = require("@lerna/package");
24
25
// Using path strings
26
await symlinkBinary("/path/to/source-package", "/path/to/dest-package");
27
28
// Using Package instances
29
const srcPackage = Package.lazy("/path/to/source-package");
30
const destPackage = Package.lazy("/path/to/dest-package");
31
await symlinkBinary(srcPackage, destPackage);
32
```
33
34
## Capabilities
35
36
### Binary Symlinking
37
38
Creates symbolic links for binary executables from a source package to the destination package's node_modules/.bin directory. Handles all declared binaries in the source package's `bin` field, creating appropriate symlinks even if the binaries don't exist yet (anticipating build-time generation).
39
40
```javascript { .api }
41
/**
42
* Symlink bins of srcPackage to node_modules/.bin in destPackage
43
* @param {Object|string} srcPackageRef - Source package reference (Package instance or path string)
44
* @param {Object|string} destPackageRef - Destination package reference (Package instance or path string)
45
* @returns {Promise} Promise that resolves when all symlinks are created successfully
46
*/
47
function symlinkBinary(srcPackageRef, destPackageRef);
48
```
49
50
**Parameters:**
51
- `srcPackageRef` (Object|string): Source package reference. Can be a Package instance or absolute path string to the source package directory.
52
- `destPackageRef` (Object|string): Destination package reference. Can be a Package instance or absolute path string to the destination package directory.
53
54
**Returns:**
55
- `Promise`: Resolves when all symlinks are created successfully. Resolves immediately if the source package has no declared binaries.
56
57
**Behavior:**
58
- Automatically converts path strings to Package instances using `Package.lazy()` - this provides lazy loading of package metadata
59
- Reads binary declarations from the source package's `bin` field in package.json
60
- Handles `contents` property: if the source package has a `contents` field, resolves binaries relative to that subdirectory instead of package root
61
- Creates symbolic links for all declared binaries, even if the binary files don't exist yet (anticipates build-time generation)
62
- Creates the destination's node_modules/.bin directory if it doesn't exist using `fs.mkdirp()`
63
- Uses concurrent processing via `p-map` for multiple symlink operations
64
- Creates executable symlinks using `createSymlink(src, dst, "exec")` - the "exec" type ensures proper executable permissions
65
- Preserves existing symlinks when adding new ones
66
- Gracefully handles packages without binary declarations (returns resolved Promise immediately)
67
68
**Usage Examples:**
69
70
```javascript
71
const { symlinkBinary } = require("@lerna/symlink-binary");
72
73
// Basic path-based usage
74
await symlinkBinary(
75
"/workspace/packages/cli-tool",
76
"/workspace/packages/app"
77
);
78
79
// Using with Package instances
80
const { Package } = require("@lerna/package");
81
const srcPkg = Package.lazy("/workspace/packages/cli-tool");
82
const destPkg = Package.lazy("/workspace/packages/app");
83
await symlinkBinary(srcPkg, destPkg);
84
85
// Multiple sequential operations
86
await symlinkBinary("/workspace/tools/build-tool", "/workspace/app");
87
await symlinkBinary("/workspace/tools/lint-tool", "/workspace/app");
88
// Both tools' binaries will be available in /workspace/app/node_modules/.bin/
89
90
// Working with packages that have a 'contents' field
91
// If source package.json has "contents": "dist", binaries resolve from /workspace/tools/compiled-tool/dist/
92
await symlinkBinary("/workspace/tools/compiled-tool", "/workspace/app");
93
```
94
95
**Error Handling:**
96
The function will reject the returned Promise if:
97
- Package paths are invalid or don't exist
98
- Package.lazy() fails to load package metadata (e.g., missing package.json)
99
- File system permissions prevent symlink creation
100
- Destination directory cannot be created (permission issues)
101
- The `createSymlink` operation fails (e.g., source file doesn't exist and can't be linked)
102
- Concurrent symlink operations fail due to filesystem conflicts
103
104
## Dependencies
105
106
- **@lerna/create-symlink**: Creates symbolic links with proper executable permissions
107
- **@lerna/package**: Provides Package class for package metadata handling
108
- **fs-extra**: Enhanced file system operations, specifically mkdirp for directory creation
109
- **p-map**: Concurrent promise mapping for parallel symlink operations