Skip to content

feat!: upgrade node to 24 and regain deployability#185

Merged
karldreher merged 8 commits intomasterfrom
20260410-120221
Apr 10, 2026
Merged

feat!: upgrade node to 24 and regain deployability#185
karldreher merged 8 commits intomasterfrom
20260410-120221

Conversation

@karldreher
Copy link
Copy Markdown
Contributor

@karldreher karldreher commented Apr 10, 2026

We presently lack the ability to make change to the repo, because we are on Node 18 (actually we probably "got upgraded" over time, earlier art in the repo shows that we intend Node 14)

image

It is not possible to roll back to a version not on this list. As a part of this change, a one-way change from 18 to 24 was made. We can roll back down to 20, but cannot get back to version 18 or below.

The rest of this change supports deployability of the project, in a reasonably minimal way, however should take care to keep other dependencies up-to-date. (Next.js, react-dom, vercel, etc). Those are deferred and out of scope in favor of getting to a deployable state. This is supportive of the effort in #184 .

Summary

  • Upgrade Node from v14 to 24 (.nvmrc updated)
  • Remove apparently disused Github Pages deployment
  • Update TypeScript target to ES2022 for Node 24 support
  • Update Jest from v27 to v29 with ts-jest v29
  • Switch Jest test environment from jsdom to node (no DOM needed)
  • Add ESM package transform ignore patterns for chroma-js, javascript-time-ago, mathjs, nanoid
  • Fix encode.ts to use globalThis instead of window (works in all environments)
  • Add dedicated test job in CI workflow, separate from build
  • Update GitHub Actions to use actions/setup-node with .nvmrc pin

Test plan

  • npm test passes with all 254 tests
  • Node 24.14.1 installed via nvm
  • npm install completes without errors
  • Tests run in node environment without DOM errors

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

This comment was marked as outdated.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
glide-code-columns Ready Ready Preview, Comment Apr 10, 2026 8:54pm

Request Review

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@karldreher karldreher changed the title chore: upgrade node to 24 feat!: upgrade node to 24 and regain deployability Apr 10, 2026
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@marcel-at-glide marcel-at-glide left a comment

Choose a reason for hiding this comment

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

approved

@karldreher
Copy link
Copy Markdown
Contributor Author

Noted observed bug from @marcel-at-glide 's observation:

https://www.loom.com/share/8e1405c6b8764e689d299acd4c39d8d6

Claudio analysis:

This is a pre-existing bug, not a regression we introduced. Nothing we touched affects this component.

The issue is on line 35:

}, [values.join("")]);

useEffect runs when values.join("") changes. On initial load, the values are e.g. [-10, -5, 5] → join = "-10-55". The
effect fires, run() executes, and setResult(-5) is called. That should work.

The actual bug is on line 65:

setValues([...values.slice(0, i), value, ...values.slice(i + 1, values.length - i)]);

values.length - i is wrong — it should be values.length. This means clicking into an input and typing re-slices the
array incorrectly, which changes values.join(""), which re-triggers the effect. The click isn't what's computing the
result — a subtle state mutation from using defaultValue (uncontrolled input) vs the actual values state is causing
it.

More specifically: the inputs use defaultValue (uncontrolled), not value (controlled). React renders the initial value
but doesn't keep the DOM in sync with state. So the displayed inputs and the values array can drift, but useEffect
still fires on initial mount and should produce the correct result.

Most likely cause of the blank result on first load: the useEffect fires before the column's run function finishes
loading (it's loaded from a <script> tag asynchronously in the iframe). The result resolves to undefined and the field
stays blank until something triggers a re-run.

This is pre-existing — none of our changes (Node upgrade, Jest config, tsconfig, encode.ts) touched this component or
the iframe loading mechanism.

Karl analysis

I believe reasonably that this reflects an aging codebase, we should pursue next.js update but outside of this scope. Unless we have clear monitoring / user feedback that tells us that this is slow, this might be recency bias. I trust Claude's judgement and recommend we move forward.

@marcel-at-glide
Copy link
Copy Markdown
Collaborator

I vote to move forward

@karldreher
Copy link
Copy Markdown
Contributor Author

The motion passes!

@karldreher karldreher merged commit d3d0e47 into master Apr 10, 2026
4 checks passed
@karldreher karldreher deleted the 20260410-120221 branch April 10, 2026 21:42
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