Skip to content

Replace Make + lerna with Bun scripts#309

Merged
brianmhunt merged 10 commits intomainfrom
modern-tooling/phase-3-replace-make-lerna
Apr 15, 2026
Merged

Replace Make + lerna with Bun scripts#309
brianmhunt merged 10 commits intomainfrom
modern-tooling/phase-3-replace-make-lerna

Conversation

@brianmhunt
Copy link
Copy Markdown
Member

@brianmhunt brianmhunt commented Apr 15, 2026

Summary

Eliminate make and lerna as dependencies. All commands are now bun run <script>.

What changed

Deleted (72 files, -1501 lines):

  • Root Makefile
  • tools/build.mk (shared build config)
  • 28 per-package Makefile files
  • lerna.json
  • lerna from devDependencies
  • Dead electron.yaml and saucelabs.yaml workflows
  • tools/template/Makefile

Created:

  • tools/build.ts β€” shared esbuild build script (~60 lines)
  • plans/replace-make-lerna.md β€” migration plan

Modified:

  • 28 package.json files: added "build": "bun ../../tools/build.ts"
  • Root package.json: added scripts, removed lerna
  • builds/knockout/package.json: tko.iifeGlobalName: "ko", tko.buildMode: "browser-only"
  • builds/reference/package.json: tko.buildMode: "browser-only"
  • 6 CI workflows: make β†’ bun run build
  • AGENTS.md: updated all build commands

New commands

bun run build      # Build all packages
bun run test       # Run all tests
bun run lint       # ESLint
bun run format     # Prettier check
bun run tsc        # Typecheck
bun run clean      # Remove dist/

Test plan

  • bun run build β€” 27 packages build
  • bun run test β€” 2679 passed, 143 files
  • bun run tsc β€” 0 errors

πŸ€– Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Replaced Make/Lerna orchestration with Bun-based workspace scripts and added package-level build scripts.
    • CI workflows now read Bun version from repo config and run Bun scripts; several legacy CI jobs and Make-based tooling were removed.
    • Root tooling simplified to a single Bun-driven build script.
  • Documentation

    • Docs and migration plans updated with Bun-based commands and developer guidance.

Delete Makefile, tools/build.mk, lerna.json, 28 per-package
Makefiles, and dead electron/saucelabs workflows.

Create tools/build.ts β€” shared esbuild build script that reads
package.json for name/version/config. Each package gets a
"build": "bun ../../tools/build.ts" script.

Root package.json scripts replace all Make targets:
  bun run build    β€” build all packages via bun --filter
  bun run test     β€” vitest
  bun run lint     β€” eslint
  bun run format   β€” prettier
  bun run tsc      β€” typecheck
  bun run clean    β€” rm dist/

Eliminates make and lerna as dependencies. All commands are now
`bun run <script>`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 15, 2026 13:34
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 15, 2026

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3d9f4785-29ef-455c-93d3-6576647711c7

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 4b46b4e and c4760bf.

πŸ“’ Files selected for processing (1)
  • AGENTS.md
βœ… Files skipped from review due to trivial changes (1)
  • AGENTS.md

πŸ“ Walkthrough

Walkthrough

Replaces Makefile/Lerna build orchestration with Bun workspaces and a shared Bun-based build script: removes many Makefiles and tools/build.mk/lerna.json, adds tools/build.ts, injects scripts.build into package manifests, and updates CI workflows and docs to use Bun (bun run build) instead of Make.

Changes

