Skip to content

About

This is for the Javascript Package Delegator

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

javascript-package-delegator: A Universal JavaScript Package Manager CLI

Go CI License Latest Release

javascript-package-delegator (jpd) is a powerful and intuitive Command Line Interface (CLI) tool designed to streamline your workflow across various JavaScript package managers. Inspired by the simplicity of @antfu/ni, jpd automatically detects the package manager used in your project (npm, Yarn, pnpm, Bun, or Deno) based on existing lock files and configuration, then transparently delegates your commands to the appropriate tool.

This eliminates the need to remember different commands or continuously switch between package managers when collaborating in diverse teams or managing multiple projects. jpd provides a unified experience, allowing you to focus on development rather than toolchain nuances.

1. Features

jpd offers a comprehensive set of features to simplify your JavaScript development experience:

  • Automatic Package Manager Detection: Intelligently identifies the active package manager by checking for package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb, deno.json, deno.jsonc, or deno.lock.

  • Unified Command Set: Provides a consistent API for common package management tasks, regardless of the underlying tool:

    • jpd install (i, add):** Installs project dependencies.

    • jpd run (r):** Executes scripts defined in package.json or tasks in deno.json.

    • jpd exec (x):** Executes packages (e.g., npx, yarn dlx, pnpm dlx, bunx).

    • jpd create (c):** Scaffolds new projects using create runners (supports package names for npm/pnpm/yarn/bun and URLs for deno).

    • jpd update (u, up, upgrade):** Updates installed packages to their latest compatible versions.

    • jpd uninstall (un, remove, rm):** Removes specified packages from your project.

    • jpd clean-install (ci):** Performs a clean installation with a frozen lockfile, ideal for CI/CD environments and production builds.

    • jpd agent (a):** Displays the detected package manager for the current project.

  • Intelligent Yarn Version Handling: Differentiates between Yarn v1 and Yarn v2+ for clean-install and exec commands, applying the correct flags (--frozen-lockfile vs. --immutable / yarn vs. yarn dlx).

  • Interactive Package Installation (-s, --search): Provides an interactive interface for users to search for packages on the npm registry and select which ones to install.

  • Interactive Script/Task Selection: When jpd run is executed without arguments, jpd displays an interactive list of available scripts from package.json (or tasks from deno.json) for you to choose from.

  • Interactive Uninstall: Use jpd uninstall without arguments or with the -i flag to interactively select and remove dependencies from your project.

  • Automatic Package Manager Installation Prompt: If jpd detects a lock file for a specific package manager (e.g., yarn.lock) but that package manager is not installed on your system, jpd will now interactively prompt you to provide a command to install it globally, ensuring you can quickly get started without manual setup.

  • Flexible Agent Selection: Override automatic detection using the --agent (-a) flag or the JPD_AGENT environment variable to explicitly specify your preferred package manager for a command or session.

  • Change Directory Execution: Use the --cwd (-C) flag to execute any jpd command within a specified directory without changing your current shell’s working directory. This is particularly useful for running commands in sub-projects or remote locations without manually navigating. Note: paths provided to --cwd must end with a trailing / (e.g., /path/to/project/) unless the path is the root /. In CI builds that set the CI build flag via -ldflags, the trailing slash requirement is relaxed and both path and path/ are accepted.

  • Comprehensive Shell Completion: jpd provides scripts to enable tab-completion for its commands and flags in popular shells, including Bash, Zsh, Fish, PowerShell, and Nushell.

  • External Integrations: Generate Warp terminal workflows and Carapace completion specs with the integrate command. See Integrations section.

  • Volta Integration: Automatically uses Volta to run Node.js package manager commands if Volta is detected on your system, ensuring the correct Node.js version (as defined by Volta) is used.

  • Debugging Capabilities: Enable a debug mode (--debug or -d) to view verbose logging, aiding in troubleshooting and understanding command execution.

  • Go-based Performance: Written in Go, jpd is compiled into a single static binary, offering fast execution and easy distribution without runtime dependencies.

2. Installation

jpd is distributed as a single binary and can be installed via popular package managers or by downloading the binary directly.

# Via Homebrew (macOS/Linux)
brew install louiss0/tap/jpd

# Via Scoop (Windows)
scoop bucket add louiss0 https://github.com/louiss0/scoop-bucket.git
scoop install jpd

# Via Winget (Windows)
winget install jpd

# Via Chocolatey (Windows)
choco install jpd

