mdcontext 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/README.md +28 -0
- package/.changeset/config.json +11 -0
- package/.claude/settings.local.json +25 -0
- package/.github/workflows/ci.yml +83 -0
- package/.github/workflows/claude-code-review.yml +44 -0
- package/.github/workflows/claude.yml +85 -0
- package/.github/workflows/release.yml +113 -0
- package/.tldrignore +112 -0
- package/BACKLOG.md +338 -0
- package/CONTRIBUTING.md +186 -0
- package/NOTES/NOTES +44 -0
- package/README.md +434 -11
- package/biome.json +36 -0
- package/cspell.config.yaml +14 -0
- package/dist/chunk-23UPXDNL.js +3044 -0
- package/dist/chunk-2W7MO2DL.js +1366 -0
- package/dist/chunk-3NUAZGMA.js +1689 -0
- package/dist/chunk-7TOWB2XB.js +366 -0
- package/dist/chunk-7XOTOADQ.js +3065 -0
- package/dist/chunk-AH2PDM2K.js +3042 -0
- package/dist/chunk-BNXWSZ63.js +3742 -0
- package/dist/chunk-BTL5DJVU.js +3222 -0
- package/dist/chunk-HDHYG7E4.js +104 -0
- package/dist/chunk-HLR4KZBP.js +3234 -0
- package/dist/chunk-IP3FRFEB.js +1045 -0
- package/dist/chunk-KHU56VDO.js +3042 -0
- package/dist/chunk-KRYIFLQR.js +88 -0
- package/dist/chunk-LBSDNLEM.js +287 -0
- package/dist/chunk-MNTQ7HCP.js +2643 -0
- package/dist/chunk-MUJELQQ6.js +1387 -0
- package/dist/chunk-MXJGMSLV.js +2199 -0
- package/dist/chunk-N6QJGC3Z.js +2636 -0
- package/dist/chunk-OBELGBPM.js +1713 -0
- package/dist/chunk-OT7R5XTA.js +3192 -0
- package/dist/chunk-P7X4RA2T.js +106 -0
- package/dist/chunk-PIDUQNC2.js +3185 -0
- package/dist/chunk-POGCDIH4.js +3187 -0
- package/dist/chunk-PSIEOQGZ.js +3043 -0
- package/dist/chunk-PVRT3IHA.js +3238 -0
- package/dist/chunk-QNN4TT23.js +1430 -0
- package/dist/chunk-RE3R45RJ.js +3042 -0
- package/dist/chunk-S7E6TFX6.js +803 -0
- package/dist/chunk-SG6GLU4U.js +1378 -0
- package/dist/chunk-SJCDV2ST.js +274 -0
- package/dist/chunk-SYE5XLF3.js +104 -0
- package/dist/chunk-T5VLYBZD.js +103 -0
- package/dist/chunk-TOQB7VWU.js +3238 -0
- package/dist/chunk-VFNMZ4ZQ.js +3228 -0
- package/dist/chunk-VVTGZNBT.js +1629 -0
- package/dist/chunk-W7Q4RFEV.js +104 -0
- package/dist/chunk-XTYYVRLO.js +3190 -0
- package/dist/chunk-Y6MDYVJD.js +3063 -0
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +5458 -0
- package/dist/index.d.ts +653 -0
- package/dist/index.js +79 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +472 -0
- package/dist/schema-BAWSG7KY.js +22 -0
- package/dist/schema-E3QUPL26.js +20 -0
- package/dist/schema-EHL7WUT6.js +20 -0
- package/docs/019-USAGE.md +625 -0
- package/docs/020-current-implementation.md +364 -0
- package/docs/021-DOGFOODING-FINDINGS.md +175 -0
- package/docs/BACKLOG.md +80 -0
- package/docs/CONFIG.md +1123 -0
- package/docs/DESIGN.md +439 -0
- package/docs/ERRORS.md +383 -0
- package/docs/PROJECT.md +88 -0
- package/docs/ROADMAP.md +407 -0
- package/docs/summarization.md +320 -0
- package/docs/test-links.md +9 -0
- package/justfile +40 -0
- package/package.json +74 -9
- package/pnpm-workspace.yaml +5 -0
- package/research/INDEX.md +315 -0
- package/research/code-review/README.md +90 -0
- package/research/code-review/cli-error-handling-review.md +979 -0
- package/research/code-review/code-review-validation-report.md +464 -0
- package/research/code-review/main-ts-review.md +1128 -0
- package/research/config-analysis/01-current-implementation.md +470 -0
- package/research/config-analysis/02-strategy-recommendation.md +428 -0
- package/research/config-analysis/03-task-candidates.md +715 -0
- package/research/config-analysis/033-research-configuration-management.md +828 -0
- package/research/config-analysis/034-research-effect-cli-config.md +1504 -0
- package/research/config-analysis/04-consolidated-task-candidates.md +277 -0
- package/research/config-docs/SUMMARY.md +357 -0
- package/research/config-docs/TEST-RESULTS.md +776 -0
- package/research/config-docs/TODO.md +542 -0
- package/research/config-docs/analysis.md +744 -0
- package/research/config-docs/fix-validation.md +502 -0
- package/research/config-docs/help-audit.md +264 -0
- package/research/config-docs/help-system-analysis.md +890 -0
- package/research/dogfood/consolidated-tool-evaluation.md +373 -0
- package/research/dogfood/strategy-a/a-synthesis.md +184 -0
- package/research/dogfood/strategy-a/a1-docs.md +226 -0
- package/research/dogfood/strategy-a/a2-amorphic.md +156 -0
- package/research/dogfood/strategy-a/a3-llm.md +164 -0
- package/research/dogfood/strategy-b/b-synthesis.md +228 -0
- package/research/dogfood/strategy-b/b1-architecture.md +207 -0
- package/research/dogfood/strategy-b/b2-gaps.md +258 -0
- package/research/dogfood/strategy-b/b3-workflows.md +250 -0
- package/research/dogfood/strategy-c/c-synthesis.md +451 -0
- package/research/dogfood/strategy-c/c1-explorer.md +192 -0
- package/research/dogfood/strategy-c/c2-diver-memory.md +145 -0
- package/research/dogfood/strategy-c/c3-diver-control.md +148 -0
- package/research/dogfood/strategy-c/c4-diver-failure.md +151 -0
- package/research/dogfood/strategy-c/c5-diver-execution.md +221 -0
- package/research/dogfood/strategy-c/c6-diver-org.md +221 -0
- package/research/effect-cli-error-handling.md +845 -0
- package/research/effect-errors-as-values.md +943 -0
- package/research/errors-task-analysis/00-consolidated-tasks.md +207 -0
- package/research/errors-task-analysis/cli-commands-analysis.md +909 -0
- package/research/errors-task-analysis/embeddings-analysis.md +709 -0
- package/research/errors-task-analysis/index-search-analysis.md +812 -0
- package/research/frontmatter/COMMENTS-ARE-SKIPPED.md +149 -0
- package/research/frontmatter/LLM-CODE-NAVIGATION.md +276 -0
- package/research/issue-review.md +603 -0
- package/research/llm-summarization/agent-cli-tools-2026.md +1082 -0
- package/research/llm-summarization/alternative-providers-2026.md +1428 -0
- package/research/llm-summarization/anthropic-2026.md +367 -0
- package/research/llm-summarization/claude-cli-integration.md +1706 -0
- package/research/llm-summarization/cli-integration-patterns.md +3155 -0
- package/research/llm-summarization/openai-2026.md +473 -0
- package/research/llm-summarization/openai-compatible-providers-2026.md +1022 -0
- package/research/llm-summarization/opencode-cli-integration.md +1552 -0
- package/research/llm-summarization/prompt-engineering-2026.md +1426 -0
- package/research/llm-summarization/prototype-results.md +56 -0
- package/research/llm-summarization/provider-switching-patterns-2026.md +2153 -0
- package/research/llm-summarization/typescript-llm-libraries-2026.md +2436 -0
- package/research/mdcontext-error-analysis.md +521 -0
- package/research/mdcontext-pudding/00-EXECUTIVE-SUMMARY.md +282 -0
- package/research/mdcontext-pudding/01-index-embed.md +956 -0
- package/research/mdcontext-pudding/02-search-COMMANDS.md +142 -0
- package/research/mdcontext-pudding/02-search-SUMMARY.md +146 -0
- package/research/mdcontext-pudding/02-search.md +970 -0
- package/research/mdcontext-pudding/03-context.md +779 -0
- package/research/mdcontext-pudding/04-navigation-and-analytics.md +803 -0
- package/research/mdcontext-pudding/04-tree.md +704 -0
- package/research/mdcontext-pudding/05-config.md +1038 -0
- package/research/mdcontext-pudding/06-links-summary.txt +87 -0
- package/research/mdcontext-pudding/06-links.md +679 -0
- package/research/mdcontext-pudding/07-stats.md +693 -0
- package/research/mdcontext-pudding/BUG-FIX-PLAN.md +388 -0
- package/research/mdcontext-pudding/P0-BUG-VALIDATION.md +167 -0
- package/research/mdcontext-pudding/README.md +168 -0
- package/research/mdcontext-pudding/TESTING-SUMMARY.md +128 -0
- package/research/npm_publish/011-npm-workflow-research-agent2.md +792 -0
- package/research/npm_publish/012-npm-workflow-research-agent1.md +530 -0
- package/research/npm_publish/013-npm-workflow-research-agent3.md +722 -0
- package/research/npm_publish/014-npm-workflow-synthesis.md +556 -0
- package/research/npm_publish/031-npm-workflow-task-analysis.md +134 -0
- package/research/research-quality-review.md +834 -0
- package/research/semantic-search/002-research-embedding-models.md +490 -0
- package/research/semantic-search/003-research-rag-alternatives.md +523 -0
- package/research/semantic-search/004-research-vector-search.md +841 -0
- package/research/semantic-search/032-research-semantic-search.md +427 -0
- package/research/semantic-search/embedding-text-analysis.md +156 -0
- package/research/semantic-search/multi-word-failure-reproduction.md +171 -0
- package/research/semantic-search/query-processing-analysis.md +207 -0
- package/research/semantic-search/root-cause-and-solution.md +114 -0
- package/research/semantic-search/threshold-validation-report.md +69 -0
- package/research/semantic-search/vector-search-analysis.md +63 -0
- package/research/task-management-2026/00-synthesis-recommendations.md +295 -0
- package/research/task-management-2026/01-ai-workflow-tools.md +416 -0
- package/research/task-management-2026/02-agent-framework-patterns.md +476 -0
- package/research/task-management-2026/03-lightweight-file-based.md +567 -0
- package/research/task-management-2026/04-established-tools-ai-features.md +541 -0
- package/research/task-management-2026/linear/01-core-features-workflow.md +771 -0
- package/research/task-management-2026/linear/02-api-integrations.md +930 -0
- package/research/task-management-2026/linear/03-ai-features.md +368 -0
- package/research/task-management-2026/linear/04-pricing-setup.md +205 -0
- package/research/task-management-2026/linear/05-usage-patterns-best-practices.md +605 -0
- package/research/test-path-issues.md +276 -0
- package/review/ALP-76/1-error-type-design.md +962 -0
- package/review/ALP-76/2-error-handling-patterns.md +906 -0
- package/review/ALP-76/3-error-presentation.md +624 -0
- package/review/ALP-76/4-test-coverage.md +625 -0
- package/review/ALP-76/5-migration-completeness.md +440 -0
- package/review/ALP-76/6-effect-best-practices.md +755 -0
- package/scripts/apply-branch-protection.sh +47 -0
- package/scripts/branch-protection-templates.json +79 -0
- package/scripts/prototype-summarization.ts +346 -0
- package/scripts/rebuild-hnswlib.js +58 -0
- package/scripts/setup-branch-protection.sh +64 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/active-provider.json +7 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/bm25.json +541 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/bm25.meta.json +5 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/config.json +8 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.bin +0 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.meta.bin +0 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/documents.json +60 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/links.json +13 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/sections.json +1197 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/configuration-management.md +99 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/distributed-systems.md +92 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/error-handling.md +78 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/failure-automation.md +55 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/job-context.md +69 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/process-orchestration.md +99 -0
- package/src/cli/argv-preprocessor.test.ts +210 -0
- package/src/cli/argv-preprocessor.ts +202 -0
- package/src/cli/cli.test.ts +627 -0
- package/src/cli/commands/backlinks.ts +54 -0
- package/src/cli/commands/config-cmd.ts +642 -0
- package/src/cli/commands/context.ts +285 -0
- package/src/cli/commands/duplicates.ts +122 -0
- package/src/cli/commands/embeddings.ts +529 -0
- package/src/cli/commands/index-cmd.ts +480 -0
- package/src/cli/commands/index.ts +16 -0
- package/src/cli/commands/links.ts +52 -0
- package/src/cli/commands/search.ts +1281 -0
- package/src/cli/commands/stats.ts +149 -0
- package/src/cli/commands/tree.ts +128 -0
- package/src/cli/config-layer.ts +176 -0
- package/src/cli/error-handler.test.ts +235 -0
- package/src/cli/error-handler.ts +655 -0
- package/src/cli/flag-schemas.ts +341 -0
- package/src/cli/help.ts +588 -0
- package/src/cli/index.ts +9 -0
- package/src/cli/main.ts +435 -0
- package/src/cli/options.ts +41 -0
- package/src/cli/shared-error-handling.ts +199 -0
- package/src/cli/typo-suggester.test.ts +105 -0
- package/src/cli/typo-suggester.ts +130 -0
- package/src/cli/utils.ts +259 -0
- package/src/config/file-provider.test.ts +320 -0
- package/src/config/file-provider.ts +273 -0
- package/src/config/index.ts +72 -0
- package/src/config/integration.test.ts +667 -0
- package/src/config/precedence.test.ts +277 -0
- package/src/config/precedence.ts +451 -0
- package/src/config/schema.test.ts +414 -0
- package/src/config/schema.ts +603 -0
- package/src/config/service.test.ts +320 -0
- package/src/config/service.ts +243 -0
- package/src/config/testing.test.ts +264 -0
- package/src/config/testing.ts +110 -0
- package/src/core/index.ts +1 -0
- package/src/core/types.ts +113 -0
- package/src/duplicates/detector.test.ts +183 -0
- package/src/duplicates/detector.ts +414 -0
- package/src/duplicates/index.ts +18 -0
- package/src/embeddings/embedding-namespace.test.ts +300 -0
- package/src/embeddings/embedding-namespace.ts +947 -0
- package/src/embeddings/heading-boost.test.ts +222 -0
- package/src/embeddings/hnsw-build-options.test.ts +198 -0
- package/src/embeddings/hyde.test.ts +272 -0
- package/src/embeddings/hyde.ts +264 -0
- package/src/embeddings/index.ts +10 -0
- package/src/embeddings/openai-provider.ts +414 -0
- package/src/embeddings/pricing.json +22 -0
- package/src/embeddings/provider-constants.ts +204 -0
- package/src/embeddings/provider-errors.test.ts +967 -0
- package/src/embeddings/provider-errors.ts +565 -0
- package/src/embeddings/provider-factory.test.ts +240 -0
- package/src/embeddings/provider-factory.ts +225 -0
- package/src/embeddings/provider-integration.test.ts +788 -0
- package/src/embeddings/query-preprocessing.test.ts +187 -0
- package/src/embeddings/semantic-search-threshold.test.ts +508 -0
- package/src/embeddings/semantic-search.ts +1270 -0
- package/src/embeddings/types.ts +359 -0
- package/src/embeddings/vector-store.ts +708 -0
- package/src/embeddings/voyage-provider.ts +313 -0
- package/src/errors/errors.test.ts +845 -0
- package/src/errors/index.ts +533 -0
- package/src/index/ignore-patterns.test.ts +354 -0
- package/src/index/ignore-patterns.ts +305 -0
- package/src/index/index.ts +4 -0
- package/src/index/indexer.ts +684 -0
- package/src/index/storage.ts +260 -0
- package/src/index/types.ts +147 -0
- package/src/index/watcher.ts +189 -0
- package/src/index.ts +30 -0
- package/src/integration/search-keyword.test.ts +678 -0
- package/src/mcp/server.ts +612 -0
- package/src/parser/index.ts +1 -0
- package/src/parser/parser.test.ts +291 -0
- package/src/parser/parser.ts +394 -0
- package/src/parser/section-filter.test.ts +277 -0
- package/src/parser/section-filter.ts +392 -0
- package/src/search/__tests__/hybrid-search.test.ts +650 -0
- package/src/search/bm25-store.ts +366 -0
- package/src/search/cross-encoder.test.ts +253 -0
- package/src/search/cross-encoder.ts +406 -0
- package/src/search/fuzzy-search.test.ts +419 -0
- package/src/search/fuzzy-search.ts +273 -0
- package/src/search/hybrid-search.ts +448 -0
- package/src/search/path-matcher.test.ts +276 -0
- package/src/search/path-matcher.ts +33 -0
- package/src/search/query-parser.test.ts +260 -0
- package/src/search/query-parser.ts +319 -0
- package/src/search/searcher.test.ts +280 -0
- package/src/search/searcher.ts +724 -0
- package/src/search/wink-bm25.d.ts +30 -0
- package/src/summarization/cli-providers/claude.ts +202 -0
- package/src/summarization/cli-providers/detection.test.ts +273 -0
- package/src/summarization/cli-providers/detection.ts +118 -0
- package/src/summarization/cli-providers/index.ts +8 -0
- package/src/summarization/cost.test.ts +139 -0
- package/src/summarization/cost.ts +102 -0
- package/src/summarization/error-handler.test.ts +127 -0
- package/src/summarization/error-handler.ts +111 -0
- package/src/summarization/index.ts +102 -0
- package/src/summarization/pipeline.test.ts +498 -0
- package/src/summarization/pipeline.ts +231 -0
- package/src/summarization/prompts.test.ts +269 -0
- package/src/summarization/prompts.ts +133 -0
- package/src/summarization/provider-factory.test.ts +396 -0
- package/src/summarization/provider-factory.ts +178 -0
- package/src/summarization/types.ts +184 -0
- package/src/summarize/budget-bugs.test.ts +620 -0
- package/src/summarize/formatters.ts +419 -0
- package/src/summarize/index.ts +20 -0
- package/src/summarize/summarizer.test.ts +275 -0
- package/src/summarize/summarizer.ts +597 -0
- package/src/summarize/verify-bugs.test.ts +238 -0
- package/src/types/huggingface-transformers.d.ts +66 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/tokens.test.ts +142 -0
- package/src/utils/tokens.ts +186 -0
- package/tests/fixtures/cli/.mdcontext/active-provider.json +7 -0
- package/tests/fixtures/cli/.mdcontext/config.json +8 -0
- package/tests/fixtures/cli/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.bin +0 -0
- package/tests/fixtures/cli/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.meta.bin +0 -0
- package/tests/fixtures/cli/.mdcontext/indexes/documents.json +33 -0
- package/tests/fixtures/cli/.mdcontext/indexes/links.json +12 -0
- package/tests/fixtures/cli/.mdcontext/indexes/sections.json +247 -0
- package/tests/fixtures/cli/README.md +9 -0
- package/tests/fixtures/cli/api-reference.md +11 -0
- package/tests/fixtures/cli/getting-started.md +11 -0
- package/tests/integration/embed-index.test.ts +712 -0
- package/tests/integration/search-context.test.ts +469 -0
- package/tests/integration/search-semantic.test.ts +522 -0
- package/tsconfig.json +26 -0
- package/vitest.config.ts +16 -0
- package/vitest.setup.ts +12 -0
|
@@ -0,0 +1,792 @@
|
|
|
1
|
+
# NPM Publishing Workflow Best Practices 2026
|
|
2
|
+
|
|
3
|
+
> Research conducted January 2026 - Modern approaches for npm publishing with pnpm and GitHub Actions
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Release Automation Tools](#1-release-automation-tools)
|
|
8
|
+
2. [CI/CD Pipeline Design](#2-cicd-pipeline-design)
|
|
9
|
+
3. [NPM Provenance & Supply Chain Security](#3-npm-provenance--supply-chain-security)
|
|
10
|
+
4. [Dual ESM/CJS Publishing](#4-dual-esmcjs-publishing)
|
|
11
|
+
5. [Pre-release & Canary Workflows](#5-pre-release--canary-workflows)
|
|
12
|
+
6. [Bun Migration Analysis](#6-bun-migration-analysis)
|
|
13
|
+
7. [Decision Framework](#7-decision-framework)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. Release Automation Tools
|
|
18
|
+
|
|
19
|
+
### Tool Comparison Matrix
|
|
20
|
+
|
|
21
|
+
| Feature | semantic-release | release-please | Changesets |
|
|
22
|
+
| ------------------------- | ---------------------- | ---------------- | ---------------------- |
|
|
23
|
+
| **Automation Level** | Fully automated | Semi-automated | Semi-automated |
|
|
24
|
+
| **Version Determination** | Commit messages | Commit messages | Changeset files |
|
|
25
|
+
| **Monorepo Support** | Via plugins (limited) | Native | Native (primary focus) |
|
|
26
|
+
| **Human Review** | No (automated) | Yes (PR-based) | Yes (PR-based) |
|
|
27
|
+
| **Flexibility** | Prescriptive | Configurable | Most granular |
|
|
28
|
+
| **Weekly Downloads** | ~1.9M | ~500K | ~630K |
|
|
29
|
+
| **Best For** | Single packages, CI/CD | Google ecosystem | Monorepos |
|
|
30
|
+
|
|
31
|
+
### semantic-release
|
|
32
|
+
|
|
33
|
+
**Pros:**
|
|
34
|
+
|
|
35
|
+
- Fully automated releases based on conventional commits
|
|
36
|
+
- Excellent documentation and plugin ecosystem
|
|
37
|
+
- Generates changelogs automatically
|
|
38
|
+
- Battle-tested with 23,000+ GitHub stars
|
|
39
|
+
|
|
40
|
+
**Cons:**
|
|
41
|
+
|
|
42
|
+
- No native monorepo support (requires community plugins)
|
|
43
|
+
- Commit message mistakes can trigger unintended releases
|
|
44
|
+
- Less control over release timing
|
|
45
|
+
|
|
46
|
+
**Configuration Example:**
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
// .releaserc.js
|
|
50
|
+
module.exports = {
|
|
51
|
+
branches: ["main", { name: "beta", prerelease: true }],
|
|
52
|
+
plugins: [
|
|
53
|
+
"@semantic-release/commit-analyzer",
|
|
54
|
+
"@semantic-release/release-notes-generator",
|
|
55
|
+
"@semantic-release/changelog",
|
|
56
|
+
"@semantic-release/npm",
|
|
57
|
+
"@semantic-release/github",
|
|
58
|
+
"@semantic-release/git",
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### release-please
|
|
64
|
+
|
|
65
|
+
**Pros:**
|
|
66
|
+
|
|
67
|
+
- Created and maintained by Google
|
|
68
|
+
- PR-based workflow allows human review before release
|
|
69
|
+
- Native monorepo support
|
|
70
|
+
- More flexible than semantic-release
|
|
71
|
+
|
|
72
|
+
**Cons:**
|
|
73
|
+
|
|
74
|
+
- Requires manual PR merge to trigger release
|
|
75
|
+
- Smaller community than semantic-release
|
|
76
|
+
- Google-centric defaults
|
|
77
|
+
|
|
78
|
+
### Changesets (Recommended for Monorepos)
|
|
79
|
+
|
|
80
|
+
**Pros:**
|
|
81
|
+
|
|
82
|
+
- Built specifically for monorepos
|
|
83
|
+
- Decouples versioning from commit messages
|
|
84
|
+
- Changes can be edited after committing
|
|
85
|
+
- Manages inter-package dependencies automatically
|
|
86
|
+
- Used by major projects (Pnpm, Turborepo, etc.)
|
|
87
|
+
|
|
88
|
+
**Cons:**
|
|
89
|
+
|
|
90
|
+
- Requires explicit changeset file creation
|
|
91
|
+
- More manual steps than semantic-release
|
|
92
|
+
- Learning curve for teams used to automatic versioning
|
|
93
|
+
|
|
94
|
+
**Setup with pnpm:**
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pnpm add -D @changesets/cli @changesets/changelog-github
|
|
98
|
+
pnpm changeset init
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
// .changeset/config.json
|
|
103
|
+
{
|
|
104
|
+
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
|
|
105
|
+
"changelog": ["@changesets/changelog-github", { "repo": "your-org/repo" }],
|
|
106
|
+
"commit": false,
|
|
107
|
+
"access": "public",
|
|
108
|
+
"baseBranch": "main"
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Verdict: Choose Based on Your Needs
|
|
113
|
+
|
|
114
|
+
| Scenario | Recommendation |
|
|
115
|
+
| ------------------------------------ | ---------------------------- |
|
|
116
|
+
| Single package, want full automation | semantic-release |
|
|
117
|
+
| Monorepo with multiple packages | **Changesets** |
|
|
118
|
+
| Need human approval before releases | release-please or Changesets |
|
|
119
|
+
| Google Cloud ecosystem | release-please |
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 2. CI/CD Pipeline Design
|
|
124
|
+
|
|
125
|
+
### Modern GitHub Actions Architecture
|
|
126
|
+
|
|
127
|
+
```yaml
|
|
128
|
+
# .github/workflows/ci.yml
|
|
129
|
+
name: CI
|
|
130
|
+
|
|
131
|
+
on:
|
|
132
|
+
push:
|
|
133
|
+
branches: [main]
|
|
134
|
+
pull_request:
|
|
135
|
+
branches: [main]
|
|
136
|
+
|
|
137
|
+
jobs:
|
|
138
|
+
# Job 1: Lint and Type Check (fast feedback)
|
|
139
|
+
lint:
|
|
140
|
+
runs-on: ubuntu-latest
|
|
141
|
+
steps:
|
|
142
|
+
- uses: actions/checkout@v4
|
|
143
|
+
- uses: pnpm/action-setup@v4
|
|
144
|
+
with:
|
|
145
|
+
version: 10
|
|
146
|
+
- uses: actions/setup-node@v6
|
|
147
|
+
with:
|
|
148
|
+
node-version: "22"
|
|
149
|
+
cache: "pnpm"
|
|
150
|
+
- run: pnpm install --frozen-lockfile
|
|
151
|
+
- run: pnpm lint
|
|
152
|
+
- run: pnpm typecheck
|
|
153
|
+
|
|
154
|
+
# Job 2: Test Matrix (parallel)
|
|
155
|
+
test:
|
|
156
|
+
runs-on: ubuntu-latest
|
|
157
|
+
strategy:
|
|
158
|
+
matrix:
|
|
159
|
+
node-version: [20, 22, 24]
|
|
160
|
+
fail-fast: false
|
|
161
|
+
steps:
|
|
162
|
+
- uses: actions/checkout@v4
|
|
163
|
+
- uses: pnpm/action-setup@v4
|
|
164
|
+
with:
|
|
165
|
+
version: 10
|
|
166
|
+
- uses: actions/setup-node@v6
|
|
167
|
+
with:
|
|
168
|
+
node-version: ${{ matrix.node-version }}
|
|
169
|
+
cache: "pnpm"
|
|
170
|
+
- run: pnpm install --frozen-lockfile
|
|
171
|
+
- run: pnpm test
|
|
172
|
+
|
|
173
|
+
# Job 3: Build
|
|
174
|
+
build:
|
|
175
|
+
runs-on: ubuntu-latest
|
|
176
|
+
needs: [lint, test]
|
|
177
|
+
steps:
|
|
178
|
+
- uses: actions/checkout@v4
|
|
179
|
+
- uses: pnpm/action-setup@v4
|
|
180
|
+
with:
|
|
181
|
+
version: 10
|
|
182
|
+
- uses: actions/setup-node@v6
|
|
183
|
+
with:
|
|
184
|
+
node-version: "22"
|
|
185
|
+
cache: "pnpm"
|
|
186
|
+
- run: pnpm install --frozen-lockfile
|
|
187
|
+
- run: pnpm build
|
|
188
|
+
- uses: actions/upload-artifact@v4
|
|
189
|
+
with:
|
|
190
|
+
name: build-output
|
|
191
|
+
path: dist/
|
|
192
|
+
|
|
193
|
+
# Job 4: Publish (only on main)
|
|
194
|
+
publish:
|
|
195
|
+
if: github.ref == 'refs/heads/main'
|
|
196
|
+
runs-on: ubuntu-latest
|
|
197
|
+
needs: [build]
|
|
198
|
+
permissions:
|
|
199
|
+
contents: write
|
|
200
|
+
id-token: write # Required for OIDC
|
|
201
|
+
steps:
|
|
202
|
+
- uses: actions/checkout@v4
|
|
203
|
+
- uses: pnpm/action-setup@v4
|
|
204
|
+
with:
|
|
205
|
+
version: 10
|
|
206
|
+
- uses: actions/setup-node@v6
|
|
207
|
+
with:
|
|
208
|
+
node-version: "22"
|
|
209
|
+
cache: "pnpm"
|
|
210
|
+
registry-url: "https://registry.npmjs.org"
|
|
211
|
+
- run: pnpm install --frozen-lockfile
|
|
212
|
+
- uses: actions/download-artifact@v4
|
|
213
|
+
with:
|
|
214
|
+
name: build-output
|
|
215
|
+
path: dist/
|
|
216
|
+
- run: pnpm publish --access public --no-git-checks
|
|
217
|
+
env:
|
|
218
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Caching Best Practices
|
|
222
|
+
|
|
223
|
+
**Option 1: Built-in setup-node caching (Recommended)**
|
|
224
|
+
|
|
225
|
+
```yaml
|
|
226
|
+
- uses: actions/setup-node@v6
|
|
227
|
+
with:
|
|
228
|
+
node-version: "22"
|
|
229
|
+
cache: "pnpm"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Option 2: pnpm/action-setup with caching**
|
|
233
|
+
|
|
234
|
+
```yaml
|
|
235
|
+
- uses: pnpm/action-setup@v4
|
|
236
|
+
with:
|
|
237
|
+
version: 10
|
|
238
|
+
run_install: false
|
|
239
|
+
- name: Get pnpm store directory
|
|
240
|
+
shell: bash
|
|
241
|
+
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
|
242
|
+
- uses: actions/cache@v4
|
|
243
|
+
with:
|
|
244
|
+
path: ${{ env.STORE_PATH }}
|
|
245
|
+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
246
|
+
restore-keys: ${{ runner.os }}-pnpm-store-
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Matrix Strategy Optimization
|
|
250
|
+
|
|
251
|
+
```yaml
|
|
252
|
+
strategy:
|
|
253
|
+
matrix:
|
|
254
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
255
|
+
node: [20, 22]
|
|
256
|
+
exclude:
|
|
257
|
+
# Skip Windows + Node 20 (known issues)
|
|
258
|
+
- os: windows-latest
|
|
259
|
+
node: 20
|
|
260
|
+
max-parallel: 4 # Control concurrent jobs
|
|
261
|
+
fail-fast: false # Continue other jobs if one fails
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Performance Tips
|
|
265
|
+
|
|
266
|
+
1. **Run independent jobs in parallel** - lint, test, and build can often run concurrently
|
|
267
|
+
2. **Use `fail-fast: false`** - See all failures, not just the first
|
|
268
|
+
3. **Cache aggressively** - pnpm store, build artifacts, test caches
|
|
269
|
+
4. **Use `actions/upload-artifact`** - Pass build outputs between jobs
|
|
270
|
+
5. **Consider GitHub's larger runners** - For monorepos, 4-core runners can be worth it
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## 3. NPM Provenance & Supply Chain Security
|
|
275
|
+
|
|
276
|
+
### Critical Changes in 2025-2026
|
|
277
|
+
|
|
278
|
+
**Classic Tokens Deprecated (December 9, 2025)**
|
|
279
|
+
|
|
280
|
+
- All classic npm tokens have been permanently revoked
|
|
281
|
+
- New granular tokens have maximum 90-day validity
|
|
282
|
+
- 2FA is now mandatory for local publishing
|
|
283
|
+
|
|
284
|
+
**OIDC Trusted Publishing (Generally Available July 2025)**
|
|
285
|
+
|
|
286
|
+
- No tokens to manage, rotate, or risk exposing
|
|
287
|
+
- Short-lived, cryptographically-signed credentials
|
|
288
|
+
- Automatic provenance attestations
|
|
289
|
+
|
|
290
|
+
### Setting Up Trusted Publishing
|
|
291
|
+
|
|
292
|
+
**Step 1: Configure npm Package**
|
|
293
|
+
|
|
294
|
+
1. Go to npmjs.com > Your Package > Settings > Trusted Publishers
|
|
295
|
+
2. Add GitHub Actions as trusted publisher:
|
|
296
|
+
- Organization/User: `your-github-org`
|
|
297
|
+
- Repository: `your-repo`
|
|
298
|
+
- Workflow file: `release.yml` (the file that triggers publish)
|
|
299
|
+
- Environment: `production` (optional, but recommended)
|
|
300
|
+
|
|
301
|
+
**Step 2: Configure GitHub Actions**
|
|
302
|
+
|
|
303
|
+
```yaml
|
|
304
|
+
# .github/workflows/release.yml
|
|
305
|
+
name: Release
|
|
306
|
+
|
|
307
|
+
on:
|
|
308
|
+
push:
|
|
309
|
+
tags:
|
|
310
|
+
- "v*"
|
|
311
|
+
|
|
312
|
+
jobs:
|
|
313
|
+
publish:
|
|
314
|
+
runs-on: ubuntu-latest
|
|
315
|
+
environment: production # Must match npm trusted publisher config
|
|
316
|
+
permissions:
|
|
317
|
+
contents: write
|
|
318
|
+
id-token: write # CRITICAL: Required for OIDC
|
|
319
|
+
|
|
320
|
+
steps:
|
|
321
|
+
- uses: actions/checkout@v4
|
|
322
|
+
|
|
323
|
+
- uses: pnpm/action-setup@v4
|
|
324
|
+
with:
|
|
325
|
+
version: 10
|
|
326
|
+
|
|
327
|
+
- uses: actions/setup-node@v6
|
|
328
|
+
with:
|
|
329
|
+
node-version: "22"
|
|
330
|
+
cache: "pnpm"
|
|
331
|
+
registry-url: "https://registry.npmjs.org"
|
|
332
|
+
|
|
333
|
+
- run: pnpm install --frozen-lockfile
|
|
334
|
+
- run: pnpm build
|
|
335
|
+
|
|
336
|
+
# No NPM_TOKEN needed with OIDC!
|
|
337
|
+
- run: npm publish --access public
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Important:** With trusted publishing, provenance attestations are generated automatically - no `--provenance` flag needed.
|
|
341
|
+
|
|
342
|
+
### Verifying Provenance
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
# Check package provenance
|
|
346
|
+
npm audit signatures
|
|
347
|
+
|
|
348
|
+
# View provenance details on npmjs.com
|
|
349
|
+
# Look for "Provenance" badge on package page
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Common OIDC Troubleshooting
|
|
353
|
+
|
|
354
|
+
| Issue | Solution |
|
|
355
|
+
| ------------------------ | ---------------------------------------------------------- |
|
|
356
|
+
| 404 on publish | Organization/repo name must match exactly (case-sensitive) |
|
|
357
|
+
| OIDC token rejected | Verify workflow filename matches npm config |
|
|
358
|
+
| Reusable workflow fails | Reference the _caller_ workflow, not the reusable one |
|
|
359
|
+
| Provenance not appearing | Ensure `id-token: write` permission is set |
|
|
360
|
+
|
|
361
|
+
### Security Best Practices
|
|
362
|
+
|
|
363
|
+
1. **Use environments** - Create a `production` environment with required reviewers
|
|
364
|
+
2. **Pin action versions** - Use SHA hashes, not tags (`actions/checkout@a1b2c3d`)
|
|
365
|
+
3. **Minimize dependencies** - Each dependency increases attack surface
|
|
366
|
+
4. **Disable lifecycle scripts in CI** - `pnpm install --ignore-scripts`
|
|
367
|
+
5. **Use lockfiles** - Always commit `pnpm-lock.yaml`
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## 4. Dual ESM/CJS Publishing
|
|
372
|
+
|
|
373
|
+
### Is Dual Publishing Still Necessary in 2026?
|
|
374
|
+
|
|
375
|
+
**Yes, for maximum compatibility.** While ESM adoption continues to grow, many enterprise codebases and tools still require CJS support.
|
|
376
|
+
|
|
377
|
+
### Recommended Approach: ESM-First with CJS Fallback
|
|
378
|
+
|
|
379
|
+
```json
|
|
380
|
+
// package.json
|
|
381
|
+
{
|
|
382
|
+
"name": "your-package",
|
|
383
|
+
"version": "1.0.0",
|
|
384
|
+
"type": "module",
|
|
385
|
+
"exports": {
|
|
386
|
+
".": {
|
|
387
|
+
"import": {
|
|
388
|
+
"types": "./dist/index.d.ts",
|
|
389
|
+
"default": "./dist/index.js"
|
|
390
|
+
},
|
|
391
|
+
"require": {
|
|
392
|
+
"types": "./dist/index.d.cts",
|
|
393
|
+
"default": "./dist/index.cjs"
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
"main": "./dist/index.cjs",
|
|
398
|
+
"module": "./dist/index.js",
|
|
399
|
+
"types": "./dist/index.d.ts"
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Build Tool Comparison
|
|
404
|
+
|
|
405
|
+
| Tool | Status | Engine | Best For |
|
|
406
|
+
| ---------- | ------------------- | --------------- | ----------------- |
|
|
407
|
+
| **tsdown** | Active, recommended | Rolldown (Rust) | New projects |
|
|
408
|
+
| tsup | Maintenance mode | esbuild | Existing projects |
|
|
409
|
+
| unbuild | Active | Rollup | Nuxt ecosystem |
|
|
410
|
+
|
|
411
|
+
### tsdown Configuration (Recommended)
|
|
412
|
+
|
|
413
|
+
**Note:** tsup is no longer actively maintained and recommends tsdown as its successor.
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
// tsdown.config.ts
|
|
417
|
+
import { defineConfig } from "tsdown";
|
|
418
|
+
|
|
419
|
+
export default defineConfig({
|
|
420
|
+
entry: ["src/index.ts"],
|
|
421
|
+
format: ["esm", "cjs"],
|
|
422
|
+
dts: true,
|
|
423
|
+
clean: true,
|
|
424
|
+
sourcemap: true,
|
|
425
|
+
minify: false, // Let consumers minify
|
|
426
|
+
target: "node18",
|
|
427
|
+
});
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Migration from tsup to tsdown
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
# Automatic migration
|
|
434
|
+
npx tsdown migrate
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Handling ESM/CJS Gotchas
|
|
438
|
+
|
|
439
|
+
**Problem:** `__dirname` and `__filename` don't exist in ESM
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
// Solution: Use import.meta
|
|
443
|
+
import { fileURLToPath } from "node:url";
|
|
444
|
+
import { dirname } from "node:path";
|
|
445
|
+
|
|
446
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
447
|
+
const __dirname = dirname(__filename);
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
**Problem:** `require` doesn't exist in ESM
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
// Solution: Use createRequire
|
|
454
|
+
import { createRequire } from "node:module";
|
|
455
|
+
const require = createRequire(import.meta.url);
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Validation
|
|
459
|
+
|
|
460
|
+
Use [Are The Types Wrong?](https://arethetypeswrong.github.io/) to validate your package exports:
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
npx @arethetypeswrong/cli your-package
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## 5. Pre-release & Canary Workflows
|
|
469
|
+
|
|
470
|
+
### Release Channels Overview
|
|
471
|
+
|
|
472
|
+
| Channel | Use Case | npm Tag | Version Example |
|
|
473
|
+
| ------- | --------------- | -------- | --------------------- |
|
|
474
|
+
| Stable | Production | `latest` | `1.0.0` |
|
|
475
|
+
| Beta | Feature testing | `beta` | `1.1.0-beta.1` |
|
|
476
|
+
| Alpha | Early testing | `alpha` | `1.1.0-alpha.1` |
|
|
477
|
+
| Canary | CI builds | `canary` | `0.0.0-canary.abc123` |
|
|
478
|
+
| Next | Major previews | `next` | `2.0.0-next.1` |
|
|
479
|
+
|
|
480
|
+
### Changesets Pre-release Mode
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
# Enter pre-release mode
|
|
484
|
+
pnpm changeset pre enter beta
|
|
485
|
+
|
|
486
|
+
# Create changesets and version as normal
|
|
487
|
+
pnpm changeset
|
|
488
|
+
pnpm changeset version # Creates 1.0.1-beta.0
|
|
489
|
+
|
|
490
|
+
# Exit pre-release mode
|
|
491
|
+
pnpm changeset pre exit
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### semantic-release Branch Configuration
|
|
495
|
+
|
|
496
|
+
```javascript
|
|
497
|
+
// .releaserc.js
|
|
498
|
+
module.exports = {
|
|
499
|
+
branches: [
|
|
500
|
+
"main",
|
|
501
|
+
{ name: "beta", prerelease: true },
|
|
502
|
+
{ name: "alpha", prerelease: true },
|
|
503
|
+
{ name: "next", prerelease: true },
|
|
504
|
+
],
|
|
505
|
+
};
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Canary Releases with GitHub Actions
|
|
509
|
+
|
|
510
|
+
```yaml
|
|
511
|
+
# .github/workflows/canary.yml
|
|
512
|
+
name: Canary Release
|
|
513
|
+
|
|
514
|
+
on:
|
|
515
|
+
push:
|
|
516
|
+
branches: [main]
|
|
517
|
+
|
|
518
|
+
jobs:
|
|
519
|
+
canary:
|
|
520
|
+
runs-on: ubuntu-latest
|
|
521
|
+
permissions:
|
|
522
|
+
id-token: write
|
|
523
|
+
steps:
|
|
524
|
+
- uses: actions/checkout@v4
|
|
525
|
+
|
|
526
|
+
- uses: pnpm/action-setup@v4
|
|
527
|
+
with:
|
|
528
|
+
version: 10
|
|
529
|
+
|
|
530
|
+
- uses: actions/setup-node@v6
|
|
531
|
+
with:
|
|
532
|
+
node-version: "22"
|
|
533
|
+
cache: "pnpm"
|
|
534
|
+
registry-url: "https://registry.npmjs.org"
|
|
535
|
+
|
|
536
|
+
- run: pnpm install --frozen-lockfile
|
|
537
|
+
- run: pnpm build
|
|
538
|
+
|
|
539
|
+
# Set canary version
|
|
540
|
+
- name: Set canary version
|
|
541
|
+
run: |
|
|
542
|
+
SHORT_SHA=$(git rev-parse --short HEAD)
|
|
543
|
+
npm version 0.0.0-canary.${SHORT_SHA} --no-git-tag-version
|
|
544
|
+
|
|
545
|
+
- run: npm publish --tag canary --access public
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Installing Pre-releases
|
|
549
|
+
|
|
550
|
+
```bash
|
|
551
|
+
# Install specific channel
|
|
552
|
+
npm install your-package@beta
|
|
553
|
+
npm install your-package@canary
|
|
554
|
+
npm install your-package@next
|
|
555
|
+
|
|
556
|
+
# Check available versions
|
|
557
|
+
npm view your-package versions
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## 6. Bun Migration Analysis
|
|
563
|
+
|
|
564
|
+
### Performance Benchmarks (2026)
|
|
565
|
+
|
|
566
|
+
| Metric | Bun | Node.js | Improvement |
|
|
567
|
+
| ------------------------ | ----------- | -------- | ------------- |
|
|
568
|
+
| HTTP Requests/sec | 52,000 | 13,000 | **4x faster** |
|
|
569
|
+
| Package Install | 30x faster | baseline | Significant |
|
|
570
|
+
| Test Suite (Jest-compat) | 20x faster | baseline | Significant |
|
|
571
|
+
| Memory Usage | 30-40% less | baseline | Notable |
|
|
572
|
+
| Cold Start | Sub-50ms | 200ms+ | **4x faster** |
|
|
573
|
+
|
|
574
|
+
### API Compatibility Status
|
|
575
|
+
|
|
576
|
+
- **Node.js API Coverage:** >95%
|
|
577
|
+
- **npm Package Compatibility:** ~95%
|
|
578
|
+
- **Native Module Support:** ~34% (major limitation)
|
|
579
|
+
|
|
580
|
+
### When Bun Makes Sense
|
|
581
|
+
|
|
582
|
+
**Ideal for Bun:**
|
|
583
|
+
|
|
584
|
+
- New TypeScript projects (native .ts execution)
|
|
585
|
+
- Serverless/edge deployments (fast cold starts)
|
|
586
|
+
- Development tooling (tests, scripts)
|
|
587
|
+
- High-performance APIs
|
|
588
|
+
- CI pipelines (30-minute builds to 5 minutes reported)
|
|
589
|
+
|
|
590
|
+
**Stick with Node.js:**
|
|
591
|
+
|
|
592
|
+
- Heavy native module dependencies (bcrypt, sharp, etc.)
|
|
593
|
+
- Enterprise compliance requirements
|
|
594
|
+
- Existing large codebases
|
|
595
|
+
- Windows-primary environments
|
|
596
|
+
- Zero-tolerance for edge-case bugs
|
|
597
|
+
|
|
598
|
+
### Hybrid Approach (Recommended)
|
|
599
|
+
|
|
600
|
+
```json
|
|
601
|
+
// package.json
|
|
602
|
+
{
|
|
603
|
+
"scripts": {
|
|
604
|
+
"dev": "bun run src/index.ts",
|
|
605
|
+
"test": "bun test",
|
|
606
|
+
"build": "bun run build.ts",
|
|
607
|
+
"start": "node dist/index.js"
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
Use Bun for:
|
|
613
|
+
|
|
614
|
+
- Development (`bun run`)
|
|
615
|
+
- Testing (`bun test`)
|
|
616
|
+
- Building (`bun build`)
|
|
617
|
+
|
|
618
|
+
Use Node.js for:
|
|
619
|
+
|
|
620
|
+
- Production runtime
|
|
621
|
+
- Native module compatibility
|
|
622
|
+
- Enterprise deployments
|
|
623
|
+
|
|
624
|
+
### CI with Bun
|
|
625
|
+
|
|
626
|
+
```yaml
|
|
627
|
+
# .github/workflows/ci-bun.yml
|
|
628
|
+
jobs:
|
|
629
|
+
test:
|
|
630
|
+
runs-on: ubuntu-latest
|
|
631
|
+
steps:
|
|
632
|
+
- uses: actions/checkout@v4
|
|
633
|
+
- uses: oven-sh/setup-bun@v2
|
|
634
|
+
with:
|
|
635
|
+
bun-version: latest
|
|
636
|
+
- run: bun install
|
|
637
|
+
- run: bun test
|
|
638
|
+
- run: bun run build
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
### Bun Verdict
|
|
642
|
+
|
|
643
|
+
**Should You Migrate in 2026?**
|
|
644
|
+
|
|
645
|
+
| Project Type | Recommendation |
|
|
646
|
+
| ------------------------- | ------------------------------- |
|
|
647
|
+
| New greenfield project | **Yes** - Try Bun, excellent DX |
|
|
648
|
+
| Existing Node.js project | **Cautious** - Hybrid approach |
|
|
649
|
+
| Heavy native dependencies | **No** - Stick with Node.js |
|
|
650
|
+
| Enterprise/compliance | **No** - Node.js remains safer |
|
|
651
|
+
| Performance-critical APIs | **Yes** - Bun excels here |
|
|
652
|
+
| Serverless/Edge | **Yes** - Fast cold starts |
|
|
653
|
+
|
|
654
|
+
**Bottom Line:** Bun is production-ready for many use cases in 2026, especially after Anthropic's acquisition brought enterprise stability. However, the 34% native dependency compatibility rate means thorough testing is essential. The hybrid approach - Bun for dev/test, Node.js for production - offers the best of both worlds.
|
|
655
|
+
|
|
656
|
+
---
|
|
657
|
+
|
|
658
|
+
## 7. Decision Framework
|
|
659
|
+
|
|
660
|
+
### Release Tool Selection
|
|
661
|
+
|
|
662
|
+
```
|
|
663
|
+
START
|
|
664
|
+
|
|
|
665
|
+
v
|
|
666
|
+
Is this a monorepo?
|
|
667
|
+
|
|
|
668
|
+
+--YES--> Use Changesets
|
|
669
|
+
|
|
|
670
|
+
+--NO--> Do you want fully automated releases?
|
|
671
|
+
|
|
|
672
|
+
+--YES--> Use semantic-release
|
|
673
|
+
|
|
|
674
|
+
+--NO--> Do you use Google Cloud?
|
|
675
|
+
|
|
|
676
|
+
+--YES--> Use release-please
|
|
677
|
+
|
|
|
678
|
+
+--NO--> Use Changesets or release-please
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
### CI/CD Architecture Decision
|
|
682
|
+
|
|
683
|
+
```
|
|
684
|
+
START
|
|
685
|
+
|
|
|
686
|
+
v
|
|
687
|
+
How many packages?
|
|
688
|
+
|
|
|
689
|
+
+--1 package--> Simple pipeline: lint -> test -> build -> publish
|
|
690
|
+
|
|
|
691
|
+
+--Monorepo--> Matrix builds + Changesets
|
|
692
|
+
|
|
|
693
|
+
v
|
|
694
|
+
Use artifact passing between jobs
|
|
695
|
+
Use dependency caching
|
|
696
|
+
Consider nx or turborepo for build orchestration
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### ESM/CJS Decision
|
|
700
|
+
|
|
701
|
+
```
|
|
702
|
+
START
|
|
703
|
+
|
|
|
704
|
+
v
|
|
705
|
+
Who are your users?
|
|
706
|
+
|
|
|
707
|
+
+--Modern bundler users (Vite, etc.)--> ESM-only is acceptable
|
|
708
|
+
|
|
|
709
|
+
+--Mixed/Enterprise/Unknown--> Dual ESM+CJS with tsdown
|
|
710
|
+
|
|
|
711
|
+
+--Legacy CJS consumers--> CJS primary with ESM wrapper
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
### Bun Migration Decision
|
|
715
|
+
|
|
716
|
+
```
|
|
717
|
+
START
|
|
718
|
+
|
|
|
719
|
+
v
|
|
720
|
+
Do you have native module dependencies?
|
|
721
|
+
|
|
|
722
|
+
+--YES--> Do alternatives exist?
|
|
723
|
+
| |
|
|
724
|
+
| +--YES--> Consider Bun with alternatives
|
|
725
|
+
| +--NO--> Stick with Node.js
|
|
726
|
+
|
|
|
727
|
+
+--NO--> Is this a new project?
|
|
728
|
+
|
|
|
729
|
+
+--YES--> Use Bun
|
|
730
|
+
|
|
|
731
|
+
+--NO--> Is performance critical?
|
|
732
|
+
|
|
|
733
|
+
+--YES--> Hybrid approach (Bun dev, Node prod)
|
|
734
|
+
+--NO--> Stay with Node.js unless migration is easy
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
---
|
|
738
|
+
|
|
739
|
+
## Quick Reference: Recommended Stack 2026
|
|
740
|
+
|
|
741
|
+
| Component | Recommendation | Alternative |
|
|
742
|
+
| ---------------------- | ------------------------ | ------------------------------ |
|
|
743
|
+
| **Package Manager** | pnpm | Bun (for speed) |
|
|
744
|
+
| **Release Automation** | Changesets | semantic-release (single pkg) |
|
|
745
|
+
| **Build Tool** | tsdown | unbuild (Nuxt ecosystem) |
|
|
746
|
+
| **Publishing Auth** | OIDC Trusted Publishers | Granular tokens (90-day max) |
|
|
747
|
+
| **Module Format** | ESM-first + CJS fallback | ESM-only (modern consumers) |
|
|
748
|
+
| **Runtime (dev)** | Bun | Node.js |
|
|
749
|
+
| **Runtime (prod)** | Node.js | Bun (if no native deps) |
|
|
750
|
+
| **CI Platform** | GitHub Actions | GitLab CI (also supports OIDC) |
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
754
|
+
## Sources
|
|
755
|
+
|
|
756
|
+
### Release Automation
|
|
757
|
+
|
|
758
|
+
- [The Ultimate Guide to NPM Release Automation](https://oleksiipopov.com/blog/npm-release-automation/)
|
|
759
|
+
- [Using Changesets with pnpm](https://pnpm.io/next/using-changesets)
|
|
760
|
+
- [semantic-release GitHub Actions](https://semantic-release.gitbook.io/semantic-release/recipes/ci-configurations/github-actions)
|
|
761
|
+
- [Changesets vs Semantic Release](https://brianschiller.com/blog/2023/09/18/changesets-vs-semantic-release/)
|
|
762
|
+
- [Release-please vs semantic-release](https://www.hamzak.xyz/blog-posts/release-please-vs-semantic-release)
|
|
763
|
+
|
|
764
|
+
### Security & Provenance
|
|
765
|
+
|
|
766
|
+
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/trusted-publishers/)
|
|
767
|
+
- [npm Provenance Statements](https://docs.npmjs.com/generating-provenance-statements/)
|
|
768
|
+
- [npm trusted publishing with OIDC GA](https://github.blog/changelog/2025-07-31-npm-trusted-publishing-with-oidc-is-generally-available/)
|
|
769
|
+
- [How to set up trusted publishing for npm](https://remarkablemark.org/blog/2025/12/19/npm-trusted-publishing/)
|
|
770
|
+
- [npm Security Best Practices](https://github.com/lirantal/npm-security-best-practices)
|
|
771
|
+
|
|
772
|
+
### CI/CD & Caching
|
|
773
|
+
|
|
774
|
+
- [GitHub Actions setup-node](https://github.com/actions/setup-node)
|
|
775
|
+
- [pnpm action-setup](https://github.com/pnpm/action-setup)
|
|
776
|
+
- [Matrix Builds with GitHub Actions](https://www.blacksmith.sh/blog/matrix-builds-with-github-actions)
|
|
777
|
+
- [GitHub Actions Matrix Strategy](https://codefresh.io/learn/github-actions/github-actions-matrix/)
|
|
778
|
+
|
|
779
|
+
### ESM/CJS Publishing
|
|
780
|
+
|
|
781
|
+
- [Ship ESM & CJS in one Package](https://antfu.me/posts/publish-esm-and-cjs)
|
|
782
|
+
- [TypeScript in 2025 with ESM and CJS](https://lirantal.com/blog/typescript-in-2025-with-esm-and-cjs-npm-publishing)
|
|
783
|
+
- [Dual Publishing ESM and CJS with tsup](https://johnnyreilly.com/dual-publishing-esm-cjs-modules-with-tsup-and-are-the-types-wrong)
|
|
784
|
+
- [tsdown - Migrate from tsup](https://tsdown.dev/guide/migrate-from-tsup)
|
|
785
|
+
|
|
786
|
+
### Bun Analysis
|
|
787
|
+
|
|
788
|
+
- [Bun vs Node.js 2025 Performance Guide](https://strapi.io/blog/bun-vs-nodejs-performance-comparison-guide)
|
|
789
|
+
- [Bun vs Node.js vs Deno: 2026 Runtime Comparison](https://asepalazhari.com/blog/bun-vs-nodejs-vs-deno-runtime-comparison-2026)
|
|
790
|
+
- [Why We Ditched Node for Bun in 2026](https://dev.to/rayenmabrouk/why-we-ditched-node-for-bun-in-2026-and-why-you-should-too-48kg)
|
|
791
|
+
- [Bun Package Manager Reality Check 2026](https://vocal.media/01/bun-package-manager-reality-check-2026)
|
|
792
|
+
- [Bun Node.js Compatibility](https://bun.com/docs/runtime/nodejs-compat)
|