
Sandbox Npm Install
Install Node dependencies on local ext4 in GitHub Copilot sandboxes and symlink into the workspace so native npm binaries do not crash on virtiofs.
Overview
Sandbox npm Install is an agent skill for the Build phase that installs npm dependencies on local ext4 and symlinks them into a Copilot sandbox workspace.
Install
npx skills add https://github.com/github/awesome-copilot --skill sandbox-npm-installWhat is this skill?
- Bash installer resolves repo root and optional `--workspace` client with package.json
- Installs node_modules under configurable local ext4 base default `/home/agent/project-deps`
- Symlinks dependencies into the workspace to avoid virtiofs native binary crashes
- Optional `--playwright` flag to install Chromium for browser tests
- Includes `--help` usage and validation when workspace path is missing
Adoption & trust: 1.5k installs on skills.sh; 34.6k GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent sandbox npm install works on paper but native binaries crash because node_modules sits on virtiofs.
Who is it for?
Solo builders using GitHub Copilot sandboxes with monorepos or client apps that depend on native npm packages.
Skip if: Local laptops with normal ext4 project trees where a plain `npm install` already succeeds without symlink tricks.
When should I use this skill?
Before npm-based dev, build, or test in a Copilot sandbox when native modules fail on virtiofs-mounted node_modules.
What do I get? / Deliverables
node_modules is populated on ext4, linked into the client workspace, and optional Playwright Chromium is ready for the next dev or test command.
- Populated node_modules on local ext4 with symlink into workspace
- Optional Playwright Chromium browser install
Recommended Skills
Journey fit
The script exists to make agent sandboxes reliably run npm-based apps during development, which is core build-time agent tooling. It targets Copilot sandbox filesystem quirks (esbuild, lightningcss, rollup) rather than production deploy or SEO work.
How it compares
Use this sandbox-specific installer instead of asking the agent to repeatedly retry bare npm install on virtiofs mounts.
Common Questions / FAQ
Who is sandbox-npm-install for?
Developers and agent operators running npm projects inside GitHub Copilot sandboxes that hit esbuild or rollup crashes on virtiofs.
When should I use sandbox-npm-install?
Use it in Build agent-tooling at the start of a sandbox session before `npm run dev`, `npm test`, or Playwright runs, passing `--workspace` when package.json lives in a client subfolder.
Is sandbox-npm-install safe to install?
It runs shell installs and writes under `/home/agent/project-deps`; review the Security Audits panel on this page and adjust DEPS_BASE if your sandbox policy differs.
SKILL.md
READMESKILL.md - Sandbox Npm Install
#!/usr/bin/env bash set -euo pipefail # Sandbox npm Install Script # Installs node_modules on local ext4 filesystem and symlinks into the workspace. # This avoids native binary crashes (esbuild, lightningcss, rollup) on virtiofs. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" # Local ext4 base directory where node_modules is installed to avoid virtiofs crashes. # Change this path if your sandbox uses a different local filesystem location. readonly DEPS_BASE="/home/agent/project-deps" WORKSPACE_CLIENT="" INSTALL_PLAYWRIGHT="false" usage() { cat <<EOF Usage: $(basename "$0") [options] Options: --workspace <path> Client workspace containing package.json --playwright Install Playwright Chromium browser --help Show this help message Examples: bash scripts/install.sh bash scripts/install.sh --workspace app/client --playwright EOF } while [[ $# -gt 0 ]]; do case "$1" in --workspace) if [[ -z "${2:-}" ]]; then echo "Error: --workspace requires a path argument" usage exit 1 fi WORKSPACE_CLIENT="$2" shift 2 ;; --playwright) INSTALL_PLAYWRIGHT="true" shift ;; --help|-h) usage exit 0 ;; *) echo "Unknown option: $1" usage exit 1 ;; esac done if [[ -z "$WORKSPACE_CLIENT" ]]; then if [[ -f "$PWD/package.json" ]]; then WORKSPACE_CLIENT="$PWD" elif [[ -f "$REPO_ROOT/package.json" ]]; then WORKSPACE_CLIENT="$REPO_ROOT" fi fi if [[ -n "$WORKSPACE_CLIENT" ]]; then WORKSPACE_CLIENT="$(cd "$WORKSPACE_CLIENT" 2>/dev/null && pwd || true)" fi if [[ -z "$WORKSPACE_CLIENT" || ! -f "$WORKSPACE_CLIENT/package.json" ]]; then echo "Could not find a valid workspace client path containing package.json." echo "Use --workspace <path> to specify it explicitly." exit 1 fi echo "=== Sandbox npm Install ===" echo "Workspace: $WORKSPACE_CLIENT" # Derive a unique subdirectory from the workspace path relative to the repo root. # e.g. /repo/apps/web -> apps-web, /repo -> <repo-basename> REL_PATH="${WORKSPACE_CLIENT#"$REPO_ROOT"}" REL_PATH="${REL_PATH#/}" if [[ -z "$REL_PATH" ]]; then REL_PATH="$(basename "$REPO_ROOT")" fi # Sanitize: replace path separators with hyphens DEPS_SUBDIR="${REL_PATH//\//-}" DEPS_DIR="${DEPS_BASE}/${DEPS_SUBDIR}" echo "Deps dir: $DEPS_DIR" # Step 1: Prepare local deps directory echo "→ Preparing $DEPS_DIR..." if [[ -z "$DEPS_DIR" || "$DEPS_DIR" != "${DEPS_BASE}/"* ]]; then echo "ERROR: DEPS_DIR ('$DEPS_DIR') is not under DEPS_BASE ('$DEPS_BASE'). Aborting." exit 1 fi rm -rf "$DEPS_DIR" mkdir -p "$DEPS_DIR" chmod 700 "$DEPS_DIR" cp "$WORKSPACE_CLIENT/package.json" "$DEPS_DIR/" # Copy .npmrc if present (needed for private registries / scoped packages) # Permissions restricted to owner-only since .npmrc may contain auth tokens if [[ -f "$WORKSPACE_CLIENT/.npmrc" ]]; then cp "$WORKSPACE_CLIENT/.npmrc" "$DEPS_DIR/" chmod 600 "$DEPS_DIR/.npmrc" fi if [[ -f "$WORKSPACE_CLIENT/package-lock.json" ]]; then cp "$WORKSPACE_CLIENT/package-lock.json" "$DEPS_DIR/" INSTALL_CMD=(npm ci) else echo "! package-lock.json not found; falling back to npm install" INSTALL_CMD=(npm install) fi # Step 2: Install on local ext4 echo "→ Running ${INSTALL_CMD[*]} on local ext4..." cd "$DEPS_DIR" && "${INSTALL_CMD[@]}" # Step 3: Symlink into workspace echo "→ Symlinking node_modules into workspace..." cd "$WORKSPACE_CLIENT" rm -rf node_modules ln -s "$DEPS_DIR/node_modules" node_modules has_dep() { local dep="$1" node -e " const pkg=require(process.argv[1]); const deps={...(pkg.dependencies||{}),...(pkg.devDependencies||{}),...(pkg.optionalDependencies||{})}; process.exit(deps[process.argv[2]] ? 0 : 1); " "$WORKSPACE_CLIENT/package.json" "$dep" } verify_one() { local label="$1" shift if "$@" >/dev/null 2>&1; then echo " ✓ $label OK" return 0 fi echo "