Cohort / File(s) Summary
CI workflows
\.github/workflows/...
\.github/workflows/deploy-docs.yml, \.github/workflows/lint-and-typecheck.yml, \.github/workflows/main-build.yml, \.github/workflows/publish-check.yml, \.github/workflows/release.yml, \.github/workflows/test-headless.yml
Configured Bun to read .tool-versions and replaced make invocations with bun run scripts; removed some make apt installs and adjusted steps (one removed headless test step in release).
Removed workflows
\.github/workflows/...
\.github/workflows/electron.yaml, \.github/workflows/saucelabs.yaml
Deleted two legacy/disabled CI workflow files.
Root orchestration & manifests
Makefile, tools/build.mk, lerna.json, package.json
Deleted root Makefiles and tools/build.mk and lerna.json; updated root package.json scripts to Bun commands and removed lerna devDependency.
New shared build script
tools/build.ts
Added Bun/TypeScript build orchestrator that reads package tko config and runs esbuild to emit ESM/MJS/CJS and optional browser IIFE bundles.
Per-package Makefile removals
builds/*/Makefile, packages/*/Makefile, tools/template/Makefile
Removed per-package Makefile includes that referenced tools/build.mk.
Per-package build scripts & configs
builds/knockout/package.json, builds/reference/package.json, packages/*/package.json, tko.io/package.json
Added scripts.build entries invoking bun ../../tools/build.ts; added tko config fields (iifeGlobalName, buildMode) where applicable; updated tko.io prebuild to use bun run build.
Docs & migration plan
AGENTS.md, plans/modern-tooling.md, plans/replace-make-lerna.md, tko.io/public/llms.txt
Updated docs and agent instructions to reflect Bun-based toolchain, added migration plan describing tools/build.ts behavior and checklist.
Minor CI cleanup
\.github/workflows/codeql-analysis.yml, \.github/workflows/deploy-docs.yml
Removed commented Make steps and adjusted Bun setup inputs.

Sequence Diagram(s)

sequenceDiagram
    participant CI as CI / Developer
    participant SetupBun as oven-sh/setup-bun
    participant BunCLI as bun (cli)
    participant Builder as tools/build.ts
    participant Esbuild as bunx esbuild
    participant FS as filesystem (dist/)
    CI->>SetupBun: configure Bun using `.tool-versions`
    CI->>BunCLI: run `bun run build` (per-package or CI step)
    BunCLI->>Builder: execute `tools/build.ts`
    Builder->>Esbuild: invoke esbuild builds (ESM / MJS / CJS [+ IIFE if browser])
    Esbuild->>FS: write outputs (`dist/*.js`, metafiles)
    Builder->>CI: exit status / logs
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • dvHuett

Poem

🐰
Bun hops in, scripts in tow,
Makefiles cleared where old winds blow.
Esbuild hums, dist folders gleam,
A tiny rabbit bakes the stream.
Hop, commit, and watch it grow πŸ₯•βœ¨

πŸš₯ Pre-merge checks | βœ… 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
βœ… Passed checks (2 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title 'Replace Make + lerna with Bun scripts' directly and clearly summarizes the main change in the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch modern-tooling/phase-3-replace-make-lerna

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d802855f12

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builds/knockout/Makefile
@@ -1,8 +0,0 @@

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve docs prebuild target after removing package Makefiles

Removing this Makefile breaks the docs build path because tko.io/package.json still runs cd ../builds/knockout && make browser (and similarly for builds/reference) in prebuild; with the file deleted, that command now fails with No rule to make target 'browser'. This is user-facing in docs workflows and local docs development, and Bun’s script lifecycle runs pre<script> hooks before bun run build, so tko.io builds will fail until prebuild is migrated off make.

Useful? React with πŸ‘Β / πŸ‘Ž.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the monorepo build/test/lint tooling away from Make + Lerna and standardizes orchestration through Bun workspace scripts, with a shared tools/build.ts wrapper around esbuild.

Changes:

  • Replace Make/Lerna orchestration with root package.json scripts and per-workspace build scripts.
  • Introduce tools/build.ts to centralize esbuild invocation for both package builds and browser bundle builds.
  • Update CI workflows and contributor docs/plans to reflect the new Bun-based commands; remove obsolete workflows/config.

Reviewed changes

Copilot reviewed 71 out of 72 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tools/template/Makefile Removed obsolete Makefile template include.
tools/build.ts New shared Bun-driven esbuild build script.
tools/build.mk Deleted shared Make-based build configuration.
plans/replace-make-lerna.md Added migration plan for replacing Make/Lerna with Bun scripts.
plans/modern-tooling.md Updated phase tracking/status for modern-tooling initiative.
packages/utils/package.json Added build script invoking tools/build.ts.
packages/utils/Makefile Deleted per-package Makefile.
packages/utils.parser/package.json Added build script invoking tools/build.ts.
packages/utils.parser/Makefile Deleted per-package Makefile.
packages/utils.jsx/package.json Added build script invoking tools/build.ts.
packages/utils.jsx/Makefile Deleted per-package Makefile.
packages/utils.functionrewrite/package.json Added build script invoking tools/build.ts.
packages/utils.functionrewrite/Makefile Deleted per-package Makefile.
packages/utils.component/package.json Added build script invoking tools/build.ts.
packages/utils.component/Makefile Deleted per-package Makefile.
packages/provider/package.json Added build script invoking tools/build.ts.
packages/provider/Makefile Deleted per-package Makefile.
packages/provider.virtual/package.json Added build script invoking tools/build.ts.
packages/provider.virtual/Makefile Deleted per-package Makefile.
packages/provider.native/package.json Added build script invoking tools/build.ts.
packages/provider.native/Makefile Deleted per-package Makefile.
packages/provider.mustache/package.json Added build script invoking tools/build.ts.
packages/provider.mustache/Makefile Deleted per-package Makefile.
packages/provider.multi/package.json Added build script invoking tools/build.ts.
packages/provider.multi/Makefile Deleted per-package Makefile.
packages/provider.databind/package.json Added build script invoking tools/build.ts.
packages/provider.databind/Makefile Deleted per-package Makefile.
packages/provider.component/package.json Added build script invoking tools/build.ts.
packages/provider.component/Makefile Deleted per-package Makefile.
packages/provider.bindingstring/package.json Added build script invoking tools/build.ts.
packages/provider.bindingstring/Makefile Deleted per-package Makefile.
packages/provider.attr/package.json Added build script invoking tools/build.ts.
packages/provider.attr/Makefile Deleted per-package Makefile.
packages/observable/package.json Added build script invoking tools/build.ts.
packages/observable/Makefile Deleted per-package Makefile.
packages/lifecycle/package.json Added build script invoking tools/build.ts.
packages/lifecycle/Makefile Deleted per-package Makefile.
packages/filter.punches/package.json Added build script invoking tools/build.ts.
packages/filter.punches/Makefile Deleted per-package Makefile.
packages/computed/package.json Added build script invoking tools/build.ts.
packages/computed/Makefile Deleted per-package Makefile.
packages/builder/package.json Added build script invoking tools/build.ts.
packages/builder/Makefile Deleted per-package Makefile.
packages/binding.template/package.json Added build script invoking tools/build.ts.
packages/binding.template/Makefile Deleted per-package Makefile.
packages/binding.if/package.json Added build script invoking tools/build.ts.
packages/binding.if/Makefile Deleted per-package Makefile.
packages/binding.foreach/package.json Added build script invoking tools/build.ts.
packages/binding.foreach/Makefile Deleted per-package Makefile.
packages/binding.core/package.json Added build script invoking tools/build.ts.
packages/binding.core/Makefile Deleted per-package Makefile.
packages/binding.component/package.json Added build script invoking tools/build.ts.
packages/binding.component/Makefile Deleted per-package Makefile.
packages/bind/package.json Added build script invoking tools/build.ts.
packages/bind/Makefile Deleted per-package Makefile.
package.json Added root Bun scripts; removed lerna dependency.
lerna.json Deleted Lerna config.
bun.lock Updated lockfile to reflect dependency removals/updates.
builds/reference/package.json Added tko config + build script for browser-only build.
builds/reference/Makefile Deleted build Makefile.
builds/knockout/package.json Added tko config + build script for browser-only build (IIFE global ko).
builds/knockout/Makefile Deleted build Makefile.
Makefile Deleted root Make orchestrator.
AGENTS.md Updated contributor commands to Bun equivalents (some Make/Lerna references remain).
.github/workflows/test-headless.yml CI now runs bun run build instead of make.
.github/workflows/saucelabs.yaml Deleted unused workflow.
.github/workflows/release.yml Release workflow updated to use bun run build/test.
.github/workflows/publish-check.yml Publish check workflow updated to use bun run build.
.github/workflows/main-build.yml CI now runs bun run build instead of make.
.github/workflows/lint-and-typecheck.yml CI now uses bun run format/lint/build instead of Make targets.
.github/workflows/electron.yaml Deleted unused workflow.
.github/workflows/deploy-docs.yml Docs workflow now builds monorepo via bun run build.

Comment on lines 55 to 67
"exports": {
".": {
"require": "./dist/index.cjs",
"import": "./dist/index.mjs"
}
},
"tko": {
"iifeGlobalName": "ko",
"buildMode": "browser-only"
},
"scripts": {
"build": "bun ../../tools/build.ts"
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tko.buildMode is set to browser-only, but tools/build.ts does not emit dist/index.cjs or dist/index.mjs in that mode. This makes the current exports map (require/import -> ./dist/index.*) point at files that won’t be produced by the build. Either generate the index artifacts even in browser-only mode, or update exports to reference the browser bundle outputs.

Copilot uses AI. Check for mistakes.
Comment on lines 46 to 55
},
"bugs": {
"url": "https://github.com/knockout/tko/issues"
},
"tko": {
"buildMode": "browser-only"
},
"scripts": {
"build": "bun ../../tools/build.ts"
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tko.buildMode is set to browser-only, but tools/build.ts does not emit dist/index.cjs/dist/index.mjs in that mode. The package exports currently reference ./dist/index.*, so consumers importing this package will fail unless those files are still produced. Consider either generating the index artifacts in browser-only mode or changing exports to reference the browser bundle outputs.

Copilot uses AI. Check for mistakes.
Comment thread AGENTS.md Outdated
- **Editor**: 2-space indentation for JS/TS, LF line endings
- See `.prettierrc` and `eslint.config.js` for full config

Run `make format-fix && make eslint-fix` before committing.
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This instruction still tells contributors to run make format-fix && make eslint-fix, but make is removed in this PR and the equivalent commands are now bun run format:fix and bun run lint:fix. Update this line to prevent broken contributor guidance.

Suggested change
Run `make format-fix && make eslint-fix` before committing.
Run `bun run format:fix && bun run lint:fix` before committing.

Copilot uses AI. Check for mistakes.
Comment thread plans/replace-make-lerna.md Outdated
Comment on lines +25 to +29
### `tools/build.ts` (~60 lines)

Shared build script that reads the local `package.json` to get name, version,
and optional TKO-specific config. Runs esbuild programmatically.

Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plan says tools/build.ts runs esbuild β€œprogrammatically”, but the implementation shells out to bunx esbuild. Please update the wording to match the actual approach (or adjust the implementation to use the JS API if that’s the intent).

Copilot uses AI. Check for mistakes.
Comment thread AGENTS.md Outdated
Comment on lines 15 to 16
```
packages/ # 26 modular @tko/* packages (all TypeScript)
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Project Structure section still references Lerna/lerna.json immediately above this code block, but Lerna is removed in this PR. Please update that description to reflect Bun workspaces and remove the stale lerna.json reference.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
AGENTS.md (2)

13-19: ⚠️ Potential issue | 🟑 Minor

Remove stale Lerna/lerna.json wording in project structure intro.

This now contradicts the migrated tooling and can misdirect contributors.

✏️ Suggested doc fix
-Lerna monorepo with npm workspaces. Current version: see `lerna.json`.
+Bun workspace monorepo. Current version: see root `package.json`.

Based on learnings: Use Bun as the package manager and script runner instead of npm install.

πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AGENTS.md` around lines 13 - 19, Update the project intro in AGENTS.md to
remove the stale "Lerna monorepo with npm workspaces" and any reference to
`lerna.json`; replace it with the current tooling note that the repo uses Bun as
the package manager and script runner (instead of npm), and clarify that
packages/ contains the 26 TypeScript `@tko/`* packages, builds/ contains the
distribution bundles, tools/ holds the shared build script, and tko.io/ is the
docs site; ensure all mentions of "Lerna" and `lerna.json` are deleted or
replaced and add a short line instructing contributors to use Bun for
install/run tasks.

67-71: ⚠️ Potential issue | 🟑 Minor

Replace leftover Make command in contributor instructions.

Line 70 still points to Make targets after moving to Bun scripts.

✏️ Suggested doc fix
-Run `make format-fix && make eslint-fix` before committing.
+Run `bun run format:fix && bun run lint:fix` before committing.

Based on learnings: Use Bun as the package manager and script runner instead of npm install.

πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AGENTS.md` around lines 67 - 71, The contributor instructions still reference
Make targets: replace the line containing "Run `make format-fix && make
eslint-fix`" with the Bun-based script invocation (e.g., "Run `bun run
format-fix && bun run eslint-fix`" or the project's exact Bun script names),
updating the docs to state Bun is the package manager/script runner; change any
phrasing that suggests make to instead reference Bun scripts and ensure the
`.prettierrc`/`eslint.config.js` note remains.
🧹 Nitpick comments (1)
tools/build.ts (1)

53-53: Metafile directory created outside dist/.

The meta/ directory is created in the package root, but this directory isn't listed in the files array of package.json files (which only include dist/). This is fine if metafiles are only needed during development/CI analysis, but consider creating dist/meta/ instead if these files should be part of the published package or are expected to be gitignored alongside dist.

♻️ Optional: Create metafiles inside dist/
-  if (!existsSync('meta')) mkdirSync('meta', { recursive: true })
+  if (!existsSync('dist/meta')) mkdirSync('dist/meta', { recursive: true })

And update the --metafile paths on lines 59 and 62:

-  --metafile=meta/browser_min_meta.json
+  --metafile=dist/meta/browser_min_meta.json
πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/build.ts` at line 53, Change the metafile directory from 'meta' to
'dist/meta' by replacing the literal 'meta' used in existsSync/mkdirSync with
'dist/meta' (so the directory is created under dist/), and update any build
invocation flags that pass --metafile (the two occurrences currently supplying
paths with 'meta') to point to the new dist/meta paths so generated metafiles
are written into dist/meta instead of the repo root.
πŸ€– Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@builds/knockout/package.json`:
- Around line 61-64: The package.json sets the tko.buildMode to "browser-only"
which only emits dist/browser.js and dist/browser.min.js but the package exports
still reference "./dist/index.cjs" and "./dist/index.mjs"; update either the
"tko.buildMode" value to "default" or change the exports object to point to the
actual browser outputs (e.g., ./dist/browser.js and ./dist/browser.min.js or a
conditional export map) so exports match the artifacts produced by the tko build
step.

In `@tools/build.ts`:
- Around line 26-36: findSources() currently calls walk('src') and readdirSync
directly which throws ENOENT when src/ is missing; update findSources to guard
the initial walk call by checking existence (e.g., use existsSync or
fs.statSync) or wrap readdirSync in a try/catch inside walk to ignore ENOENT and
continue, so packages without a src/ directory return an empty sources array
instead of crashing; reference the findSources function and its inner walk
helper and the readdirSync call when making the change.

---

Outside diff comments:
In `@AGENTS.md`:
- Around line 13-19: Update the project intro in AGENTS.md to remove the stale
"Lerna monorepo with npm workspaces" and any reference to `lerna.json`; replace
it with the current tooling note that the repo uses Bun as the package manager
and script runner (instead of npm), and clarify that packages/ contains the 26
TypeScript `@tko/`* packages, builds/ contains the distribution bundles, tools/
holds the shared build script, and tko.io/ is the docs site; ensure all mentions
of "Lerna" and `lerna.json` are deleted or replaced and add a short line
instructing contributors to use Bun for install/run tasks.
- Around line 67-71: The contributor instructions still reference Make targets:
replace the line containing "Run `make format-fix && make eslint-fix`" with the
Bun-based script invocation (e.g., "Run `bun run format-fix && bun run
eslint-fix`" or the project's exact Bun script names), updating the docs to
state Bun is the package manager/script runner; change any phrasing that
suggests make to instead reference Bun scripts and ensure the
`.prettierrc`/`eslint.config.js` note remains.

---

Nitpick comments:
In `@tools/build.ts`:
- Line 53: Change the metafile directory from 'meta' to 'dist/meta' by replacing
the literal 'meta' used in existsSync/mkdirSync with 'dist/meta' (so the
directory is created under dist/), and update any build invocation flags that
pass --metafile (the two occurrences currently supplying paths with 'meta') to
point to the new dist/meta paths so generated metafiles are written into
dist/meta instead of the repo root.
πŸͺ„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 375c8aaf-04bd-4431-bacf-db36042d228e

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between af3cc31 and d802855.

β›” Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
πŸ“’ Files selected for processing (71)
  • .github/workflows/deploy-docs.yml
  • .github/workflows/electron.yaml
  • .github/workflows/lint-and-typecheck.yml
  • .github/workflows/main-build.yml
  • .github/workflows/publish-check.yml
  • .github/workflows/release.yml
  • .github/workflows/saucelabs.yaml
  • .github/workflows/test-headless.yml
  • AGENTS.md
  • Makefile
  • builds/knockout/Makefile
  • builds/knockout/package.json
  • builds/reference/Makefile
  • builds/reference/package.json
  • lerna.json
  • package.json
  • packages/bind/Makefile
  • packages/bind/package.json
  • packages/binding.component/Makefile
  • packages/binding.component/package.json
  • packages/binding.core/Makefile
  • packages/binding.core/package.json
  • packages/binding.foreach/Makefile
  • packages/binding.foreach/package.json
  • packages/binding.if/Makefile
  • packages/binding.if/package.json
  • packages/binding.template/Makefile
  • packages/binding.template/package.json
  • packages/builder/Makefile
  • packages/builder/package.json
  • packages/computed/Makefile
  • packages/computed/package.json
  • packages/filter.punches/Makefile
  • packages/filter.punches/package.json
  • packages/lifecycle/Makefile
  • packages/lifecycle/package.json
  • packages/observable/Makefile
  • packages/observable/package.json
  • packages/provider.attr/Makefile
  • packages/provider.attr/package.json
  • packages/provider.bindingstring/Makefile
  • packages/provider.bindingstring/package.json
  • packages/provider.component/Makefile
  • packages/provider.component/package.json
  • packages/provider.databind/Makefile
  • packages/provider.databind/package.json
  • packages/provider.multi/Makefile
  • packages/provider.multi/package.json
  • packages/provider.mustache/Makefile
  • packages/provider.mustache/package.json
  • packages/provider.native/Makefile
  • packages/provider.native/package.json
  • packages/provider.virtual/Makefile
  • packages/provider.virtual/package.json
  • packages/provider/Makefile
  • packages/provider/package.json
  • packages/utils.component/Makefile
  • packages/utils.component/package.json
  • packages/utils.functionrewrite/Makefile
  • packages/utils.functionrewrite/package.json
  • packages/utils.jsx/Makefile
  • packages/utils.jsx/package.json
  • packages/utils.parser/Makefile
  • packages/utils.parser/package.json
  • packages/utils/Makefile
  • packages/utils/package.json
  • plans/modern-tooling.md
  • plans/replace-make-lerna.md
  • tools/build.mk
  • tools/build.ts
  • tools/template/Makefile
πŸ’€ Files with no reviewable changes (33)
  • packages/binding.core/Makefile
  • packages/computed/Makefile
  • packages/binding.component/Makefile
  • packages/binding.if/Makefile
  • packages/provider.bindingstring/Makefile
  • packages/provider/Makefile
  • .github/workflows/electron.yaml
  • packages/binding.template/Makefile
  • packages/observable/Makefile
  • packages/filter.punches/Makefile
  • packages/provider.multi/Makefile
  • packages/provider.native/Makefile
  • packages/bind/Makefile
  • packages/provider.component/Makefile
  • packages/provider.databind/Makefile
  • packages/provider.virtual/Makefile
  • packages/utils.component/Makefile
  • lerna.json
  • packages/utils.jsx/Makefile
  • packages/provider.mustache/Makefile
  • packages/utils.functionrewrite/Makefile
  • .github/workflows/saucelabs.yaml
  • builds/knockout/Makefile
  • packages/provider.attr/Makefile
  • packages/lifecycle/Makefile
  • packages/utils/Makefile
  • packages/binding.foreach/Makefile
  • packages/builder/Makefile
  • packages/utils.parser/Makefile
  • Makefile
  • tools/build.mk
  • tools/template/Makefile
  • builds/reference/Makefile

Comment thread builds/knockout/package.json
Comment thread tools/build.ts Outdated
Brian M Hunt and others added 5 commits April 15, 2026 09:50
- Two-phase build: packages first, then builds (bun --filter doesn't toposort)
- Change builds from browser-only to browser mode (ESM+CJS+MJS+IIFE)
  β€” builds/reference specs import from dist/index.mjs
- Add globalThis to IIFE footer
- Fix stale make reference in AGENTS.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Release workflow runs on bare ubuntu-latest (needs Node for npm
trusted publishing), not the Playwright container. Instead of
installing browsers (5+ min), just typecheck β€” full browser tests
already passed in PR CI and main-build.

Also remove stale make comments from codeql-analysis.yml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Restore apt-get install unzip in Playwright container workflows
- Replace make browser with bun run build in tko.io prebuild script
- Update AGENTS.md: Lerna→Bun workspaces

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use bun-version-file: .tool-versions in all setup-bun steps so
CI uses the same Bun version as local development via mise/asdf.
Prevents version drift between local and CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Code already passed tsc in PR CI and main-build before tagging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread tools/build.ts
@@ -0,0 +1,70 @@
/**
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lerna light in 70 lines πŸ‘

Brian M Hunt and others added 3 commits April 15, 2026 10:19
- Use Bun.file, Bun.Glob, Bun.spawn instead of Node fs/child_process
- Add shebang #!/usr/bin/env bun
- Reduce llms.txt from 108 lines to 40 (concise like bun.sh/llms.txt)
- Update plan to reflect Bun API usage

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use Bun.spawn for esbuild invocation (Bun.$ raw doesn't work)
- Parallelize ESM/MJS/CJS builds with Promise.all
- Parallelize IIFE minified/unminified builds
- Restore gotchas and esbuild-wasm snippet to llms.txt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 5 builds (ESM, MJS, CJS + IIFE min/unmin) now run concurrently
via a single Promise.all instead of two sequential groups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@brianmhunt
Copy link
Copy Markdown
Member Author

brianmhunt commented Apr 15, 2026

Build performance

Clean build of all 27 packages now completes in 0.3 seconds (wall clock) - down from 10-15s:

bun run clean && time bun run build
...
bun run build  0.92s user 1.12s system 651% cpu 0.313 total

All 5 esbuild invocations per package (ESM, MJS, CJS + IIFE min/unmin for browser builds) run fully parallel via Promise.all. The two-phase ordering (packages β†’ builds) ensures dependency order is respected.

All 2679 tests pass, 42 skipped.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
package.json (1)

19-19: Include browser build metadata in root clean target.

Line 19 cleans dist and coverage, but tools/build.ts also emits meta/ for browser builds. Consider cleaning that output too to avoid stale artifacts.

Suggested diff
-    "clean": "rm -rf packages/*/dist builds/*/dist coverage"
+    "clean": "rm -rf packages/*/dist builds/*/dist builds/*/meta coverage"
πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` at line 19, The root "clean" npm script currently removes
packages/*/dist, builds/*/dist and coverage but omits browser build metadata
emitted by tools/build.ts into meta/; update the "clean" script (the "clean"
entry in package.json) to also remove the meta/ directories (e.g., add
packages/*/meta and builds/*/meta or a top-level meta pattern) so browser build
metadata is purged alongside dist and coverage to prevent stale artifacts.
πŸ€– Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@AGENTS.md`:
- Around line 15-20: The fenced code block starting with ``` in AGENTS.md is
missing a language identifier (causing markdownlint MD040); update that opening
fence to include a neutral identifier such as "text" (e.g., change ``` to
```text) so the block is explicitly marked and the linter passes, keeping the
block contents unchanged.

---

Nitpick comments:
In `@package.json`:
- Line 19: The root "clean" npm script currently removes packages/*/dist,
builds/*/dist and coverage but omits browser build metadata emitted by
tools/build.ts into meta/; update the "clean" script (the "clean" entry in
package.json) to also remove the meta/ directories (e.g., add packages/*/meta
and builds/*/meta or a top-level meta pattern) so browser build metadata is
purged alongside dist and coverage to prevent stale artifacts.
πŸͺ„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: afe413fa-3d4a-489a-9aab-f5e94974dcbb

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between d802855 and 4b46b4e.

πŸ“’ Files selected for processing (15)
  • .github/workflows/codeql-analysis.yml
  • .github/workflows/deploy-docs.yml
  • .github/workflows/lint-and-typecheck.yml
  • .github/workflows/main-build.yml
  • .github/workflows/publish-check.yml
  • .github/workflows/release.yml
  • .github/workflows/test-headless.yml
  • AGENTS.md
  • builds/knockout/package.json
  • builds/reference/package.json
  • package.json
  • plans/replace-make-lerna.md
  • tko.io/package.json
  • tko.io/public/llms.txt
  • tools/build.ts
πŸ’€ Files with no reviewable changes (1)
  • .github/workflows/codeql-analysis.yml
βœ… Files skipped from review due to trivial changes (3)
  • tko.io/public/llms.txt
  • builds/knockout/package.json
  • plans/replace-make-lerna.md
🚧 Files skipped from review as they are similar to previous changes (8)
  • .github/workflows/main-build.yml
  • .github/workflows/deploy-docs.yml
  • .github/workflows/test-headless.yml
  • .github/workflows/lint-and-typecheck.yml
  • .github/workflows/release.yml
  • builds/reference/package.json
  • .github/workflows/publish-check.yml
  • tools/build.ts

Comment thread AGENTS.md Outdated
@brianmhunt
Copy link
Copy Markdown
Member Author

Build output comparison: branch vs main

Methodology

  1. Built all 27 packages on main using the old Make + lerna system (make all)
  2. Built all 27 packages on this branch using bun run build
  3. For each of the 192 output files (.js, .mjs, .cjs), stripped the version banner line and sourceMappingURL comment, then computed a SHA-256 hash
  4. Compared manifests line-by-line

Results

163 of 192 files are byte-for-byte identical (all ESM dist/*.js and MJS dist/index.mjs files).

29 files differ, all intentionally:

Category Files Cause
CJS (index.cjs) 25 packages Branch uses --external:@tko/* β€” deps resolved via node_modules instead of inlined
IIFE (browser.js, browser.min.js) 4 files (2 builds) Footer adds globalThis to environment detection chain

CJS size reduction

The old Make build bundled all @tko/* dependencies into each CJS file. The new build externalizes them (--external:@tko/*), which is correct for Node/CJS consumers who resolve deps through node_modules. Example: @tko/bind CJS went from 111KB β†’ 37KB.

IIFE builds

The IIFE browser bundles remain fully self-contained (bundled). The only difference is ~49 bytes from adding typeof globalThis !== 'undefined' ? globalThis : to the footer's environment detection, which is a minor improvement for modern runtimes.

@brianmhunt
Copy link
Copy Markdown
Member Author

CJS transitive dependency verification

Methodology

With --external:@tko/* on CJS builds, dependencies are resolved at runtime via node_modules instead of being inlined. To verify this works correctly, ran node -e "require(...)" tests that exercise actual functionality across transitive dependency chains β€” not just module loading, but reactive state propagation.

Tests

# Test Dependency chain
1 observable: create, read, write @tko/observable
2 computed: depends on observable, re-evaluates on change @tko/computed β†’ @tko/observable
3 observableArray: create, push, read @tko/observable
4 computed over observableArray: reactive sum @tko/computed β†’ @tko/observable
5 pureComputed: lazy evaluation + dependency tracking @tko/computed β†’ @tko/observable
6 Subscribe chain: observable β†’ computed β†’ subscriber @tko/computed β†’ @tko/observable (full reactive graph)
7 utils: arrayFilter (transitive dep used by observable+computed) @tko/utils
8 Parser constructor loads with utils dependency @tko/utils.parser β†’ @tko/utils
9 Provider chain @tko/provider.multi β†’ @tko/provider β†’ @tko/utils
10 Builder loads full dependency tree @tko/builder β†’ nearly all packages

Results

All 25 individual packages load via require() with correct exports. All 10 functional tests pass β€” reactive state propagation, subscription notifications, and deep transitive chains all work correctly through externalized CJS imports resolved via Bun workspace node_modules symlinks.

The 2 builds packages (@tko/build.knockout, @tko/build.reference) parse as valid CJS but fail at runtime with Node is not defined β€” expected, as these are browser-only bundles referencing DOM APIs.

Fixes markdownlint MD040 warning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@brianmhunt brianmhunt merged commit c4760bf into main Apr 15, 2026
5 checks passed
@brianmhunt brianmhunt deleted the modern-tooling/phase-3-replace-make-lerna branch April 15, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants