fix(tui): register the spinner element by value so the bundler keeps it - #225
Merged
Conversation
`import "opentui-spinner/solid"` was there only for its side effect, the
`extend({ spinner })` call that puts `spinner` in the component catalogue.
Bun's bundler drops that import, so compiled binaries reach
`createElement("spinner")` with an empty catalogue entry and throw
`[Reconciler] Unknown component type: spinner` as soon as the prompt renders.
Import `registerSpinner` and call it instead: a called binding cannot be
tree-shaken. `extend` is `Object.assign` on a module-level object, so calling
it from both files that render `<spinner>` is idempotent.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
| import "opentui-spinner/solid" | ||
| import { registerSpinner } from "opentui-spinner/solid" | ||
|
|
||
| registerSpinner() |
nikomatt69
approved these changes
Aug 18, 2026
nikomatt69
left a comment
Owner
There was a problem hiding this comment.
Review (local verification, 2026-08-18)
This is the right fix for #224. opentui-spinner/solid already calls extend({ spinner }) on import and exports registerSpinner as that same function. A binding that is called cannot be tree-shaken, and a second extend is Object.assign so calling it from both spinner.tsx and prompt/index.tsx is idempotent.
Verified
- CI
typecheckpassed registerSpinneris exported fromopentui-spinner@0.0.7(dist/solid.d.mts/dist/solid.mjs) and is the sameextend({ spinner })the side-effect import used to rely on- No overlap with #227 / #233
- Merges clean onto current
live-main(fdf92f6bf6, no conflicts)
CI that is red is not this PR
test (windows): Bun remap crash (could not create process/ exit 255) while runningbun test:e2e:local— infrastructure, same class of failure on the other PRscheck-duplicates:Executable not found in $PATH: "nikcli"inscript/duplicate-pr.ts— pre-existingtest (linux)has been queued for hours, not a test failure
Merge: yes. This is the compiled-TUI crash. Merge first of the three.
This was referenced Aug 18, 2026
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue for this PR
Closes #224
Type of change
What does this PR do?
spinneris not a built-in opentui element — it comes fromopentui-spinner, which registers it by callingextend({ spinner })whenopentui-spinner/solidis evaluated. Both files that render<spinner>pulled it in with a bareimport "opentui-spinner/solid", i.e. an import with no bindings, kept only for that side effect.Bun's bundler drops that import. In a compiled binary the registration never runs, the component catalogue has no
spinner, and the firstcreateElement("spinner")throws[Reconciler] Unknown component type: spinner— which is the prompt's thinking indicator, so the TUI dies right after start.bun devnever showed it because nothing bundles there.The fix imports the
registerSpinnerbinding the package already exports and calls it. A binding that is called cannot be tree-shaken, so the registration survives the bundle.extendisObject.assignonto a module-level object, so calling it from both files is idempotent.How did you verify your code works?
Built
live-main(12c9fac, v1.292.0) twice on Windows and grepped the executable for a string that only exists insideopentui-spinner:The patched binary starts into the TUI and the spinner animates; the unpatched one hits the fatal-error screen.
bun run --cwd packages/tui typecheckis clean.A reviewer can reproduce with the same two builds and that grep, no Windows needed — the import is dropped on every platform.
Screenshots / recordings
Not a UI change beyond the spinner rendering again; the crash screen is quoted in #224.
Checklist