{"_id":"bun-profiler","_rev":"7-9e7621176a6f22048b1189c52c70ee07","name":"bun-profiler","dist-tags":{"latest":"0.4.4"},"versions":{"0.2.0":{"name":"bun-profiler","version":"0.2.0","keywords":["bun","pyroscope","profiling","continuous-profiling","flamegraph","apm","observability","javascriptcore","jsc","grafana"],"author":{"url":"https://x.com/the_mewc","name":"mewc"},"license":"MIT","_id":"bun-profiler@0.2.0","maintainers":[{"name":"mewc771","email":"michael@drummerduck.com"}],"homepage":"https://github.com/mewc/bun-profiler#readme","bugs":{"url":"https://github.com/mewc/bun-profiler/issues"},"dist":{"shasum":"581281a323939869803dfc52f15919b413fc9065","tarball":"https://registry.npmjs.org/bun-profiler/-/bun-profiler-0.2.0.tgz","fileCount":15,"integrity":"sha512-g8LZrwMdEyHLROZO5PsAcSWrgros6KD8o/bWKAp7XzJfGwVd0xpicq54FZg47e75fQKewYjRUgLy8eAUShNR/Q==","signatures":[{"sig":"MEYCIQCC6FzfzbodxFEz/q1jZ9MGuVi9KwRYrojPAs5WY1pFowIhAJ1SdkqdQMcmoWOeCQWwp4G4Cydy3M7j7mycO1nCPB5Z","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41646},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"bun":">=1.3.7"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"e3bfee8180441e3189d1aea0eb9585ef70067dc6","scripts":{"l":"bun run typecheck && bun run lint && bun test","lint":"biome check src test","test":"bun test","build":"bun run build:esm && bun run build:cjs && bun run build:types","smoke":"bun smoke-test.ts","lint:fix":"biome check --write src test","build:cjs":"bun build ./src/index.ts --outfile ./dist/index.cjs --format cjs --target node --external node:inspector --external node:os --external node:zlib --external node:util","build:esm":"bun build ./src/index.ts --outfile ./dist/index.js --format esm --target node --external node:inspector --external node:os --external node:zlib --external node:util","typecheck":"tsc --noEmit","build:types":"tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist","release:major":"npm version major && git push --follow-tags","release:minor":"npm version minor && git push --follow-tags","release:patch":"npm version patch && git push --follow-tags","prepublishOnly":"bun run build && bun run l"},"_npmUser":{"name":"mewc771","email":"michael@drummerduck.com"},"repository":{"url":"git+https://github.com/mewc/bun-profiler.git","type":"git"},"_npmVersion":"11.6.2","description":"Continuous CPU profiling for Bun (JavaScriptCore) via Pyroscope/Grafana ingest — zero native dependencies","directories":{},"_nodeVersion":"24.2.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^25.3.0","@biomejs/biome":"^2.4.2"},"trustedDependencies":["@biomejs/biome"],"_npmOperationalInternal":{"tmp":"tmp/bun-profiler_0.2.0_1771469774046_0.14224543336382367","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"bun-profiler","version":"0.3.1","keywords":["bun","pyroscope","profiling","continuous-profiling","flamegraph","apm","observability","javascriptcore","jsc","grafana"],"author":{"url":"https://x.com/the_mewc","name":"mewc"},"license":"MIT","_id":"bun-profiler@0.3.1","maintainers":[{"name":"mewc771","email":"michael@drummerduck.com"}],"homepage":"https://github.com/mewc/bun-profiler#readme","bugs":{"url":"https://github.com/mewc/bun-profiler/issues"},"dist":{"shasum":"787901cb08e5c79742edd58ee27c9199302d2072","tarball":"https://registry.npmjs.org/bun-profiler/-/bun-profiler-0.3.1.tgz","fileCount":15,"integrity":"sha512-wWIxSbQNyWsmffwPMzNDDrQ9/FN0yjSbppSjFy/CuVb7lbFn2ASzY5iLWM6g8UCo6vsUsX/ByzK4N6rl+dKWcQ==","signatures":[{"sig":"MEUCIAn+FIWDMriqZdK/ucArwqCfODJlOsHsRMkyR0aqjZtAAiEAvMZakBAvlE0HeRNUgOPxF/bIsq6zYj4mttc/LEqsGDc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51162},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"bun":">=1.3.7"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"13a0dd0fd6e0cd87528aa2a3cba9bacdc1b8e721","scripts":{"l":"bun run typecheck && bun run lint && bun test","lint":"biome check src test","test":"bun test","build":"bun run build:esm && bun run build:cjs && bun run build:types","smoke":"bun smoke-test.ts","lint:fix":"biome check --write src test","build:cjs":"bun build ./src/index.ts --outfile ./dist/index.cjs --format cjs --target node --external node:inspector --external node:os --external node:zlib --external node:util","build:esm":"bun build ./src/index.ts --outfile ./dist/index.js --format esm --target node --external node:inspector --external node:os --external node:zlib --external node:util","typecheck":"tsc --noEmit","build:types":"tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist","release:major":"npm version major && git push --follow-tags","release:minor":"npm version minor && git push --follow-tags","release:patch":"npm version patch && git push --follow-tags","prepublishOnly":"bun run build && bun run l"},"_npmUser":{"name":"mewc771","email":"michael@drummerduck.com"},"repository":{"url":"git+https://github.com/mewc/bun-profiler.git","type":"git"},"_npmVersion":"11.6.2","description":"Continuous CPU profiling for Bun (JavaScriptCore) via Pyroscope/Grafana ingest — zero native dependencies","directories":{},"_nodeVersion":"24.2.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^25.3.0","@biomejs/biome":"^2.4.2"},"trustedDependencies":["@biomejs/biome"],"_npmOperationalInternal":{"tmp":"tmp/bun-profiler_0.3.1_1771709392084_0.17080223671948813","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"bun-profiler","version":"0.4.0","keywords":["bun","pyroscope","profiling","continuous-profiling","flamegraph","apm","observability","javascriptcore","jsc","grafana"],"author":{"url":"https://x.com/the_mewc","name":"mewc"},"license":"MIT","_id":"bun-profiler@0.4.0","maintainers":[{"name":"mewc771","email":"michael@drummerduck.com"}],"homepage":"https://github.com/mewc/bun-profiler#readme","bugs":{"url":"https://github.com/mewc/bun-profiler/issues"},"dist":{"shasum":"66de9ade0d5e92df9b42ddc6e99794eaf157d22c","tarball":"https://registry.npmjs.org/bun-profiler/-/bun-profiler-0.4.0.tgz","fileCount":15,"integrity":"sha512-YKZntpsqcbzLy2xwujTn9lWQIxsH3ILz5qkg1UWMoEWa+yQo4WQ3vWH6rVo0w5ZmYVpcLlFcKHhHXsDGRfisrg==","signatures":[{"sig":"MEQCIFwIMkBfrPb363w+HkjNrj8rQG2dJqghOUsHWbpy2uEsAiA/xe8AHfDCYkNf1Wu5XjjGw/IMcTaVQzMRLfKcxADwjg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":59903},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"bun":">=1.3.7"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"a3df3b82891d12dede2706b78d74e512e1b4a1c0","scripts":{"l":"bun run typecheck && bun run lint && bun test","lint":"biome check src test","test":"bun test","build":"bun run build:esm && bun run build:cjs && bun run build:types","smoke":"bun smoke-test.ts","lint:fix":"biome check --write src test","build:cjs":"bun build ./src/index.ts --outfile ./dist/index.cjs --format cjs --target node --external node:inspector --external node:os --external node:zlib --external node:util","build:esm":"bun build ./src/index.ts --outfile ./dist/index.js --format esm --target node --external node:inspector --external node:os --external node:zlib --external node:util","typecheck":"tsc --noEmit","build:types":"tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist","release:major":"npm version major && git push --follow-tags","release:minor":"npm version minor && git push --follow-tags","release:patch":"npm version patch && git push --follow-tags","prepublishOnly":"bun run build && bun run l"},"_npmUser":{"name":"mewc771","email":"michael@drummerduck.com"},"repository":{"url":"git+https://github.com/mewc/bun-profiler.git","type":"git"},"_npmVersion":"11.6.2","description":"Continuous CPU profiling for Bun (JavaScriptCore) via Pyroscope/Grafana ingest — zero native dependencies","directories":{},"_nodeVersion":"24.2.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^25.3.0","@biomejs/biome":"^2.4.2"},"trustedDependencies":["@biomejs/biome"],"_npmOperationalInternal":{"tmp":"tmp/bun-profiler_0.4.0_1771801396433_0.7324404265278608","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"bun-profiler","version":"0.4.1","keywords":["bun","pyroscope","profiling","continuous-profiling","flamegraph","apm","observability","javascriptcore","jsc","grafana"],"author":{"url":"https://x.com/the_mewc","name":"mewc"},"license":"MIT","_id":"bun-profiler@0.4.1","maintainers":[{"name":"mewc771","email":"michael@drummerduck.com"}],"homepage":"https://github.com/mewc/bun-profiler#readme","bugs":{"url":"https://github.com/mewc/bun-profiler/issues"},"dist":{"shasum":"c96fc2e3c182e950bafebebfa28c1fc936227a7a","tarball":"https://registry.npmjs.org/bun-profiler/-/bun-profiler-0.4.1.tgz","fileCount":15,"integrity":"sha512-bJ73B5i6mTBVKcQYMSLDnYoz9w2aB1WS2roUPp40Q1J3SGzQ7melXuIVFt0KP7AP7ZkYsNbP69JUb3kV6YvG9w==","signatures":[{"sig":"MEQCIGSOFGsHH8vP2PnGTwD0fBvxXT/SCXPuIsRbU9RmfjDPAiBW81a7ChLjEuMtO/F4m3JJm3NcErSSPPdVmzZEzD8nnw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62380},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"bun":">=1.3.7"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"9f8f2eb802fb0c7c07bc0bbbdd60292e828c6dc9","scripts":{"l":"bun run typecheck && bun run lint && bun test","dev":"cd dev && docker compose up --build -d && echo '\\n  App:        http://localhost:3002\\n  Pyroscope:   http://localhost:4042\\n  Grafana:     http://localhost:3003\\n  Prometheus:  http://localhost:9091\\n'","lint":"biome check src test","test":"bun test","build":"bun run build:esm && bun run build:cjs && bun run build:types","smoke":"bun smoke-test.ts","dev:down":"cd dev && docker compose down","dev:logs":"cd dev && docker compose logs -f app","lint:fix":"biome check --write src test","build:cjs":"bun build ./src/index.ts --outfile ./dist/index.cjs --format cjs --target node --external node:inspector --external node:os --external node:zlib --external node:util","build:esm":"bun build ./src/index.ts --outfile ./dist/index.js --format esm --target node --external node:inspector --external node:os --external node:zlib --external node:util","typecheck":"tsc --noEmit","build:types":"tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist","dev:restart":"cd dev && docker compose restart app","release:major":"npm version major && git push --follow-tags","release:minor":"npm version minor && git push --follow-tags","release:patch":"npm version patch && git push --follow-tags","prepublishOnly":"bun run build && bun run l"},"_npmUser":{"name":"mewc771","email":"michael@drummerduck.com"},"repository":{"url":"git+https://github.com/mewc/bun-profiler.git","type":"git"},"_npmVersion":"11.6.2","description":"Continuous CPU profiling for Bun (JavaScriptCore) via Pyroscope/Grafana ingest — zero native dependencies","directories":{},"_nodeVersion":"24.2.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^25.3.0","@biomejs/biome":"^2.4.2"},"trustedDependencies":["@biomejs/biome"],"_npmOperationalInternal":{"tmp":"tmp/bun-profiler_0.4.1_1771895420755_0.741482338361027","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"bun-profiler","version":"0.4.2","keywords":["bun","pyroscope","profiling","continuous-profiling","flamegraph","apm","observability","javascriptcore","jsc","grafana"],"author":{"url":"https://x.com/the_mewc","name":"mewc"},"license":"MIT","_id":"bun-profiler@0.4.2","maintainers":[{"name":"mewc771","email":"michael@drummerduck.com"}],"homepage":"https://github.com/mewc/bun-profiler#readme","bugs":{"url":"https://github.com/mewc/bun-profiler/issues"},"dist":{"shasum":"cb57714a1c5bb6a6ae46c0999db29a5c6585ac12","tarball":"https://registry.npmjs.org/bun-profiler/-/bun-profiler-0.4.2.tgz","fileCount":15,"integrity":"sha512-kjG6FTIgCYXnlC7ZlZtGcU3FdaaHa6c9MiUFosIa2ubpEGpHg0uSKPsdZKuR3ipFfuuGPw2RxXQdDFdnascYsQ==","signatures":[{"sig":"MEQCIFhoZRbPSnHTV3FSScz6OE1sSrtDecd1IFQv8NlULUP3AiBj7rF6tV1r1uvns2SCBk3O95rH/y9vL/pgHH+8fe/1+w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/bun-profiler@0.4.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":62380},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"bun":">=1.3.7"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"1fdaa9872b5e67b4cb8260aa183a5d651ed5f073","scripts":{"l":"bun run typecheck && bun run lint && bun test","dev":"cd dev && docker compose up --build -d && echo '\\n  App:        http://localhost:3002\\n  Pyroscope:   http://localhost:4042\\n  Grafana:     http://localhost:3003\\n  Prometheus:  http://localhost:9091\\n'","lint":"biome check src test","test":"bun test","build":"bun run build:esm && bun run build:cjs && bun run build:types","smoke":"bun smoke-test.ts","dev:down":"cd dev && docker compose down","dev:logs":"cd dev && docker compose logs -f app","lint:fix":"biome check --write src test","build:cjs":"bun build ./src/index.ts --outfile ./dist/index.cjs --format cjs --target node --external node:inspector --external node:os --external node:zlib --external node:util","build:esm":"bun build ./src/index.ts --outfile ./dist/index.js --format esm --target node --external node:inspector --external node:os --external node:zlib --external node:util","typecheck":"tsc --noEmit","build:types":"tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist","dev:restart":"cd dev && docker compose restart app","release:major":"npm version major && git push --follow-tags","release:minor":"npm version minor && git push --follow-tags","release:patch":"npm version patch && git push --follow-tags","prepublishOnly":"bun run build && bun run l"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:33a833bf-4d59-4292-bdd0-7cb9139eb915"}},"repository":{"url":"git+https://github.com/mewc/bun-profiler.git","type":"git"},"_npmVersion":"11.10.1","description":"Continuous CPU profiling for Bun (JavaScriptCore) via Pyroscope/Grafana ingest — zero native dependencies","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^25.3.0","@biomejs/biome":"^2.4.2"},"trustedDependencies":["@biomejs/biome"],"_npmOperationalInternal":{"tmp":"tmp/bun-profiler_0.4.2_1771896069116_0.21826391844967574","host":"s3://npm-registry-packages-npm-production"}},"0.4.3":{"name":"bun-profiler","version":"0.4.3","keywords":["bun","pyroscope","profiling","continuous-profiling","flamegraph","apm","observability","javascriptcore","jsc","grafana"],"author":{"url":"https://x.com/the_mewc","name":"mewc"},"license":"MIT","_id":"bun-profiler@0.4.3","maintainers":[{"name":"mewc771","email":"michael@drummerduck.com"}],"homepage":"https://github.com/mewc/bun-profiler#readme","bugs":{"url":"https://github.com/mewc/bun-profiler/issues"},"dist":{"shasum":"08060f3c4088b7db8b20cfb1560e887a5a3631f6","tarball":"https://registry.npmjs.org/bun-profiler/-/bun-profiler-0.4.3.tgz","fileCount":15,"integrity":"sha512-lTwsRj9sJCrCUHBr8DXnp5Zg/q8eI6UFR8YN4c/jfOE2ZTIcoSYjZKGrn0tzh+FNqvgcbhemm73MmQBhDyrByQ==","signatures":[{"sig":"MEUCIB0xczIV+LwnY46ipxxpFS/I/IbdFrDW/LADJSIfQr0hAiEAz4f7bxm4NdAezop8A6skomVcurjhLR1EXYQi/58AFuU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/bun-profiler@0.4.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":62704},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"bun":">=1.3.7"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"40d7609684937de0b2fb391ee5b69b7ee1309860","scripts":{"l":"bun run typecheck && bun run lint && bun test","dev":"cd dev && docker compose up --build -d && echo '\\n  App:        http://localhost:3002\\n  Pyroscope:   http://localhost:4042\\n  Grafana:     http://localhost:3003\\n  Prometheus:  http://localhost:9091\\n'","lint":"biome check src test","test":"bun test","build":"bun run build:esm && bun run build:cjs && bun run build:types","smoke":"bun smoke-test.ts","dev:down":"cd dev && docker compose down","dev:logs":"cd dev && docker compose logs -f app","lint:fix":"biome check --write src test","build:cjs":"bun build ./src/index.ts --outfile ./dist/index.cjs --format cjs --target node --external node:inspector --external node:os --external node:zlib --external node:util","build:esm":"bun build ./src/index.ts --outfile ./dist/index.js --format esm --target node --external node:inspector --external node:os --external node:zlib --external node:util","typecheck":"tsc --noEmit","build:types":"tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist","dev:restart":"cd dev && docker compose restart app","release:major":"npm version major && git push --follow-tags","release:minor":"npm version minor && git push --follow-tags","release:patch":"npm version patch && git push --follow-tags","prepublishOnly":"bun run build && bun run l"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:33a833bf-4d59-4292-bdd0-7cb9139eb915"}},"repository":{"url":"git+https://github.com/mewc/bun-profiler.git","type":"git"},"_npmVersion":"11.10.1","description":"Continuous CPU profiling for Bun (JavaScriptCore) via Pyroscope/Grafana ingest — zero native dependencies","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^25.3.0","@biomejs/biome":"^2.4.2"},"trustedDependencies":["@biomejs/biome"],"_npmOperationalInternal":{"tmp":"tmp/bun-profiler_0.4.3_1771899049989_0.7277835364668408","host":"s3://npm-registry-packages-npm-production"}},"0.4.4":{"name":"bun-profiler","version":"0.4.4","description":"Continuous CPU profiling for Bun (JavaScriptCore) via Pyroscope/Grafana ingest — zero native dependencies","author":{"name":"mewc","url":"https://x.com/the_mewc"},"homepage":"https://github.com/mewc/bun-profiler#readme","repository":{"type":"git","url":"git+https://github.com/mewc/bun-profiler.git"},"bugs":{"url":"https://github.com/mewc/bun-profiler/issues"},"license":"MIT","keywords":["bun","pyroscope","profiling","continuous-profiling","flamegraph","apm","observability","javascriptcore","jsc","grafana"],"type":"module","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs","types":"./dist/index.d.ts"},"./preload":{"import":"./dist/preload.js","types":"./dist/preload.d.ts"},"./experimental":{"import":"./dist/experimental.js","types":"./dist/experimental.d.ts"}},"bin":{"bun-profiler":"dist/cli.js"},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"bun run build:esm && bun run build:cjs && bun run build:types","build:esm":"bun build ./src/index.ts ./src/preload.ts ./src/cli.ts ./src/experimental.ts --outdir ./dist --format esm --target node --external node:inspector --external node:os --external node:zlib --external node:util --external node:fs/promises --external node:child_process --external node:url --external node:worker_threads","build:cjs":"bun build ./src/index.ts --outfile ./dist/index.cjs --format cjs --target node --external node:inspector --external node:os --external node:zlib --external node:util","build:types":"tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist","test":"bun test","typecheck":"tsc --noEmit","lint":"biome check src test","lint:fix":"biome check --write src test","l":"bun run typecheck && bun run lint && bun test","dev":"dev/up.sh","dev:demo":"dev/up.sh --load","dev:down":"dev/down.sh","dev:logs":"dev/compose.sh logs -f app","dev:restart":"dev/compose.sh restart app","dev:load":"dev/loadgen.sh","dev:reset":"dev/down.sh && dev/up.sh","screenshots":"dev/screenshots.sh","dev:alloy":"dev/up.sh --alloy","dev:failures":"dev/failures.sh","dev:workers":"dev/workers.sh","dev:otlp":"dev/up.sh --otlp","bench":"dev/bench.sh","smoke":"bun smoke-test.ts","release:patch":"npm version patch && git push --follow-tags","release:minor":"npm version minor && git push --follow-tags","release:major":"npm version major && git push --follow-tags","prepublishOnly":"bun run build && bun run l"},"devDependencies":{"@biomejs/biome":"^2.4.2","@types/node":"^25.3.0","playwright":"^1.62.0","typescript":"^5.9.3"},"dependencies":{"@jridgewell/trace-mapping":"^0.3.31","protobufjs":"^7.6.5"},"engines":{"bun":">=1.3.7"},"trustedDependencies":["@biomejs/biome"],"gitHead":"ade55a2cddf6ae9c5864465a7246c5e41d4bd4fb","_id":"bun-profiler@0.4.4","_nodeVersion":"22.23.2","_npmVersion":"12.0.2","dist":{"integrity":"sha512-kFcfLUyb99KszFXoCt8XezfUcEK5cOBn+3VIKlzHDyaDQRtbeHxMvCF4UEhWxguRloAJTfnEztvd2BNA2yl2oA==","shasum":"1321d8b1336d6dadb57cc6554dce93e3fc931872","tarball":"https://registry.npmjs.org/bun-profiler/-/bun-profiler-0.4.4.tgz","fileCount":59,"unpackedSize":1599771,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/bun-profiler@0.4.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICvk8v2GxixVA/TJndFt3pb+m4tGlcGrD8SrJ0nS3UmoAiEApeFtO8kazJm+zxyfwOzN++dRQGk2cAPEWWLgwiAtHjM="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:33a833bf-4d59-4292-bdd0-7cb9139eb915"}},"directories":{},"maintainers":[{"name":"mewc771","email":"michael@drummerduck.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/bun-profiler_0.4.4_1787571549207_0.5877059160295002"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-19T02:56:13.831Z","modified":"2026-08-24T11:39:09.791Z","0.2.0":"2026-02-19T02:56:14.180Z","0.3.1":"2026-02-21T21:29:52.237Z","0.4.0":"2026-02-22T23:03:16.586Z","0.4.1":"2026-02-24T01:10:20.926Z","0.4.2":"2026-02-24T01:21:09.306Z","0.4.3":"2026-02-24T02:10:50.171Z","0.4.4":"2026-08-24T11:39:09.415Z"},"bugs":{"url":"https://github.com/mewc/bun-profiler/issues"},"author":{"name":"mewc","url":"https://x.com/the_mewc"},"license":"MIT","homepage":"https://github.com/mewc/bun-profiler#readme","keywords":["bun","pyroscope","profiling","continuous-profiling","flamegraph","apm","observability","javascriptcore","jsc","grafana"],"repository":{"type":"git","url":"git+https://github.com/mewc/bun-profiler.git"},"description":"Continuous CPU profiling for Bun (JavaScriptCore) via Pyroscope/Grafana ingest — zero native dependencies","maintainers":[{"name":"mewc771","email":"michael@drummerduck.com"}],"readme":"# bun-profiler\n\nContinuous CPU profiling for [Bun](https://bun.sh) via [Pyroscope](https://pyroscope.io) / [Grafana](https://grafana.com/oss/pyroscope/) — zero native dependencies.\n\n![CPU vs wall flamegraphs in Grafana](./docs/images/grafana-dashboard.png)\n\n<p align=\"center\"><em>The bundled demo stack — <code>bun run dev</code>. Same samples, weighted two ways.</em></p>\n\n## Why this exists\n\nEvery other Node.js profiler package (`@pyroscope/nodejs`, `@datadog/pprof`, etc.) **segfaults or silently fails** on Bun because they call V8-specific native APIs that don't exist in JavaScriptCore (JSC). This package uses Bun's built-in `node:inspector` Profiler API directly, converts CDP profiles to Pyroscope's folded-stack format, and pushes them to your Pyroscope server.\n\n## Requirements\n\n- Bun ≥ 1.3.7\n- A running Pyroscope instance (self-hosted or Grafana Cloud)\n\n## Install\n\n```sh\nbun add bun-profiler\n```\n\n## Usage\n\n```ts\nimport { startProfiling } from \"bun-profiler\";\n\n// Fire-and-forget — call at app startup\nstartProfiling({\n  pyroscopeUrl: \"http://localhost:4040\",\n  appName: \"my-service\",\n});\n```\n\nFor manual start/stop control:\n\n```ts\nimport { BunPyroscope } from \"bun-profiler\";\n\nconst profiler = new BunPyroscope({\n  pyroscopeUrl: \"http://localhost:4040\",\n  appName: \"my-service\",\n});\n\nawait profiler.start();\n\n// Later, e.g. in tests or graceful shutdown:\nawait profiler.stop(); // flushes final profile before disconnecting\n```\n\n## Configuration\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `pyroscopeUrl` | `string` | — | Pyroscope server URL; required unless `exporters` is set |\n| `appName` | `string` | `SERVICE_NAME` env / `npm_package_name` / `\"bun-app\"` | Application name |\n| `sampleIntervalUs` | `number` | `10000` (10ms) | Sampling interval in microseconds |\n| `pushIntervalMs` | `number` | `15000` (15s) | How often to flush profiles |\n| `labels` | `Record<string, string>` | `{}` | Extra labels (merged with auto-detected) |\n| `authToken` | `string` | — | Bearer token for auth |\n| `basicAuth` | `{ username, password }` | — | Basic auth credentials |\n| `maxRetries` | `number` | `2` | Push retry attempts before dropping window |\n| `maxPendingWindows` | `number` | `2` | Bounded pending queue depth per exporter; oldest waiting window is evicted |\n| `shutdownTimeoutMs` | `number` | `10000` | Maximum time `stop()` waits for exporters before dropping pending work |\n| `exportTimeoutMs` | `number` | `10000` | Per-attempt HTTP deadline for the shorthand Pyroscope exporter |\n| `tenantId` | `string` | — | Grafana/Pyroscope `X-Scope-OrgID` tenant |\n| `headers` | `Record<string, string>` | `{}` | Safe additional request headers |\n| `exporters` | `ProfileExporter[]` | — | Independent file, callback, Pyroscope, or custom destinations |\n| `pyroscopeFormat` | `\"folded\" \\| \"pprof\"` | `\"folded\"` | Pyroscope CPU encoding; pprof is opt-in during 0.x |\n| `compress` | `boolean` | `false` | Gzip the request body — see the warning below |\n| `debug` | `boolean` | `false` | Log debug info to stderr |\n| `wallTime` | `{ enabled: boolean }` | `{ enabled: false }` | Wall-time profiling (opt-in) |\n| `heap` | `{ enabled, samplingIntervalBytes? }` | `{ enabled: false }` | Heap allocation profiling (opt-in) |\n| `sourceMaps` | `{ enabled, cacheSize? }` | `{ enabled: false }` | Resolve bundled-JS frames with a bounded map cache |\n| `adaptiveSampling` | `{ enabled, ... }` | `{ enabled: false }` | Experimental between-window sampling adjustment |\n\n> **Don't enable `compress` unless you've confirmed your server accepts it.** Grafana Pyroscope's `/ingest` endpoint does not decompress `format=folded` bodies. Verified against `grafana/pyroscope:latest`: a gzipped body is answered with **HTTP 200** and then stored as an empty profile. Nothing errors, nothing retries, and no data ever appears. It defaults to `false` for that reason.\n\n### Environment-first setup\n\nContainer deployments can use the same configuration without an application wrapper:\n\n```ts\nimport { startProfilingFromEnv } from \"bun-profiler\";\n\nconst profiler = startProfilingFromEnv({ labels: { component: \"api\" } });\n```\n\nExplicit overrides win over environment values, which win over defaults. Supported common variables are `PYROSCOPE_SERVER_ADDRESS`, `PYROSCOPE_APPLICATION_NAME`, `PYROSCOPE_LABELS`, `PYROSCOPE_PROFILING_INTERVAL`, `PYROSCOPE_UPLOAD_INTERVAL`, `PYROSCOPE_BASIC_AUTH_USER`, `PYROSCOPE_BASIC_AUTH_PASSWORD`, and `PYROSCOPE_TENANT_ID`. Durations include a unit, for example `10ms`, `15s`, or `2m`.\n\nLibrary controls use `BUN_PROFILER_*`: `MAX_RETRIES`, `MAX_PENDING_WINDOWS`, `SHUTDOWN_TIMEOUT`, `EXPORT_TIMEOUT`, `DEBUG`, `COMPRESS`, `AUTH_TOKEN`, `PYROSCOPE_FORMAT`, `WALL_TIME_ENABLED`, `HEAP_ENABLED`, `HEAP_SAMPLING_INTERVAL_BYTES`, `SOURCE_MAPS_ENABLED`, `SOURCE_MAP_CACHE_SIZE`, and the `ADAPTIVE_*` variables.\n\n### Exporters and pprof\n\nEach destination has its own sequential, bounded queue. A slow or unavailable backend cannot pause capture or another exporter.\nRetryable failures use capped exponential backoff with equal jitter so replicas do not retry in lockstep. HTTP `Retry-After` is honored in both delay-seconds and date forms, with positive jitter and a five-minute safety ceiling.\n\n```ts\nimport {\n  BunPyroscope,\n  callbackExporter,\n  pprofFileExporter,\n  pyroscopeExporter,\n} from \"bun-profiler\";\n\nconst profiler = new BunPyroscope({\n  appName: \"orders\",\n  exporters: [\n    pyroscopeExporter({ url: \"http://pyroscope:4040\", format: \"pprof\" }),\n    pprofFileExporter({ directory: \"./profiles\" }),\n    callbackExporter(\"audit\", async (window) => console.log(window.from, window.type)),\n  ],\n});\n```\n\n`encodePprof()` emits standards-compatible gzip-compressed `profile.proto`. File exporters also support raw `.cpuprofile` and Speedscope JSON. `ProfileWindow` is immutable at the exporter boundary, and custom exporters implement the small `ProfileExporter` interface.\n\n## Wall-time profiling\n\nCPU profiling only captures on-CPU time — what your code does when it's actively executing JavaScript. For I/O-heavy servers that spend most of their time waiting on external APIs, databases, or network calls, CPU profiles miss the full picture.\n\nWall-time profiling weights stacks by elapsed microseconds rather than sample count, and surfaces time spent parked off-CPU as an explicit `(idle)` frame.\n\n```ts\nstartProfiling({\n  pyroscopeUrl: \"http://localhost:4040\",\n  appName: \"my-api-server\",\n  wallTime: { enabled: true },\n});\n```\n\nWhen enabled, an additional `wall` profile stream is pushed alongside `cpu`. In Pyroscope/Grafana, select the `my-api-server.wall{}` stream to see the wall-time flamegraph.\n\nIt adds no extra sampling overhead — it reuses the same CDP profile data as CPU profiling.\n\n### What it can and cannot tell you on Bun\n\n**It tells you how much time went off-CPU. It cannot tell you which call was waiting.**\n\nJavaScriptCore emits no `(idle)` samples and stops sampling altogether while the process is parked, so the first sample taken *after* a wait carries a `timeDelta` spanning the entire wait. Nothing in the profile records what the process was waiting on.\n\nThis matters, because attributing that whole delta to the sampled stack — the obvious implementation — blames whichever function happened to resume. Measured on Bun 1.3.14, for a request that awaited 300ms and then ran a 60ms handler:\n\n| | Reported |\n| --- | --- |\n| Naive: charge the full delta to the sampled stack | `renderReceipt` **354ms** — the function that waited never appears |\n| What actually happened | `renderReceipt` 60ms, waiting 300ms |\n| This package | `renderReceipt` **58ms**, `(idle)` **301ms** |\n\nA delta larger than twice the sampling interval is treated as a gap: the stack is credited with one sampling interval, and the remainder is booked to `(idle)`. So a `(idle)` block that dwarfs everything else is the signal that your service is I/O-bound — you then reach for request tracing to find *which* call, because a JSC sampling profiler fundamentally cannot answer that.\n\nOn Node.js/V8, which does emit real `(idle)` samples, those are already attributed correctly and are passed through untouched.\n\n## Checking the profiler is actually working\n\nContinuous profiling fails quietly. It runs in the background, and a profiler that has stopped delivering looks exactly like a service that happens to be idle — no data either way. `stats()` makes the difference visible:\n\n```ts\nconst profiler = startProfiling({ pyroscopeUrl: \"...\", appName: \"my-service\" });\n\nBun.serve({\n  routes: {\n    \"/health\": () => {\n      const s = profiler.stats();\n      // \"Nothing pushed lately\" is NOT a fault — an idle process produces no\n      // samples, so empty windows are correct. A dead loop, or pushes that have\n      // only ever failed, are unambiguous.\n      const degraded = !s.running || (s.pushedWindows === 0 && s.failedWindows > 0);\n      return Response.json(s, { status: degraded ? 503 : 200 });\n    },\n  },\n});\n```\n\n```json\n{\n  \"running\": true,\n  \"pushedWindows\": 42,\n  \"failedWindows\": 0,\n  \"emptyWindows\": 3,\n  \"lastPushAt\": 1785131313353,\n  \"lastError\": null,\n  \"streams\": [\"cpu\", \"wall\"]\n}\n```\n\n`emptyWindows` climbing alongside `pushedWindows` is normal. `emptyWindows` climbing while `pushedWindows` doesn't, on a service you know is busy, means the profiler isn't seeing your work.\n\nThis reports what the transport did, so it catches a dead loop and rejected pushes. It cannot catch a server that accepts a push and stores nothing — see the `compress` warning above for the one case where that happens.\n\n`renderPrometheusMetrics(profiler)` exposes the same state without owning an HTTP server: capture gaps and samples, conversion time, per-exporter queue/retry/drop/failure/latency/last-success state, and Bun/Node memory gauges. The examples show plain `Bun.serve`, Hono, and Elysia integration.\n\n## Tagging a region of code\n\n`tag()` splits the profiling window so a specific block of work gets its own labelled stream — useful for a background job, a migration, or one hot endpoint:\n\n```ts\nconst profiler = new BunPyroscope({ pyroscopeUrl: \"...\", appName: \"my-service\" });\nawait profiler.start();\n\nawait profiler.tag({ job: \"nightly-report\" }, async () => {\n  await generateReport();\n});\n```\n\nThe work inside runs under `my-service.cpu{job=nightly-report}`, so you can isolate it in Pyroscope.\n\nIt flushes the current window on entry and exit, so each call costs two extra pushes — use it around meaningful units of work, not per request.\n\nOverlapping `tag()` calls fail immediately with `ProfilerConcurrencyError`. Do not create another profiler to work around this: Bun exposes one inspector CPU sampler per process, and concurrent sessions corrupt each other's windows. Use bounded, non-overlapping regions or ordinary profile/resource labels for concurrent work.\n\n## Heap profiling\n\nOpt-in allocation profiling tracks where memory is being allocated:\n\n```ts\nstartProfiling({\n  pyroscopeUrl: \"http://localhost:4040\",\n  appName: \"my-service\",\n  heap: { enabled: true, samplingIntervalBytes: 32_768 },\n});\n```\n\nWhen enabled, an `alloc_space` profile stream is pushed alongside `cpu`.\n\n**Bun limitation:** Bun's JavaScriptCore runtime does not currently implement `HeapProfiler.enable`. When heap profiling is enabled on Bun, the profiler logs a warning and continues with CPU-only profiling. Heap profiling works on Node.js/V8. This will be supported once Bun adds HeapProfiler to their inspector implementation.\n\nLow-cost `process.memoryUsage()` and `bun:jsc.heapStats()` gauges remain available in `stats()` and Prometheus output. Full heap snapshots are deliberately on demand:\n\n```ts\nimport { captureHeapSnapshot } from \"bun-profiler\";\nawait captureHeapSnapshot(\"incident.heapsnapshot\");\n```\n\nor `bun-profiler heap-snapshot incident.heapsnapshot`. A snapshot can pause the process and be large, so the library never schedules one periodically.\n\n## Preload, CLI, workers, and pull mode\n\nUse the preload entry point when changing application code is undesirable:\n\n```sh\nPYROSCOPE_SERVER_ADDRESS=http://localhost:4040 \\\nPYROSCOPE_APPLICATION_NAME=orders \\\nbun --preload bun-profiler/preload src/server.ts\n```\n\nThe CLI is equivalent and can capture short-lived commands offline:\n\n```sh\nbun-profiler run --out ./profiles --format pprof -- scripts/import.ts\n```\n\nThe preload timer is unreferenced and flushes on `beforeExit`, SIGINT, and SIGTERM, so profiling does not keep a finished script alive.\n\nWorkers may select the preload through their `preload` option, and worker streams receive a `worker_id` label. Current Bun releases still expose a process-wide inspector sampler, so only one selected isolate—main or one worker—may profile in a process at a time. `bun run dev:workers` demonstrates the supported pattern and reports the limitation explicitly.\n\nFor systems that scrape Go-style endpoints, `createPprofHandler()` provides `/debug/pprof/profile?seconds=N` behavior without creating a server. It coalesces concurrent scrapes and returns `409` when continuous push mode owns the sampler. Pull and push mode are intentionally mutually exclusive.\n\n## Source maps and experimental signals\n\nDirectly executed TypeScript already carries original locations in Bun profiles. For bundled JavaScript, `sourceMaps: { enabled: true }` resolves inline or external maps using a bounded cache and falls back to generated positions on any map or filesystem error.\n\nAdaptive sampling is opt-in and only changes the sampling interval between windows. Every change is counted in stats and fixed 100 Hz sampling remains the default.\n\nOTLP Profiles is Alpha. The current OTLP/HTTP JSON exporter therefore lives behind the explicitly unstable entry point and posts to `/v1development/profiles`:\n\n```ts\nimport { otlpHttpProfilesExporter } from \"bun-profiler/experimental\";\n```\n\nIt adds window-level resource labels only. The library does not invent per-span or per-request attribution because Bun's sampler does not expose the context needed to associate a CDP sample with an async span.\n\n## Auto-detected labels\n\nThe following labels are added automatically when the corresponding environment variables are set:\n\n| Label | Environment variable(s) |\n|---|---|\n| `service_name` | `SERVICE_NAME`, `npm_package_name`, or `appName` option |\n| `service_version` | `SERVICE_VERSION`, `npm_package_version` |\n| `environment` | `NODE_ENV`, `BUN_ENV` |\n| `hostname` | `os.hostname()` (always present) |\n| `fly_region` | `FLY_REGION` |\n| `fly_app_name` | `FLY_APP_NAME` |\n| `aws_region` | `AWS_REGION`, `AWS_DEFAULT_REGION` |\n| `railway_region` | `RAILWAY_REGION` |\n| `railway_service` | `RAILWAY_SERVICE_NAME` |\n| `pod_name` | `POD_NAME` |\n| `k8s_namespace` | `K8S_NAMESPACE` |\n\nExtra labels passed via the `labels` option override auto-detected values.\n\n## Try it locally\n\nA complete demo stack — Bun app, Pyroscope, Grafana, Prometheus — lives in [`dev/`](./dev).\n\n```sh\nbun run dev:demo   # start everything, then drive 60s of traffic\nbun run dev:alloy  # app -> Alloy receive_http -> two Pyroscope destinations\nbun run dev:failures # 429/500/timeout/recovery fault injection\nbun run dev:workers  # selected worker-isolate fixture\nbun run dev:otlp   # experimental OTLP Profiles -> Collector debug exporter\nbun run bench      # unprofiled/CPU/wall/pprof/worker comparison\n```\n\nIt waits until the stack is serving and prints the URLs — by default\n<http://localhost:3003/d/bun-profiler-demo>. (Ports are per-workspace under\n[Conductor](https://conductor.build), so take them from the output.)\n\nThe demo server exposes workloads with deliberately distinct flamegraph shapes — deep recursion, a hot comparator, regex scanning, crypto — alongside I/O-bound ones and a realistic mixed `/api/checkout` pipeline. Drive them from the panel the script links to (<http://localhost:3002> by default), individually, by group, or all at once. Every result links straight to the flamegraph for that exact run:\n\n![Demo control panel](./docs/images/demo-panel.png)\n\nThe provisioned dashboard puts the two profiles side by side. Same samples, weighted differently:\n\n![CPU vs wall flamegraphs in Grafana](./docs/images/grafana-dashboard.png)\n\nThe CPU profile contains no idle time at all — every frame is real compute, and it points at `applyDiscounts` and the regex scan. The wall profile, over the same window, shows that the largest single block is `(idle)`:\n\n![Wall profile with idle as the top entry](./docs/images/wall-flamegraph.png)\n\nThat contrast is the whole argument for wall-time profiling: the CPU flamegraph tells you which loop to optimise, while the wall flamegraph tells you whether optimising it would matter at all.\n\nThose three images are not hand-captured. `bun run screenshots` drives the live stack with Playwright — clicks \"Run all\", waits for the profiler to push, generates 90s of mixed traffic, blocks until Prometheus actually returns series, then captures Grafana. It fails if any panel renders \"No data\" or a result is missing its deep link, so regenerating them is itself an end-to-end test.\n\nSee [`dev/README.md`](./dev/README.md) for the full workload list and troubleshooting.\nDeployment constraints, failure modes, Kubernetes environment configuration, migration guidance, and the custom-exporter contract are in [`docs/production.md`](./docs/production.md).\n\n## Development\n\n```sh\nbun install\nbun run l       # typecheck + lint + tests\nbun run build\n```\n\n## How it works\n\n1. Connects to Bun's embedded JavaScriptCore inspector via `node:inspector/promises`\n2. Every `pushIntervalMs`: stops the profiler, immediately starts the next sampling window, and measures that unavoidable stop/start gap\n3. Converts the completed CDP window and hands it to independent bounded exporter queues while sampling has already resumed\n4. On SIGTERM/SIGINT: flushes the current window before exiting\n\nStep 2 still leaves a small unavoidable inspector stop/start blind spot, but conversion, pprof encoding, retries, and network I/O are no longer inside it. `lastCaptureGapMs`, `maxCaptureGapMs`, and the Prometheus gap metrics make the remaining loss observable.\n\n## Why not `Bun.jsc.profile()`?\n\nBun exposes `bun:jsc` with a `profile()` function, but it's **not suitable** for continuous profiling:\n\n- **Wrong output format** — `Bun.jsc.profile()` returns a `SamplingProfile` with pre-formatted text strings (`.functions`, `.bytecodes`, `.stackTraces`), not structured CDP/V8 JSON with `nodes`/`samples`/`timeDeltas`. There's no way to convert this to folded stacks without writing a brittle text parser.\n- **No start/stop control** — `Bun.jsc.startSamplingProfiler()` has no corresponding stop function. It's a fire-and-forget debug tool that writes to a directory, not a programmatic API.\n- **`node:inspector` already works** — Bun added full `node:inspector` Profiler support in [v1.3.7](https://bun.sh/blog/bun-v1.3.7) (November 2024). This is the same CDP API that Chrome DevTools uses, returning proper `CdpProfile` objects that convert directly to Pyroscope's folded-stack format. That's why the minimum Bun version is 1.3.7.\n\nIf you're on Bun < 1.3.7, you'll get a clear error from `start()` explaining the requirement. Upgrade Bun and it works out of the box.\n\n## Graceful shutdown\n\nSignal handlers are installed automatically. On SIGTERM or SIGINT, the profiler flushes the current window and disconnects before re-emitting the signal so your process exits normally.\n\n## Release\n\n```sh\nbun run release:patch   # 0.1.0 → 0.1.1  (bug fixes)\nbun run release:minor   # 0.1.0 → 0.2.0  (new features)\nbun run release:major   # 0.1.0 → 1.0.0  (breaking changes)\n```\n\nBumps `package.json`, commits, tags, and pushes. GitHub Actions publishes to npm automatically via OIDC trusted publishing — no token required.\n\n## License\n\nMIT\n\n---\n\nBuilt by [mewc](https://x.com/the_mewc) · [ChartCastr](https://chartcastr.com)\n","readmeFilename":"README.md"}