Skip to content

feat: support React 19 - #45

Merged
raphi merged 3 commits into
mainfrom
chore/react-19-peer
Oct 24, 2026
Merged

raphi merged 3 commits into
mainfrom
chore/react-19-peer

Conversation

@raphi

@raphi raphi commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds React 19 support. Drop-in upgrade for React 16, 17 and 18.

Problem

React 19 no longer applies defaultProps to function components (including forwardRef) created through the JSX runtime. With 2.2.2 on React 19:

  • the geolocation button is not rendered (geolocation is undefined)
  • the input has no placeholder
  • npm install fails with ERESOLVE (peer range stops at ^18)

Changes

  • PlaceKit: defaults are now also declared as parameter defaults (geolocation = true, options = DEFAULT_OPTIONS, placeholder = DEFAULT_PLACEHOLDER). placeholder is passed explicitly to <input> since it is no longer part of the rest spread. DEFAULT_OPTIONS is a module-level constant to keep a stable reference.
  • PlaceKit.defaultProps is kept with the same values, so code that reads or mutates it keeps working on React 16 to 18. React 19 ignores it and logs no warning for it.
  • peerDependencies: react and react-dom widened to ^16 || ^17 || ^18 || ^19.
  • index.d.ts: return type JSX.Element -> React.ReactElement. @types/react 19 removed the global JSX namespace; React.ReactElement is available in all @types/react versions.
  • rollup.config.js: JSON import uses with instead of assert (assert is rejected by Node 22).
  • Version 2.3.0.

@types/react stays at ^18.2.58 on purpose: widening it to ^19 makes fresh installs of React 18 TypeScript apps resolve @types/react 19.

Compatibility testing

Published 2.2.2 vs this branch, installed in otherwise identical consumer apps (React StrictMode, API mocked). Each scenario runs the same flow (type, keyboard navigation, pick, clear, Escape, geolocation toggle) and compares DOM, screenshots (pixel diff), handler calls, outgoing requests and console output.

Consumer Result
Vite + React 16.14, 17.0.2, 18.3.1 (dev and prod) identical
Next.js 14 pages router (dev, prod, SSR HTML) identical, no hydration warnings
Vite + React 19.0, Next.js 15 app router + React 19.2 placeholder and geolocation button render again; installs without --legacy-peer-deps
TypeScript, React 17/18 (fresh install and existing lockfile) same @types/react resolution, same tsc output
TypeScript, React 19 + @types/react 19 Cannot find namespace 'JSX' error fixed

Scenarios covered: default props, custom/empty/null/undefined placeholder, geolocation={false}, disabled, HTML attributes, defaultValue, full options with custom format, inline options re-created on each render, all event handlers, object and callback refs, usePlaceKit, reading/mutating/reassigning PlaceKit.defaultProps.

Only difference on React 16 to 18: when placeholder is passed before other props, it is emitted later in the <input> attribute list. No visual or behavioral change. Bundle size: +0.08 kB gzipped.

Known issues (unchanged by this PR)

  • @placekit/client-js type declarations fail with skipLibCheck: false (TS1016).
  • require('@placekit/autocomplete-react') from plain Node fails ("type": "module" with a .cjs.js entry). Bundlers are not affected.
  • No 'use client' directive: Next.js app router users need a client wrapper.

🤖 Generated with Claude Code

raphi and others added 3 commits October 23, 2026 20:46
React 19 ignores `defaultProps` on function components, so on React 19
the geolocation button disappeared and the input lost its default
placeholder. Defaults are now parameter defaults in the render function
(`geolocation = true`, `options` as a module-level constant,
`placeholder = 'Search places...'` passed explicitly to the input).

- peerDependencies: react and react-dom widened to ^16 || ^17 || ^18 || ^19
- types: use `React.JSX.Element` (global `JSX` namespace is gone in
  @types/react 19) and widen @types/react to ^18.2.58 || ^19 so npm
  dedupes it with the app's version
- build: rollup config uses `with { type: 'json' }` (Node 22 dropped
  import assertions, `assert` failed the build)
- version 2.3.0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o 19

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Apps on React 16 to 18 that read or mutate PlaceKit.defaultProps keep
working, and the @types/react range no longer pulls React 19 types into
React 18 projects on fresh installs. Parameter defaults still cover React 19.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@raphi
raphi merged commit af9895e into main Oct 24, 2026
1 check passed
@raphi
raphi deleted the chore/react-19-peer branch October 24, 2026 11:14
@raphi

raphi commented Oct 24, 2026

Copy link
Copy Markdown
Member Author

Closes #44

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.

1 participant