Episode 8: Understanding Bin Scripts and Their Use in Yarn Workspaces
What Are Bin Scripts?
Bin scripts are executable files defined within a package that can be invoked:
From other packages in the workspace.
Globally when installed as a dependency.
They’re commonly used for:
CLIs (Command Line Interfaces), such as Babel, ESLint, or Create React App.
Custom scripts for automating tasks within projects.
How Bin Scripts Work
Definition
Bin scripts are specified in thepackage.json
of a package under thebin
property.Example for
moduleB
:{ "name": "moduleB", "version": "1.0.0", "bin": { "my-script": "./index.js" } }
The key (
my-script
) becomes the command name.The value (
./index.js
) points to the script file that will run.
Installation
Run
yarn install
(with--force
if necessary) to link the bin script.The script will appear in the root
node_modules/.bin/
folder as a symlink to the defined file.
Usage
The bin script can be run from:
The root package.json:
{ "scripts": { "start": "my-script" } }
Other packages in the workspace:
{ "scripts": { "start": "my-script" } }
Steps to Create and Use a Bin Script
1. Define a Bin Script
In the package.json
of the package (e.g., moduleB
):
{
"name": "moduleB",
"version": "1.0.0",
"bin": {
"moduleB-script": "./index.js"
}
}
2. Add a Shebang to the Script File
At the start of index.js
, include the shebang for Node.js:
#!/usr/bin/env node
console.log("Hello from moduleB!");
This tells the terminal to use Node.js to execute the script.
3. Install Dependencies and Link the Script
Run:
yarn install --force
This updates the node_modules/.bin/
directory in the root with a symlink for moduleB-script
.
4. Run the Script
From the Root package.json
Add a start
script:
{
"scripts": {
"start": "moduleB-script"
}
}
Run:
yarn start
From Another Package (e.g., moduleA
)
In moduleA/package.json
:
{
"scripts": {
"start": "moduleB-script"
}
}
Run from the workspace root:
yarn workspace moduleA start
Customizing Bin Script Names and Adding Multiple Scripts
Custom Command Names
Instead of using the package name as the default command, specify a custom name:{ "bin": { "custom-command": "./index.js" } }
Multiple Commands
Provide an object with multiple keys and corresponding script paths:{ "bin": { "command-one": "./script-one.js", "command-two": "./script-two.js" } }
Run yarn install --force
again to update the bin directory.
Using Bin Scripts Across the Workspace
Symlinks to the Root
Bin scripts are symlinked to the root node_modules/.bin
directory, making them accessible:
Globally across the monorepo.
Without needing to install the package multiple times.
Accessing from Other Packages
Packages in the workspace can directly call the bin script in their own scripts, such as yarn workspace moduleA start
.
Troubleshooting
Bin Script Errors
Missing Shebang
Ensure#!/usr/bin/env node
is at the top of the file to specify Node.js for execution.No Action on
yarn install
Use the--force
flag to ensure Yarn recognizes changes to thebin
property.Conflicting Names
Choose unique command names to avoid conflicts.
Summary
Bin scripts enable CLI functionality within and across workspace packages.
They are easy to set up using the
bin
property inpackage.json
.Use the shebang to run JavaScript as a script.
Symlinks in
node_modules/.bin
make scripts accessible globally within the monorepo.You can define custom command names and add multiple bin scripts per package.