diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml
index 558a1445a..869b94c30 100644
--- a/.github/workflows/benchmark.yaml
+++ b/.github/workflows/benchmark.yaml
@@ -132,6 +132,8 @@ jobs:
VLT_REGISTRY_AUTH_TOKEN: ${{ secrets.VLT_REGISTRY_AUTH_TOKEN }}
CLOUDSMITH_REGISTRY: ${{ secrets.CLOUDSMITH_REGISTRY }}
CLOUDSMITH_AUTH_TOKEN: ${{ secrets.CLOUDSMITH_AUTH_TOKEN }}
+ GH_REGISTRY: ${{ secrets.GH_REGISTRY }}
+ GH_AUTH_TOKEN: ${{ secrets.GH_AUTH_TOKEN }}
run: |
./bench run \
--fixtures="${{ matrix.fixture }}" \
diff --git a/app/src/components/header.tsx b/app/src/components/header.tsx
index ac14b9c79..a688b59e0 100644
--- a/app/src/components/header.tsx
+++ b/app/src/components/header.tsx
@@ -289,7 +289,7 @@ const LeaderBoardItem = ({
{Icon && (
)}
diff --git a/app/src/components/icons/github.tsx b/app/src/components/icons/github.tsx
new file mode 100644
index 000000000..f8f33d228
--- /dev/null
+++ b/app/src/components/icons/github.tsx
@@ -0,0 +1,13 @@
+import { createLucideIcon } from "lucide-react";
+
+export const Github = createLucideIcon("Github", [
+ [
+ "path",
+ {
+ d: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12",
+ fill: "currentColor",
+ key: "1",
+ strokeWidth: "0",
+ },
+ ],
+]);
diff --git a/app/src/components/icons/index.ts b/app/src/components/icons/index.ts
index fcfbfd242..9a4575731 100644
--- a/app/src/components/icons/index.ts
+++ b/app/src/components/icons/index.ts
@@ -13,6 +13,7 @@ export * from "./bar-chart.tsx";
// ecosystem icons
export * from "./astro.tsx";
export * from "./aws.tsx";
+export * from "./github.tsx";
export * from "./berry.tsx";
export * from "./bun.tsx";
export * from "./cloudsmith.tsx";
diff --git a/app/src/hooks/use-history-data.ts b/app/src/hooks/use-history-data.ts
index 722ef7522..21f9d822e 100644
--- a/app/src/hooks/use-history-data.ts
+++ b/app/src/hooks/use-history-data.ts
@@ -21,6 +21,7 @@ const PACKAGE_MANAGERS = [
"node",
"aws",
"cloudsmith",
+ "github",
];
interface UseHistoryDataReturn {
diff --git a/app/src/lib/get-icons.ts b/app/src/lib/get-icons.ts
index 844a3f040..d987fbab8 100644
--- a/app/src/lib/get-icons.ts
+++ b/app/src/lib/get-icons.ts
@@ -6,6 +6,7 @@ import {
Bun,
Cloudsmith,
Deno,
+ Github,
Next,
Node,
Npm,
@@ -26,6 +27,7 @@ const packageManagerMap: Partial> = {
aws: Aws,
bun: Bun,
cloudsmith: Cloudsmith,
+ github: Github,
deno: Deno,
node: Node,
npm: Npm,
diff --git a/app/src/lib/utils.ts b/app/src/lib/utils.ts
index c977eb0fe..44d84b7c5 100644
--- a/app/src/lib/utils.ts
+++ b/app/src/lib/utils.ts
@@ -466,12 +466,14 @@ export function getPackageManagerDisplayName(
if (packageManager === "aws")
return "codeartifact.us-east-1.amazonaws.com";
if (packageManager === "cloudsmith") return "npm.cloudsmith.io";
+ if (packageManager === "github") return "npm.pkg.github.com";
}
if (packageManager === "berry") return "yarn (berry)";
if (packageManager === "zpm") return "yarn (zpm)";
if (packageManager === "turbo") return "turborepo";
if (packageManager === "aws") return "AWS CodeArtifact";
if (packageManager === "cloudsmith") return "Cloudsmith";
+ if (packageManager === "github") return "GitHub";
return packageManager;
}
diff --git a/app/src/types/chart-data.ts b/app/src/types/chart-data.ts
index 99718c5c8..8fefe427c 100644
--- a/app/src/types/chart-data.ts
+++ b/app/src/types/chart-data.ts
@@ -11,7 +11,8 @@ export type PackageManager =
| "turbo"
| "node"
| "aws"
- | "cloudsmith";
+ | "cloudsmith"
+ | "github";
export type Fixture =
| "next"
@@ -52,6 +53,7 @@ export interface PackageManagerVersions {
node?: string;
aws?: string;
cloudsmith?: string;
+ github?: string;
}
export interface BaseFixtureResult {
@@ -72,6 +74,7 @@ export interface PackageManagerData {
node?: number;
aws?: number;
cloudsmith?: number;
+ github?: number;
npm_stddev?: number;
yarn_stddev?: number;
@@ -86,6 +89,7 @@ export interface PackageManagerData {
node_stddev?: number;
aws_stddev?: number;
cloudsmith_stddev?: number;
+ github_stddev?: number;
npm_fill?: string;
yarn_fill?: string;
@@ -100,6 +104,7 @@ export interface PackageManagerData {
node_fill?: string;
aws_fill?: string;
cloudsmith_fill?: string;
+ github_fill?: string;
npm_count?: number;
yarn_count?: number;
@@ -114,6 +119,7 @@ export interface PackageManagerData {
node_count?: number;
aws_count?: number;
cloudsmith_count?: number;
+ github_count?: number;
npm_dnf?: boolean;
yarn_dnf?: boolean;
@@ -128,6 +134,7 @@ export interface PackageManagerData {
node_dnf?: boolean;
aws_dnf?: boolean;
cloudsmith_dnf?: boolean;
+ github_dnf?: boolean;
}
export type FixtureResult = BaseFixtureResult & PackageManagerData;
@@ -167,6 +174,7 @@ export interface PackageCountData {
node?: PackageCountEntry;
aws?: PackageCountEntry;
cloudsmith?: PackageCountEntry;
+ github?: PackageCountEntry;
}
export interface PackageCountTableRow {
diff --git a/bench b/bench
index 933cf5e39..735a02f08 100755
--- a/bench
+++ b/bench
@@ -43,6 +43,7 @@ AVAILABLE_REGISTRIES=(
vlt
aws
cloudsmith
+ github
)
usage() {
@@ -56,7 +57,7 @@ Usage:
Options:
--fixtures Comma or space-separated fixture names (default: next)
--pms Comma or space-separated package managers (default: all)
- --registries Comma-separated registries for registry-* variations (default: npm,vlt,aws,cloudsmith)
+ --registries Comma-separated registries for registry-* variations (default: npm,vlt,aws,cloudsmith,github)
--variation Comma or space-separated benchmark variations (default: clean)
--runs Hyperfine runs (default: scripts/variations/common.sh default)
--warmup Hyperfine warmup runs (default: scripts/variations/common.sh default)
@@ -78,6 +79,7 @@ Examples:
./bench run --variation=registry-lockfile --registries=npm,vlt
CODEARTIFACT_AUTH_TOKEN= ./bench run --variation=registry-clean --fixtures=next --registries=aws
CLOUDSMITH_REGISTRY= CLOUDSMITH_AUTH_TOKEN= ./bench run --variation=registry-clean --fixtures=next --registries=cloudsmith
+ GH_REGISTRY= GH_AUTH_TOKEN= ./bench run --variation=registry-clean --fixtures=next --registries=github
./bench chart --fixtures=next --variation=clean
./bench process
EOF
@@ -448,7 +450,7 @@ run_bench() {
if [[ -n "$registries_env" ]]; then
echo " registries: $registries_env"
else
- echo " registries: npm,vlt,aws,cloudsmith (default)"
+ echo " registries: npm,vlt,aws,cloudsmith,github (default)"
fi
fi
diff --git a/scripts/generate-chart.js b/scripts/generate-chart.js
index 22d171729..d95660122 100644
--- a/scripts/generate-chart.js
+++ b/scripts/generate-chart.js
@@ -40,6 +40,7 @@ const REGISTRY_COLORS = {
vlt: "#000000",
aws: "#ff9900",
cloudsmith: "#2a6fe1",
+ github: "#6336b8",
};
const parseNumeric = (value) => {
diff --git a/scripts/registry/common.sh b/scripts/registry/common.sh
index c1283ea92..e97aeae1a 100644
--- a/scripts/registry/common.sh
+++ b/scripts/registry/common.sh
@@ -68,6 +68,11 @@ BENCH_REGISTRY_AWS_NPMRC_KEY="${BENCH_REGISTRY_AWS_URL#http*://}"
# The auth .npmrc key uses the URL as-is (without protocol).
BENCH_REGISTRY_CLOUDSMITH_URL="https:${CLOUDSMITH_REGISTRY:-}"
BENCH_REGISTRY_CLOUDSMITH_NPMRC_KEY="${CLOUDSMITH_REGISTRY#//}"
+# GitHub registry URL is injected without the protocol prefix
+# (e.g. "//npm.pkg.github.com/..."), so we prepend "https:" for the registry config.
+# The auth .npmrc key uses the URL as-is (without protocol).
+BENCH_REGISTRY_GITHUB_URL="https:${GH_REGISTRY:-}"
+BENCH_REGISTRY_GITHUB_NPMRC_KEY="${GH_REGISTRY#//}"
# Registry setup commands run in hyperfine --prepare (untimed, before each run).
# Auth token is written as a literal placeholder so npm resolves it from env.
@@ -81,6 +86,7 @@ BENCH_SETUP_REGISTRY_NPM="npm config set registry \"$BENCH_REGISTRY_NPM_URL\" --
BENCH_SETUP_REGISTRY_VLT="npm config set registry \"$BENCH_REGISTRY_VLT_URL\" --location=project && npm config set \"//${BENCH_REGISTRY_VLT_URL_NPMRC_KEY}:_authToken=\\\${VLT_REGISTRY_AUTH_TOKEN}:$(head -c 16 /dev/urandom | xxd -p)_\\\${HYPERFINE_ITERATION}\" --location=project"
BENCH_SETUP_REGISTRY_AWS="npm config set registry \"$BENCH_REGISTRY_AWS_URL\" --location=project && npm config set \"//${BENCH_REGISTRY_AWS_NPMRC_KEY}:_authToken=\\\${CODEARTIFACT_AUTH_TOKEN}\" --location=project"
BENCH_SETUP_REGISTRY_CLOUDSMITH="npm config set registry \"$BENCH_REGISTRY_CLOUDSMITH_URL\" --location=project && npm config set \"//${BENCH_REGISTRY_CLOUDSMITH_NPMRC_KEY}:_authToken=\\\${CLOUDSMITH_AUTH_TOKEN}\" --location=project"
+BENCH_SETUP_REGISTRY_GITHUB="npm config set registry \"$BENCH_REGISTRY_GITHUB_URL\" --location=project && npm config set \"//${BENCH_REGISTRY_GITHUB_NPMRC_KEY}:_authToken=\\\${GH_AUTH_TOKEN}\" --location=project"
# Registry verification helper runs in hyperfine --conclude (untimed, after each run).
BENCH_VERIFY_REGISTRY="npm config get registry && ((grep -m3 '\"resolved\"' package-lock.json 2>/dev/null | sed 's/^[[:space:]]*//') || echo 'no lockfile yet') && echo ''"
@@ -90,23 +96,26 @@ BENCH_CONCLUDE_NPM="{ $BENCH_VERIFY_REGISTRY; } >> $BENCH_OUTPUT_FOLDER/npm-veri
BENCH_CONCLUDE_VLT_REG="{ $BENCH_VERIFY_REGISTRY; } >> $BENCH_OUTPUT_FOLDER/vlt-verify.log 2>&1"
BENCH_CONCLUDE_AWS="{ $BENCH_VERIFY_REGISTRY; } >> $BENCH_OUTPUT_FOLDER/aws-verify.log 2>&1"
BENCH_CONCLUDE_CLOUDSMITH="{ $BENCH_VERIFY_REGISTRY; } >> $BENCH_OUTPUT_FOLDER/cloudsmith-verify.log 2>&1"
+BENCH_CONCLUDE_GITHUB="{ $BENCH_VERIFY_REGISTRY; } >> $BENCH_OUTPUT_FOLDER/github-verify.log 2>&1"
# Registry commands are timed and should only run installs.
BENCH_COMMAND_NPM="$BENCH_NPM_INSTALL >> $BENCH_OUTPUT_FOLDER/npm-output-\${HYPERFINE_ITERATION}.log 2>&1"
BENCH_COMMAND_VLT_REG="$BENCH_NPM_INSTALL >> $BENCH_OUTPUT_FOLDER/vlt-output-\${HYPERFINE_ITERATION}.log 2>&1"
BENCH_COMMAND_AWS="$BENCH_NPM_INSTALL >> $BENCH_OUTPUT_FOLDER/aws-output-\${HYPERFINE_ITERATION}.log 2>&1"
BENCH_COMMAND_CLOUDSMITH="$BENCH_NPM_INSTALL >> $BENCH_OUTPUT_FOLDER/cloudsmith-output-\${HYPERFINE_ITERATION}.log 2>&1"
+BENCH_COMMAND_GITHUB="$BENCH_NPM_INSTALL >> $BENCH_OUTPUT_FOLDER/github-output-\${HYPERFINE_ITERATION}.log 2>&1"
# Registry include flags
# If BENCH_INCLUDE_REGISTRY is not set, default to running all registries.
if [ -z "${BENCH_INCLUDE_REGISTRY:-}" ]; then
- BENCH_INCLUDE_REGISTRY="npm,vlt,aws,cloudsmith"
+ BENCH_INCLUDE_REGISTRY="npm,vlt,aws,cloudsmith,github"
fi
BENCH_INCLUDE_REG_NPM=""
BENCH_INCLUDE_REG_VLT=""
BENCH_INCLUDE_REG_AWS=""
BENCH_INCLUDE_REG_CLOUDSMITH=""
+BENCH_INCLUDE_REG_GITHUB=""
for entry in $(echo "$BENCH_INCLUDE_REGISTRY" | tr ',' '\n'); do
case "$entry" in
@@ -115,6 +124,7 @@ for entry in $(echo "$BENCH_INCLUDE_REGISTRY" | tr ',' '\n'); do
vlt) BENCH_INCLUDE_REG_VLT=1 ;;
aws) BENCH_INCLUDE_REG_AWS=1 ;;
cloudsmith) BENCH_INCLUDE_REG_CLOUDSMITH=1 ;;
+ github) BENCH_INCLUDE_REG_GITHUB=1 ;;
*)
echo "Error: Unknown registry '$entry' in BENCH_INCLUDE_REGISTRY"
exit 1
@@ -142,6 +152,16 @@ if [ -n "$BENCH_INCLUDE_REG_CLOUDSMITH" ] && [ -z "${CLOUDSMITH_REGISTRY:-}" ];
exit 1
fi
+if [ -n "$BENCH_INCLUDE_REG_GITHUB" ] && [ -z "${GH_AUTH_TOKEN:-}" ]; then
+ echo "Error: 'github' registry was requested, but GH_AUTH_TOKEN is not set"
+ exit 1
+fi
+
+if [ -n "$BENCH_INCLUDE_REG_GITHUB" ] && [ -z "${GH_REGISTRY:-}" ]; then
+ echo "Error: 'github' registry was requested, but GH_REGISTRY is not set"
+ exit 1
+fi
+
echo "Registry benchmarks will run: $BENCH_INCLUDE_REGISTRY"
# Clean up & create the results directory
diff --git a/scripts/variations/registry-clean.sh b/scripts/variations/registry-clean.sh
index 035f537ef..a4c04eb17 100644
--- a/scripts/variations/registry-clean.sh
+++ b/scripts/variations/registry-clean.sh
@@ -28,4 +28,7 @@ hyperfine --ignore-failure \
${BENCH_INCLUDE_REG_AWS:+--conclude="$BENCH_CONCLUDE_AWS"} \
${BENCH_INCLUDE_REG_CLOUDSMITH:+--prepare="$BENCH_PREPARE_BASE && $BENCH_SETUP_REGISTRY_CLOUDSMITH"} \
${BENCH_INCLUDE_REG_CLOUDSMITH:+--command-name="cloudsmith" "$BENCH_COMMAND_CLOUDSMITH"} \
- ${BENCH_INCLUDE_REG_CLOUDSMITH:+--conclude="$BENCH_CONCLUDE_CLOUDSMITH"}
+ ${BENCH_INCLUDE_REG_CLOUDSMITH:+--conclude="$BENCH_CONCLUDE_CLOUDSMITH"} \
+ ${BENCH_INCLUDE_REG_GITHUB:+--prepare="$BENCH_PREPARE_BASE && $BENCH_SETUP_REGISTRY_GITHUB"} \
+ ${BENCH_INCLUDE_REG_GITHUB:+--command-name="github" "$BENCH_COMMAND_GITHUB"} \
+ ${BENCH_INCLUDE_REG_GITHUB:+--conclude="$BENCH_CONCLUDE_GITHUB"}
diff --git a/scripts/variations/registry-lockfile.sh b/scripts/variations/registry-lockfile.sh
index 04ddb5841..7d0557c96 100644
--- a/scripts/variations/registry-lockfile.sh
+++ b/scripts/variations/registry-lockfile.sh
@@ -29,4 +29,7 @@ hyperfine --ignore-failure \
${BENCH_INCLUDE_REG_AWS:+--conclude="$BENCH_CONCLUDE_AWS"} \
${BENCH_INCLUDE_REG_CLOUDSMITH:+--prepare="$BENCH_PREPARE_BASE && $BENCH_SETUP_REGISTRY_CLOUDSMITH"} \
${BENCH_INCLUDE_REG_CLOUDSMITH:+--command-name="cloudsmith" "$BENCH_COMMAND_CLOUDSMITH"} \
- ${BENCH_INCLUDE_REG_CLOUDSMITH:+--conclude="$BENCH_CONCLUDE_CLOUDSMITH"}
+ ${BENCH_INCLUDE_REG_CLOUDSMITH:+--conclude="$BENCH_CONCLUDE_CLOUDSMITH"} \
+ ${BENCH_INCLUDE_REG_GITHUB:+--prepare="$BENCH_PREPARE_BASE && $BENCH_SETUP_REGISTRY_GITHUB"} \
+ ${BENCH_INCLUDE_REG_GITHUB:+--command-name="github" "$BENCH_COMMAND_GITHUB"} \
+ ${BENCH_INCLUDE_REG_GITHUB:+--conclude="$BENCH_CONCLUDE_GITHUB"}