docs(adr): propose Bun runtime and native tooling

Record the proposed decision to run project-owned JavaScript under Bun
with its native test runner, linter, formatter, type checker and HTTP
server, keeping Angular's standard build pipeline, plus the development
spec for the migration tickets.

Refs #289

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nessarandClaude Opus 5.5 committed 2026-10-17 12:01:42 +02:00
1 parent 752c8b7a99
commit c949480e49
2 files changed
+217

No files matched your search

@@ -0,0 +1,18 @@
---
status: proposed
---
# Bun Runtime and Native Tooling
VacOptimizer will use Bun as the runtime for project-owned JavaScript in
development, CI, and production, adopting its native test runner, linter,
formatter, type checker, and HTTP server even without measured performance gains.
This deliberately accepts Bun-specific tooling and migration work while retaining
Angular's standard compiler and build pipeline, including TypeScript 6 for
Angular compilation alongside `bun check` for standalone TypeScript checking.
Existing behavior, tests, lint rules, coverage reporting, and benchmark budgets
must be preserved; incompatibilities must be fixed or reported as blockers before
declaring completion, and a Node.js fallback does not meet the runtime requirement.
The [development spec](../bun-adoption.md) records the agreed boundaries,
acceptance criteria, and remaining verification.
+199
View File
@@ -0,0 +1,199 @@
# Bun Runtime and Native Tooling — Development Spec
Status: local draft synthesized from the agreed individual decisions. Integration
feasibility remains unverified; ADR 0009 remains proposed.
## Problem Statement
The maintainer wants VacOptimizer to use Bun as its actual JavaScript runtime and
adopt its native tooling wherever agreed, even without measurable performance
gains. Today Bun installs dependencies, generates the language registry, and runs
the deployed server, but development commands can launch Node-based CLIs, CI uses
Node containers, and the Docker build explicitly installs Node.
The toolchain is also inconsistent: the local Bun installation is 1.3.14, CI pins
1.4.2, and Docker uses a floating Bun image. Merely prefixing commands with Bun
does not establish which runtime executes their JavaScript.
## Solution
Use Bun for project-owned JavaScript in development, CI, and production. Adopt
Bun's native test runner, linter, formatter, standalone type checker, and HTTP
server. Retain Angular and its standard compiler and build pipeline, running the
JavaScript tooling under Bun.
Preserve the application's existing behavior and verification standards. The
planner remains client-side: planning horizons, planning rules, leave placements,
planning outcomes, plan statistics, and plan explanations retain their current
meaning. Browser code and Web Workers continue to run in the user's browser.
## User Stories
The following acceptance criteria define completion:
1. **Actual Bun execution.** Development serving and watch mode, production
builds, language generation, repository CI scripts, tests, and the production
server execute their project-owned JavaScript under Bun, including spawned
tools and test fixtures. A Node.js fallback does not satisfy this criterion.
2. **Reproducible setup.** Development instructions, CI, and both Docker stages
specify the same exact, verified Bun version. Frozen dependency installation
succeeds from a clean checkout without changing the lockfile, and the
production image installs only production dependencies.
3. **Native tests with preserved behavior.** All existing functional and Angular
component tests execute under `bun test`, preserving assertions, parameterized
cases, clock control, global mocks, cleanup, isolation, and real worker
integration. Tests cannot be dropped or weakened to make the migration pass.
4. **Preserved coverage.** Functional tests retain coverage reporting and CI
artifacts, including useful output when tests fail. Preserve the current
production-code coverage scope and exclusion of the frozen engine baseline;
report unsupported coverage capabilities or report formats as compatibility
gaps rather than silently removing them.
5. **Native linting and formatting.** Bun's native linter and formatter replace
ESLint and Prettier, preserving the current rule severities, type-aware checks,
unused-name exceptions, formatting options, and Angular-template formatting.
CI continues to reject violations. Checks cover the same application,
repository-script, and workflow content as before.
6. **Type checking alongside Angular.** `bun check` checks application and test
TypeScript. Angular's compiler retains its supported TypeScript 6 dependency
and continues to check templates during builds. Type errors still fail the
appropriate checks; successful standalone checking does not replace a
successful Angular build.
7. **Native HTTP serving.** `Bun.serve` replaces Express, preserving Angular's
request-handler integration, configured rendering modes, static assets and
cache behavior, configurable port, error handling, and container health check.
Development and production routes continue to work, including direct visits
to the benchmark page. The current catch-all route uses client rendering;
this migration does not enable server rendering for that route.
8. **Existing CI guarantees.** Policy and image-publication regression checks,
security scans, production builds, artifact retention, and required checks
continue to work. The separate required seven-scenario benchmark preserves
its calibration protocol, warm-up, measured repetitions, determinism checks,
timeouts, and performance budgets. A runtime change cannot justify weakening
these gates.
9. **Honest completion.** Fix incompatible required tooling before declaring the
migration complete. If a fix proves infeasible, report the failing behavior,
evidence, and remaining blocker. Local success must be distinguished from
successful live Gitea checks.
## Implementation Decisions
- **Agreed: runtime and native tools.** Bun adoption is a requirement independent
of speed gains. Use its native test runner, linter, formatter, standalone type
checker, and HTTP server. Compatible Node API imports may remain when executed
by Bun; rewriting every import is not required to satisfy the runtime goal.
- **Agreed: Angular boundary.** Keep Angular's standard compiler, bundler,
development server, and framework build support. Preserve the existing
rendering configuration and browser-based planner, consistent with ADR 0002.
- **Agreed: TypeScript coexistence.** Keep TypeScript 6 for Angular compilation
and use Bun's TypeScript 7-based checker for standalone checking. An Angular
upgrade is not required for this arrangement.
- **Agreed: tests and server integration.** Adapt the Angular test compilation
and setup, mocks, DOM environment, worker harnesses, and subprocess fixtures to
the chosen runtime and runner. Use Angular's web request API with Bun's HTTP
server, preserving its development/build handler contract and static-file
protections.
- **Migration reach.** Update package commands, test configuration and typings,
generated executable fixtures, server entry and exports, container build and
runtime stages, project-owned CI invocations, and development documentation.
Remove superseded dependencies and configuration after checking their callers.
- **Proposed implementation order.** Verify the Bun release, an Angular
production build, representative Angular component tests, and native
lint/format/type checks first. Extend that verified setup to the full suite,
server, containers, and CI before removing the replaced tools.
- **Proposed version.** Bun 1.4.3 is the initial candidate based on the researched
native-tool documentation. Select the exact version only after verifying the
required capabilities together.
## Testing Decisions
- Test observable behavior and failure outcomes, rather than configuration text
or internal adapter shapes. Reuse the existing behavior-level tests and change
harnesses only where the runtime or runner requires it.
- **Runtime and installation:** exercise clean frozen installs, development and
production commands, and project-owned subprocesses with Node unavailable to
those commands. Verify actual execution by Bun, rather than relying on a
command's name. Keep any CI-platform Node requirement separate from this check.
- **Angular and planning:** use the existing TestBed-based component and service
suites as prior art for compilation and DOM behavior. Retain the planning
integration, property-based, migration, date-sensitive, and cancellation tests
to check planning outcomes, saved inputs, and plan explanations.
- **Workers and subprocesses:** preserve the existing real-worker tests for
submitted-configuration isolation, outcome and explanation delivery, and worker
cleanup. Run policy and publisher regression scripts with Bun, keeping their
temporary Git repositories and fake Docker executable so verification remains
independent of real registry writes.
- **Lint, format, and types:** compare the current checks with the native tools.
Use small representative invalid inputs to establish that unused variables,
deprecated APIs, formatting violations, application/test type errors, and
Angular template errors still fail the intended command. Verify formatting
options and representative Angular templates without an unrelated reformat.
- **HTTP and containers:** add focused HTTP behavior checks around the native
server, since the explored test suite provides no equivalent server coverage.
Exercise configured routes, direct navigation, static JavaScript/CSS assets,
cache and content-type headers, missing assets, error responses, and traversal
protection. Smoke-test the production container and its health check.
- **Coverage and benchmark:** verify functional coverage artifacts, including
failure-path uploads, and run the existing benchmark outside coverage. Keep the
frozen-engine calibration and current budget assertions. Record Bun results as
new measurements rather than claiming browser or phone speedups from them.
- **CI:** use the existing policy/publisher regression scenarios as prior art for
push, pull-request, fork, manual, and release-event behavior. Obtain successful
required checks on the final PR revision; live publication and activation
validation remain subject to the repository's existing Gitea process.
## Out of Scope
- Replacing Angular's build pipeline with Bun's bundler, rewriting the framework,
or bypassing Angular's TypeScript support checks.
- Moving leave planning to the server, changing planning rules or objectives,
altering saved data, or adding accounts, synchronization, or backend services.
- Changing configured rendering modes or treating Bun as the browser runtime.
- Dropping tests, weakening lint rules or benchmark budgets, or silently using
Node to complete otherwise incompatible project commands.
- Replacing security scanners, changing registry publication policy, provisioning
CI credentials, modifying branch protections or activation settings, creating
releases, publishing this spec, or deploying the application.
- Rewriting compatible Node API imports solely because their names mention Node.
## Further Notes
This spec records the decisions made in the interview. The architecture record
remains proposed, and no migration implementation or compatibility proof exists.
The glossary receives no new terms because the choices concern general tooling,
rather than new leave-planning concepts.
Remaining verification and unresolved requirements:
- Angular compilation, test-resource loading, serializers, mocking, isolation,
and the existing worker harnesses must work under the native Bun runner.
- Standalone TypeScript 7 diagnostics must be checked alongside Angular's
TypeScript 6 diagnostics; their coexistence is agreed, but project-specific
differences have not been measured.
- Current Istanbul reports include text, HTML, and Cobertura. Native coverage
equivalence and report-format support have not been established; accepting a
reduced capability or different downstream format has not been agreed.
- Third-party Gitea checkout and artifact actions may impose their own Node
requirement. Identify the actual platform constraint; no exception allowing
project commands to fall back to Node has been agreed, and CI infrastructure
changes beyond the migration require a separate decision.
- The exact Bun release and container compatibility remain to be verified.
The local installation currently lacks the documented native lint, format,
and standalone type-check commands.
Research checked on 2026-10-17:
- [Bun runtime selection](https://bun.sh/docs/runtime#--bun) explains why a Bun
command can still launch a Node executable.
- [Bun 1.4.3](https://bun.sh/blog/bun-v1.4.3),
[native linting](https://bun.sh/docs/lint),
[formatting](https://bun.sh/docs/format), and
[type checking](https://bun.sh/docs/runtime/check) describe the candidate tools.
- [Angular build guidance](https://angular.dev/ecosystem/custom-build-pipeline)
recommends retaining its standard CLI pipeline.
- [Angular's web request engine](https://angular.dev/api/ssr/AngularAppEngine) and
[Bun's HTTP server](https://bun.sh/docs/runtime/http/server) provide the intended
server integration contracts; their compatibility here remains untested.
- [Angular version compatibility](https://angular.dev/reference/versions) and
[compiler roadmap](https://angular.dev/roadmap) establish the current Angular
compiler boundary. [Microsoft's coexistence guidance](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/#typescript-and-embedded-languages)
describes standalone TypeScript 7 checks alongside Angular-specific tooling.