# Via Nix (Linux/macOS)
nix profile install github:nix-community/nur#repos.the-code-fixer-23-nur.jpd

# Manual Installation (Cross-platform)
# Download the appropriate binary for your OS from the
# https://github.com/louiss0/javascript-package-delegator/releases[releases page]
# and place it in your system's PATH.

3. Usage

Note

jpd create flags and flag passing:

  • --search, -s: Search npm for popular create-* packages and pick interactively.

  • --size <n>: Number of results to show when using --search (default: 25).

  • Passing flags to scaffolding tools:

  • npm: jpd auto-inserts --; do not add your own. If you do, jpd normalizes it.

  • pnpm / yarn v2+ / bun: pass flags directly after your app name.

  • yarn v1: uses npx; pass flags directly.

  • deno: pass arguments directly after the URL.

Example (npm):

jpd create vite@latest my-app -- --template react
# executes: npm exec create-vite@latest -- my-app --template react

3.1. CI build flag behavior

In Continuous Integration (CI) builds, you can toggle a build-time flag to relax the --cwd folder path trailing-slash validation. By default (local builds), --cwd values must end with / (except the root /). In CI mode, both path and path/ are accepted.

How to build in CI mode (relaxed --cwd):

# Tests
go test -ldflags "-X github.com/louiss0/javascript-package-delegator/build_info.rawCI=true" ./...

# Build
go build -ldflags "-X github.com/louiss0/javascript-package-delegator/build_info.rawCI=true" -o jpd ./...

Notes: - CI mode is controlled only via -ldflags (no environment detection). - The relaxation applies only to the --cwd folder path flag; other validations are unchanged.

Once installed, you can use jpd in place of your usual package manager commands.

3.2. General Usage

To see all available commands and global flags:

jpd --help

To run a command:

jpd <command> [arguments...] [flags...]

For command-specific help:

jpd <command> --help

3.3. Commands at a Glance

A compact overview of jpd commands. For detailed usage, flags, and examples, see the complete command reference.

Install and run basics:
  • jpd install - Install dependencies

  • jpd run dev - Run script/task

Package execution:
  • jpd exec create-react-app my-app - Execute packages

  • jpd dlx create-react-app my-app - Execute packages with dedicated package runner

Project scaffolding:
Maintenance:
  • jpd update - Update packages

  • jpd uninstall lodash - Remove packages

  • jpd clean-install - Clean install (CI/CD)

Agent:
  • jpd agent - Show detected package manager

Integrations (see docs for full details):
  • jpd integrate warp --output-dir ./workflows/ - Generate Warp workflow files

  • jpd integrate warp - Print workflows as multi-doc YAML

  • jpd integrate carapace nushell --output ~/.config/nushell/completions/jpd.nu - Generate Nushell Carapace setup

3.4. Integrations

Generate external tool integrations with the integrate command:

# Warp workflows
jpd integrate warp --output-dir ./workflows/
jpd integrate warp  # print multi-doc YAML to stdout
# Carapace setup for Nushell users
jpd integrate carapace nushell --output ~/.config/nushell/completions/jpd.nu

For flags, precedence rules, and OS paths, see the Integrate command reference.

For developers maintaining shell setup docs: prefer jpd integrate carapace nushell for Nushell users, write the file to ~/.config/nushell/completions/, and tell users to source it from env.nu.

4. Configuring automatic installation of JavaScript package managers

If a detected JavaScript package manager is not found a suitable installation command will be asked from you in an interative prompt. Once that happens the value will be stored in a file

5. Contributing

NOTE: .This project is developed using a Test-Driven Development (TDD) approach. To run the test suite, use the ginkgo test runner:

ginkgo run

To watch files for changes and re-run tests automatically:

ginkgo watch

To validate behaviors related to --cwd path validation in CI mode, run tests with the CI build flag:

go test ./... -race -coverprofile=coverage.out -ldflags "-X github.com/louiss0/javascript-package-delegator/build_info.rawCI=true"

6. Project Structure

The project follows a modular structure to ensure maintainability and testability:

