Skip to content

Instantly share code, notes, and snippets.

@danthegoodman1
Last active December 27, 2025 05:32
Show Gist options
  • Select an option

  • Save danthegoodman1/021678f0aac498d7d644a70609109655 to your computer and use it in GitHub Desktop.

Select an option

Save danthegoodman1/021678f0aac498d7d644a70609109655 to your computer and use it in GitHub Desktop.
NPM Vendor in a package to a `vendor/` subdir. Helps against supply chain attacks, and makes it easier for LLMs to learn how packages work. Opus 4.5 did most of the work.
#!/bin/bash
# Downloads an npm package and extracts it to the vendor directory
# Does NOT install to node_modules - this is an alternative to npm install
#
# Usage: ./scripts/vendor-package.sh <package-name>[@version]
#
# Examples:
# ./scripts/vendor-package.sh lodash
# ./scripts/vendor-package.sh lodash@4.17.20
# ./scripts/vendor-package.sh @tanstack/react-query@5.0.0
set -e
if [ -z "$1" ]; then
echo "Usage: $0 <package-name>[@version]"
echo "Examples:"
echo " $0 lodash"
echo " $0 lodash@4.17.20"
echo " $0 @tanstack/react-query@5.0.0"
exit 1
fi
FULL_SPEC="$1"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
VENDOR_DIR="$PROJECT_ROOT/vendor"
# Parse package name from spec like "lodash@4.17.20" or "@tanstack/react-query@5.0.0"
if [[ "$FULL_SPEC" =~ ^@ ]]; then
# Scoped package: @scope/name or @scope/name@version
SCOPE_AND_NAME="${FULL_SPEC#@}" # Remove leading @
if [[ "$SCOPE_AND_NAME" =~ ^([^/]+/[^@]+)(@.+)?$ ]]; then
PACKAGE_NAME="@${BASH_REMATCH[1]}"
else
PACKAGE_NAME="$FULL_SPEC"
fi
else
# Regular package: name or name@version
if [[ "$FULL_SPEC" =~ ^([^@]+)(@.+)?$ ]]; then
PACKAGE_NAME="${BASH_REMATCH[1]}"
else
PACKAGE_NAME="$FULL_SPEC"
fi
fi
# Handle scoped packages: @tanstack/react-query -> tanstack/react-query
VENDOR_SUBDIR="$VENDOR_DIR/${PACKAGE_NAME#@}"
# Create a temp directory for downloading
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
echo "Downloading $FULL_SPEC..."
# Use npm pack to download the tarball (works without installing)
cd "$TEMP_DIR"
TARBALL=$(npm pack "$FULL_SPEC" 2>/dev/null)
if [ ! -f "$TARBALL" ]; then
echo "Error: Failed to download package '$FULL_SPEC'"
exit 1
fi
# Extract the tarball (npm pack creates a 'package' directory inside)
tar -xzf "$TARBALL"
if [ ! -d "package" ]; then
echo "Error: Failed to extract package"
exit 1
fi
# Get the version from the extracted package.json
INSTALLED_VERSION=$(node -p "require('./package/package.json').version" 2>/dev/null || echo "unknown")
# Create vendor directory if it doesn't exist
mkdir -p "$VENDOR_DIR"
# Remove existing vendored copy if present
if [ -d "$VENDOR_SUBDIR" ]; then
echo "Removing existing vendored copy at $VENDOR_SUBDIR"
rm -rf "$VENDOR_SUBDIR"
fi
# Create parent directory for scoped packages
mkdir -p "$(dirname "$VENDOR_SUBDIR")"
# Move the extracted package to vendor
echo "Installing $PACKAGE_NAME@$INSTALLED_VERSION to $VENDOR_SUBDIR"
mv "$TEMP_DIR/package" "$VENDOR_SUBDIR"
echo ""
echo "Done! Vendored $PACKAGE_NAME@$INSTALLED_VERSION to: $VENDOR_SUBDIR"
echo ""
echo "You can now import it with:"
echo " import something from \"vendor/${PACKAGE_NAME#@}\""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment