pnpm-dep-source
v0.4.0
Published
CLI to switch pnpm dependencies between local, GitHub, GitLab, and NPM sources
Downloads
18
Maintainers
Readme
pnpm-dep-source
CLI to switch pnpm dependencies between local, GitHub / GitLab, and NPM sources.
Installation
npm install -g pnpm-dep-source
# or
pnpm add -g pnpm-dep-sourceUsage
Initialize a dependency
# From local path - auto-detects GitHub/GitLab from package.json or git remote
pds init ../../path/to/local/pkg
# From GitHub/GitLab URL
pds init https://github.com/user/repo
pds init https://gitlab.com/user/repo
# Override or specify repo explicitly
pds init ../../path/to/local/pkg -H github-user/repo
pds init ../../path/to/local/pkg -L gitlab-user/repo
# Global CLI tools (uses ~/.config/pnpm-dep-source/config.json)
pds -g init /path/to/local/cliinit adds the dependency to package.json if not present, then auto-activates:
- Local path → switches to
workspace:*mode - GitHub URL → switches to
github:user/repo#sha - GitLab URL → switches to GitLab tarball URL
Use -D to add as a devDependency, or -I to skip adding/activation entirely.
Switch to local development
pds local [dep] # or pds l [dep]Note: [dep] is optional if only one dependency is configured.
This will:
- Set
package.jsondependency toworkspace:* - Create/update
pnpm-workspace.yamlwith the local path - Add to
vite.config.tsoptimizeDeps.exclude(if vite config exists) - Run
pnpm install
Switch to GitHub or GitLab (auto-detect)
pds g [dep] # Auto-detects GitHub or GitLab (uses dist branch HEAD)
pds g [dep] -r v1.0.0 # Resolves ref to SHA
pds g [dep] -R dist # Uses ref as-is (pin to branch name)
pds g [dep] -n # Dry-run: show what would be installedErrors if neither or both are configured; use pds gh or pds gl explicitly in that case.
Switch to GitHub
pds github [dep] # Uses dist branch HEAD (resolved to SHA)
pds gh [dep] -r v1.0.0 # Resolves ref to SHA
pds gh [dep] -R dist # Uses ref as-is (pin to branch name)
pds gh [dep] -n # Dry-run: show what would be installedThis will:
- Set
package.jsondependency togithub:user/repo#sha - Remove local path from
pnpm-workspace.yaml - Remove from
vite.config.tsoptimizeDeps.exclude - Run
pnpm install
Switch to GitLab
pds gitlab [dep] # Uses dist branch HEAD (resolved to SHA)
pds gl [dep] -r v1.0.0 # Resolves ref to SHA
pds gl [dep] -R dist # Uses ref as-is (pin to branch name)
pds gl [dep] -n # Dry-run: show what would be installedThis will:
- Set
package.jsondependency to GitLab tarball URL - Remove local path from
pnpm-workspace.yaml - Remove from
vite.config.tsoptimizeDeps.exclude - Run
pnpm install
Note: GitLab uses tarball URLs (e.g. https://gitlab.com/user/repo/-/archive/ref/repo-ref.tar.gz) since pnpm doesn't support gitlab: prefix.
Switch to NPM
pds npm [dep] # Latest version
pds npm [dep] [version] # Specific version
pds n 1.2.3 # With one dep, arg is treated as version
pds n [dep] -n # Dry-run: show what would be installedCheck status
pds status # Show all configured deps
pds status [dep] # Show specific dep
pds s # AliasList configured dependencies
pds # defaults to list
pds list # or pds ls
pds ls -a # show both project and global dependencies
pds ls -v # include available remote versions (npm, GitHub/GitLab dist SHA + version)
pds ls -av # combined: all deps, verbose
pds versions # or pds v (alias for ls -v)The active source is highlighted with a green * prefix (plain * in non-TTY mode). Verbose mode shows:
- Local git info (short SHA, dirty indicator)
[dev]indicator for devDependencies- Remote dist branch SHA and version (for at-a-glance staleness checks)
Update dependency fields
pds set <dep> -H user/repo # Set GitHub repo
pds set <dep> -L user/repo # Set GitLab repo
pds set <dep> -l ../path # Set local path
pds set <dep> -n pkg-name # Set NPM name
pds set <dep> -H "" # Remove GitHub
pds -g set # Update global config (with single dep)Stop tracking a dependency
pds deinit [dep] # or pds di [dep]
pds -g di # Stop tracking global depThis removes the dependency from .pds.json but keeps it in package.json.
Remove a dependency
pds rm [dep] # or pds r [dep]
pds -g rm # Remove global depThis removes the dependency from both .pds.json and package.json, then runs pnpm install.
Monorepo subdir support
For dependencies that live in a subdirectory of a monorepo, pds init auto-detects the subdirectory relative to the git root:
pds init ../../slidev/packages/slidev # detects subdir: /packages/slidevWhen switching to GitHub, the specifier uses pnpm's &path: syntax:
github:user/repo#sha&path:/packages/slidevThe subdir field is stored in .pds.json and can also be set manually via the config.
Git hooks
Prevent accidentally pushing (or committing) with local dependencies:
pds hooks install # Install global git hooks
pds hooks uninstall # Remove them
pds hooks status # Check installation statusInstalls both pre-push and pre-commit hooks via git config --global core.hooksPath. By default, the check runs on pre-push — local deps are caught before pushing, not before every commit (which would interfere with WIP workflows).
Each hook calls pds check --hook <type>, and pds check decides whether to run based on the resolved checkOn config:
project .pds.json checkOn → global config checkOn → default ("pre-push")Per-project overrides
Set "checkOn" in .pds.json (or .pnpm-dep-source.json):
{ "checkOn": "pre-commit" }Valid values:
"pre-push"(default) — block on push"pre-commit"— block on commit"none"— disable the check entirely
The legacy "skipCheck": true is treated as "checkOn": "none".
Global default override
Set "checkOn" in ~/.config/pnpm-dep-source/config.json to change the default for all projects.
Hook chaining
The hooks chain to:
- Any previously configured
core.hooksPath(saved and restored on uninstall) - Local
.git/hooks/hooks if present (normally ignored whencore.hooksPathis set)
Check for local dependencies
pds check # Exits non-zero if any deps are local (always runs)
pds check -q # Quiet mode (exit code only)
pds check --hook pre-push # Only runs if checkOn resolves to "pre-push"Shell aliases
eval "$(pds shell-integration)" # Add to .bashrc/.zshrcProvides aliases like pdl (list), pdla (list all), pdlv (list verbose), pdgh (github), pdgl (gitlab), pdsn (npm), pdg (global mode), etc. Run pds shell-integration to see the full list.
Show pds info
pds info # Show version and install sourceConfig file
The tool stores configuration in .pds.json (also supports .pnpm-dep-source.json for backwards compatibility):
{
"dependencies": {
"@scope/package-name": {
"localPath": "../../path/to/local",
"github": "user/repo",
"gitlab": "user/repo",
"npm": "@scope/package-name",
"distBranch": "dist",
"subdir": "/packages/client"
}
},
"checkOn": "pre-push"
}The subdir field is optional and auto-detected during init for monorepo packages.
Set "checkOn" to control when the git hook check runs: "pre-push" (default), "pre-commit", or "none" to disable. The legacy "skipCheck": true is still supported (treated as "checkOn": "none").
Options
Top-level options
-g, --global: Use global config (~/.config/pnpm-dep-source/config.json) for CLI tools. Must come before the command:pds -g ls,pds -g gh, etc.
Command options
-a, --all: Show both project and global dependencies (forlist)-b, --dist-branch <branch>: Dist branch name (default: "dist")-D, --dev: Add as devDependency (forinitwhen adding to package.json)-f, --force: Suppress mismatch warnings ininit-H, --github <repo>: GitHub repo (auto-detected from package.json if not specified)-I, --no-install: Skip runningpnpm installafter changes-l, --local <path>: Local path (forinitwith URL, orsetcommand)-L, --gitlab <repo>: GitLab repo (auto-detected from package.json if not specified)-n, --dry-run: Show what would be installed without making changes (forgh/gl/g/npm)-r, --ref <ref>: Git ref, resolved to SHA (forgithub/gitlabcommands)-R, --raw-ref <ref>: Git ref, used as-is (pin to branch/tag name)-v, --verbose: Show available remote versions (forlist)
Global CLI tools
For managing globally-installed CLI tools, use -g before the command:
# Initialize a global CLI tool
pds -g init /path/to/local/cli -H github-user/repo
# List global deps
pds -g ls
pds -g # shorthand for pds -g ls
# Switch global install source
pds -g gh # Install from GitHub dist branch
pds -g l # Install from local directory
pds -g n # Install from NPMGlobal config is stored at ~/.config/pnpm-dep-source/config.json.
Recommended workflow
- Local development: Use
pds local <dep>to develop against a local copy - Integration testing: Push to GitHub/GitLab, build a dist branch, use
pds gh <dep>orpds gl <dep>to test - Release: Publish to NPM, switch consumers to
pds npm <dep>
Setting up a dist branch
Add a workflow to your library that builds and pushes to a dist branch:
# .github/workflows/build-dist.yml
name: Build dist branch
on:
workflow_dispatch:
inputs:
src:
description: 'Source ref to build from'
required: false
dst:
description: 'Dist branch name (default: dist)'
required: false
jobs:
build-dist:
uses: runsascoded/npm-dist/.github/workflows/build-dist.yml@v1
with:
source_ref: ${{ inputs.src }}
dist_branch: ${{ inputs.dst }}See npm-dist for more options.
Requirements
Self-hosting
pds can manage itself! Clone the repo and use the global (-g) commands to switch between local development, dist branch testing, and NPM releases:
# Clone and initialize
git clone https://github.com/runsascoded/pnpm-dep-source.git
cd pnpm-dep-source
pnpm install && pnpm build
# Register pds as its own global dependency
pds -g init .
# Develop locally
pds -g l # installs from local ./dist
# Test dist branch
pds -g gh # installs from GitHub dist branch
# Use NPM release
pds -g n # installs from NPMLicense
MIT