├── cmd
│   ├── agent.go        // 'agent' command logic
│   ├── clean-install.go// 'clean-install' command logic
│   ├── completion.go   // 'completion' command logic, including all shell completions
│   ├── create.go       // 'create' command logic (project scaffolding)
│   ├── dlx.go          // 'dlx' command logic (dedicated package runner)
│   ├── exec.go         // 'exec' command logic
│   ├── install.go      // 'install' command logic
│   ├── integrate.go    // 'integrate' command logic (warp)
│   ├── root.go         // Main Cobra root command setup and persistent logic
│   ├── run.go          // 'run' command logic
│   ├── uninstall.go    // 'uninstall' command logic
│   └── update.go       // 'update' command logic
├── cmd/assets          // Contains embedded assets for commands (e.g., Nushell completion script)
│   └── jpd-extern.nu
├── custom_errors       // Custom error definitions
│   └── root.go
├── custom_flags        // Custom Cobra flags for common use cases, including path validation
│   └── root.go
├── detect              // Package manager detection logic, including file system and path lookup abstractions for testability
│   └── root.go
├── env                 // Environment-related utilities (e.g., Go environment checks)
│   └── root.go
├── internal            // Integration helpers and embedded completion assets
├── jpd-test            // Test utilities and helpers
├── ni                  // (Potentially deprecated or internal alias related to `ni` inspiration)
├── scripts             // Development and CI scripts for testing and cleanup
│   ├── check-coverage.sh // Coverage threshold checking with auto-cleanup
│   └── cleanup.sh       // Clean up test artifacts and accidentally generated binaries
├── LICENSE
├── README.adoc         // This documentation file
├── cmd_test.go         // Tests for commands in `cmd` package
├── coverprofile.out    // Go test coverage output
├── default.nix         // Nix package configuration
├── detect_test.go      // Tests for `detect` package
├── go.mod              // Go module definition
├── go.sum              // Go module checksums
├── goreleaser.yaml     // GoReleaser configuration for releases
├── javascript-package-delegator_suite_test.go // Ginkgo test suite setup
└── main.go             // Entry point of the application
  • The cmd package contains the implementation for all jpd commands, organized into separate files for clarity.

  • cmd/assets is a new directory storing assets embedded directly with their Go code.

  • custom_errors is designed for creating named, reusable error types.

  • custom_flags provides generic flag definitions for Cobra commands, now including robust path validation.

  • The detect package encapsulates the logic for identifying the JavaScript package manager in a project, now with improved testability via injected file system and path lookup interfaces.

  • The env package contains environment-related utilities, potentially including checks for production/development modes.

7. Tools and Libraries Used

jpd is built using robust Go libraries and tools:

Type Name Description

CLI Framework

spf13/cobra

A library for creating powerful modern CLI applications.

Logging

charmbracelet/log

A structured, colorful logger for the terminal.

Interactive UI

charmbracelet/huh

A library for building interactive prompts and forms in the terminal.

Utilities

samber/lo

A Lodash-style Go library for collections and common helpers.

Environment Loading

joho/godotenv

Loads environment variables from .env files.

Testing Framework

onsi/ginkgo

A BDD-style testing framework for Go.

Assertion Library

testify/assert

A Go testing framework with useful assertions and mocks.

Release Automation

goreleaser/goreleaser

Automates the entire Go project release cycle.

UI Styling

charmbracelet/lipgloss

Style definitions for nice terminal layouts.

8. Contributing

We welcome contributions to javascript-package-delegator! If you’re interested in contributing, please read our CONTRIBUTING.md (to be created) for guidelines on how to submit issues, features, and pull requests.

8.1. Writing Commands

When creating a new command for jpd, please follow these steps:

  1. Create a New File: In the cmd directory, create a new Go file named after your command (e.g., mycommand.go).

  2. Define New{CommandName}Cmd Function: Inside the new file, create a public function New{CommandName}Cmd() that returns a *cobra.Command instance. This function should contain the command’s Use, Short, Long descriptions, Aliases (if any), Args validation, and the RunE or PersistentPreRunE logic.

  3. Register Command in root.go: In the init() function of javascript-package-delegator/cmd/root.go, add your new command to the rootCmd using cmd.AddCommand(New{CommandName}Cmd()).

  4. Implement Flags and Arguments: Define any command-specific flags or arguments within your New{CommandName}Cmd function. Ensure proper type and default value handling.

  5. Write Tests: Create corresponding tests for your new command in the javascript-package-delegator_suite_test.go file (or a dedicated test file if the command is complex), leveraging ginkgo and testify/assert.

Tip
Use cobra-cli add <command-name> as a starting point to generate the basic command structure.
Note
Remember to always add appropriate arguments and flags to your commands and handle them robustly.
Caution
Ginkgo runs tests in parallel by default. Be mindful of shared state in tests.

9. License

This project is licensed under the MIT License. See the LICENSE file for details.

About

This is for the Javascript Package Delegator

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages