Skip to content

Conversation

@tewson
Copy link
Member

@tewson tewson commented Feb 6, 2026

WHY are these changes introduced?

Ink v6 was released with React 19 as a peer dependency. Upgrading keeps the CLI on the latest supported versions of both libraries, benefiting from React 19 performance improvements and Ink 6 fixes.

WHAT is this pull request doing?

Dependency bumps:

  • ink: 5.2.1 → 6.2.0 (cli-kit)
  • react: ^18.2.0 → ^19.0.0 (cli-kit, app)
  • @types/react: ^18.2.0 → ^19.0.0 (cli-kit, app)
  • react-dom: 18.3.1 → ^19.0.0 (app)
  • @types/react-dom: ^18.2.0 → ^19.0.0 (app)

Code changes (all in SelectInput.tsx):

  • Removed forwardRef wrapper and custom module augmentation — ref is now a regular prop in React 19
  • Updated inputFixedAreaRef type from React.RefObject<DOMElement> to React.Ref<DOMElement> for React 19 compatibility

No other code changes were required. The codebase was already clean of deprecated React 18 patterns (no defaultProps, propTypes, string refs, legacy context, or implicit children on FunctionComponent).

How to test your changes?

  1. pnpm install
  2. pnpm --filter @shopify/cli-kit type-check — passes
  3. pnpm --filter @shopify/app type-check — passes
  4. Run the CLI and verify interactive prompts (select, autocomplete, text input) work correctly

Measuring impact

  • n/a - this doesn't need measurement, e.g. a linting rule or a bug-fix

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes

🤖 Generated with Claude Code

@tewson tewson requested a review from a team as a code owner February 6, 2026 18:42
@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

We detected some changes at packages/*/src and there are no updates in the .changeset.
If the changes are user-facing, run pnpm changeset add to track your changes and include them in the next release CHANGELOG.

Caution

DO NOT create changesets for features which you do not wish to be included in the public changelog of the next CLI release.

@tewson tewson force-pushed the feature/react-19-ink-6 branch 2 times, most recently from 28e81f7 to a3819fe Compare February 9, 2026 14:44
@tewson tewson force-pushed the feature/react-19-ink-6 branch 4 times, most recently from 03b74ca to 322430f Compare February 9, 2026 16:31
Ink 6 requires React 19 as a peer dependency. This upgrades both
libraries and fixes the breaking changes:

- Remove forwardRef pattern in SelectInput (ref is now a regular prop)
- Update RefObject type for React 19 compatibility
- Remove custom forwardRef module augmentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tewson tewson force-pushed the feature/react-19-ink-6 branch from 322430f to aedbd23 Compare February 9, 2026 17:03
@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements 79.61% 14471/18178
🟡 Branches 73.92% 7176/9708
🟡 Functions 79.79% 3692/4627
🟡 Lines 79.96% 13675/17103

Test suite run success

3718 tests passing in 1438 suites.

Report generated by 🧪jest coverage report action from aedbd23

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/private/node/testing/ui.d.ts
@@ -73,7 +73,8 @@ export declare function sendInputAndWait(renderInstance: ReturnType<typeof rende
 export declare function sendInputAndWaitForContent(renderInstance: ReturnType<typeof render>, content: string, ...inputs: string[]): Promise<void>;
 /** Function that is useful when you want to check the last frame of a component that unmounted.
  *
- * The reason this function exists is that in CI Ink will clear the last frame on unmount.
+ * With Ink 6 / React 19, the output is no longer cleared on unmount,
+ * so lastFrame() consistently returns the last rendered content.
  */
 export declare function getLastFrameAfterUnmount(renderInstance: ReturnType<typeof render>): string | undefined;
 type TrackedPromise<T> = Promise<T> & {
packages/cli-kit/dist/private/node/ui/components/SelectInput.d.ts
@@ -1,8 +1,5 @@
 import React from 'react';
 import { DOMElement } from 'ink';
-declare module 'react' {
-    function forwardRef<T, P>(render: (props: P, ref: React.Ref<T>) => React.ReactElement | null): (props: P & React.RefAttributes<T>) => React.ReactElement | null;
-}
 export interface SelectInputProps<T> {
     items: Item<T>[];
     initialItems?: Item<T>[];
@@ -18,7 +15,8 @@ export interface SelectInputProps<T> {
     morePagesMessage?: string;
     availableLines?: number;
     onSubmit?: (item: Item<T>) => void;
-    inputFixedAreaRef?: React.RefObject<DOMElement>;
+    inputFixedAreaRef?: React.Ref<DOMElement>;
+    ref?: React.Ref<DOMElement>;
     groupOrder?: string[];
 }
 export interface Item<T> {
@@ -29,4 +27,5 @@ export interface Item<T> {
     helperText?: string;
     disabled?: boolean;
 }
-export declare const SelectInput: <T>(props: SelectInputProps<T> & React.RefAttributes<DOMElement>) => React.ReactElement | null;
\ No newline at end of file
+declare function SelectInput<T>({ items: rawItems, initialItems, onChange, enableShortcuts, focus, emptyMessage, defaultValue, highlightedTerm, loading, errorMessage, hasMorePages, morePagesMessage, availableLines, onSubmit, inputFixedAreaRef, ref, groupOrder, }: SelectInputProps<T>): React.ReactElement | null;
+export { SelectInput };
\ No newline at end of file

@gonzaloriestra
Copy link
Contributor

/snapit

@github-actions
Copy link
Contributor

🫰✨ Thanks @gonzaloriestra! Your snapshot has been published to npm.

Test the snapshot by installing your package globally:

npm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260210125457

Caution

After installing, validate the version by running just shopify in your terminal.
If the versions don't match, you might have multiple global instances installed.
Use which shopify to find out which one you are running and uninstall it.

@tewson
Copy link
Member Author

tewson commented Feb 11, 2026

@gonzaloriestra Thank you for generating the snapshot build. What are the next steps for me? I tested the snapshot with the shopify theme dev command and it seemed fine but is there a more thorough test I should do?

Copy link
Contributor

You don't need to do anything else. I just need some time to review and test it a bit. Thanks a lot for taking care of this!

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.

2 participants