Skip to content

Conversation

@KVNLS
Copy link
Member

@KVNLS KVNLS commented Jan 5, 2026

βœ… Checklist

  • npx changeset was attached.
  • Covered by automatic tests.
  • Impact of the changes:
    • ...

πŸ“ Description

What

Migrate Ledger Live Mobile from Metro bundler to Repack (powered by rspack) for faster and more flexible bundling.

Why

  • Faster build times: Repack leverages rspack (Rust-based bundler) which provides significantly faster bundling compared to Metro
  • Better compatibility: Improved handling of monorepo dependencies and pnpm workspace resolution
  • Developer tooling: Integration with Rozenite for enhanced debugging capabilities (network activity, React Navigation, Redux DevTools, MMKV inspection)
  • Modern architecture: rspack provides better tree-shaking, code splitting capabilities, and webpack ecosystem compatibility
  • Module Federation: We want to unlock this capability for potential usage with Live Apps or other use cases

❓ Context


Build iOS
Build Android

🧐 Checklist for the PR Reviewers

  • The code aligns with the requirements described in the linked JIRA or GitHub issue.
  • The PR description clearly documents the changes made and explains any technical trade-offs or design decisions.
  • There are no undocumented trade-offs, technical debt, or maintainability issues.
  • The PR has been tested thoroughly, and any potential edge cases have been considered and handled.
  • Any new dependencies have been justified and documented.
  • Performance considerations have been taken into account. (changes have been profiled or benchmarked if necessary)

@vercel
Copy link

vercel bot commented Jan 5, 2026

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

4 Skipped Deployments
Project Deployment Review Updated (UTC)
ledger-live-github-bot Ignored Ignored Preview Jan 28, 2026 10:38am
native-ui-storybook Ignored Ignored Preview Jan 28, 2026 10:38am
react-ui-storybook Ignored Ignored Preview Jan 28, 2026 10:38am
web-tools Ignored Ignored Preview Jan 28, 2026 10:38am

Request Review

@live-github-bot live-github-bot bot added the mobile Has changes in LLM label Jan 5, 2026
@live-github-bot
Copy link
Contributor

live-github-bot bot commented Jan 5, 2026

Desktop Bundle Checks

Comparing 3fbef34 against 8edd2a9.

βœ… Previous issues have all been fixed.

Mobile Bundle Checks

Comparing 3fbef34 against 8edd2a9.

⚠️ main.ios.jsbundle bundle size significantly increased: 55.6mb -> 56mb. Please check if this is expected.
⚠️ main.android.jsbundle bundle size significantly increased: 55.6mb -> 56mb. Please check if this is expected.

@KVNLS KVNLS force-pushed the fix/circular-dependency-redux branch from 1674479 to f831fd5 Compare January 7, 2026 08:35
Base automatically changed from fix/circular-dependency-redux to develop January 7, 2026 09:29
@KVNLS KVNLS force-pushed the feat/repack-bundler branch 4 times, most recently from c7c0873 to 2bc56e5 Compare January 13, 2026 17:03
@KVNLS KVNLS force-pushed the feat/repack-bundler branch 5 times, most recently from e474f65 to 52cf9e2 Compare January 20, 2026 15:11
@KVNLS KVNLS marked this pull request as ready for review January 20, 2026 15:52
@KVNLS KVNLS requested a review from a team as a code owner January 20, 2026 15:52
Copilot AI review requested due to automatic review settings January 20, 2026 15:52
ysitbon
ysitbon previously approved these changes Jan 20, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates Ledger Live Mobile from Metro bundler to Repack (powered by rspack) to achieve faster build times, better monorepo compatibility, and enhanced developer tooling through Rozenite integration.

Changes:

  • Replaced Metro bundler with Repack/rspack for significantly faster build times and better pnpm workspace resolution
  • Added Rozenite integration for enhanced debugging capabilities (network monitoring, Redux DevTools, navigation inspection, MMKV storage)
  • Updated build scripts and iOS/Android configurations to support the new bundler architecture

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pnpm-lock.yaml Added @callstack/repack packages, @rspack/core, and @rozenite/repack; removed @react-native/metro-config and @rozenite/metro
apps/ledger-live-mobile/rspack.config.mjs New rspack configuration with TypeScript alias resolution, pnpm workspace support, and Rozenite integration
apps/ledger-live-mobile/react-native.config.js Added Repack rspack commands configuration
apps/ledger-live-mobile/package.json Updated bundle scripts with increased Node memory allocation and added new Repack dependencies
apps/ledger-live-mobile/babel.config.js Added metro-transform-plugins for inline requires and removed styled-components plugin configuration
apps/ledger-live-mobile/src/reducers/accounts.ts Added optional chaining to accountsSelector for safer state access
apps/ledger-live-mobile/ios/ledgerlivemobile.xcodeproj/project.pbxproj Updated React Native bundling script to properly detect CLI path
apps/ledger-live-mobile/ios/Podfile.lock Added callstack-repack pod with dependencies (JWTDecode, SwiftyRSA)
apps/ledger-live-mobile/android/app/build.gradle Added androidx.appcompat:appcompat dependency
knip.json Updated ignored dependencies to reflect bundler migration
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* This is important because the `accounts` array is modified at the end almost
* every account sync, so potentially you could avoid many unnessary and
* expensive re-renders.
*/
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The optional chaining operator (?.) is added to safely access s.accounts.active. While this prevents potential runtime errors, it would be helpful to understand why this defensive coding is necessary. Is there a scenario where s.accounts could be undefined or null during the migration to Repack? If this is a workaround for a bundler-related initialization issue, it should be documented in a comment explaining the context.

Suggested change
*/
*/
// Note: we use optional chaining on `s.accounts` here because, during app startup
// (e.g. store hydration, state migrations, or Repack/bundler-related initialization),
// the `accounts` slice can briefly be undefined/null before the reducer state is
// fully initialized. This defensive access avoids crashes in those transient states.

Copilot uses AI. Check for mistakes.
"@babel/plugin-transform-export-namespace-from",
"@babel/plugin-transform-class-static-block",
"@babel/plugin-transform-flow-strip-types",
["@babel/plugin-transform-private-methods", { loose: true }],
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The babel-plugin-styled-components configuration has been removed from babel.config.js. This plugin was previously configured with specific options for SSR, display names, minification, and template literal transpilation. Ensure that styled-components still functions correctly without this configuration, or verify that the Repack bundler handles styled-components transformation internally. If this functionality is no longer needed, consider removing the babel-plugin-styled-components dependency from package.json as well.

Suggested change
["@babel/plugin-transform-private-methods", { loose: true }],
["@babel/plugin-transform-private-methods", { loose: true }],
[
"babel-plugin-styled-components",
{
ssr: true,
displayName: true,
minify: true,
transpileTemplateLiterals: true,
},
],

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 160
import path from "node:path";
import { fileURLToPath } from "node:url";
import * as Repack from "@callstack/repack";
import { ReanimatedPlugin } from "@callstack/repack-plugin-reanimated";
import { ExpoModulesPlugin } from "@callstack/repack-plugin-expo-modules";
import { createRequire } from "node:module";
import { readFileSync, existsSync, readdirSync } from "node:fs";
import { withRozenite } from "@rozenite/repack";

const require = createRequire(import.meta.url);

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRootDir = path.resolve(__dirname, "..", "..");

const tsconfig = JSON.parse(readFileSync(path.join(__dirname, "./tsconfig.json"), "utf8"));
const resolveFromPnpmSubmodule = (...subPath) => {
const pnpmDir = path.resolve(projectRootDir, "node_modules", ".pnpm");
for (const entry of readdirSync(pnpmDir)) {
const candidate = path.join(pnpmDir, entry, ...subPath);
if (existsSync(candidate)) return candidate;
}
throw new Error(`Cannot resolve pnpm submodule path: ${path.join(...subPath)}`);
};

const removeStarPath = moduleName => moduleName.replace("/*", "");
const buildTsAlias = (paths = {}) =>
Object.keys(paths).reduce(
(acc, moduleName) => ({
...acc,
[removeStarPath(moduleName)]: path.resolve(__dirname, removeStarPath(paths[moduleName][0])),
}),
{},
);

const nodeModulesPaths = [
path.resolve(__dirname, "node_modules"),
path.resolve(projectRootDir, "node_modules"),
path.resolve(projectRootDir, "node_modules", ".pnpm"),
path.resolve(projectRootDir, "node_modules", ".pnpm", "node_modules"),
"node_modules",
];

const hermesParserPath = require.resolve("hermes-parser");

export default withRozenite(
Repack.defineRspackConfig(env => {
const { mode, platform } = env;
return {
mode,
context: __dirname,
entry: "./index.js",
resolve: {
...Repack.getResolveOptions(platform, {
enablePackageExports: true,
preferNativePlatform: true,
}),
fullySpecified: false,
modules: nodeModulesPaths,
extensions: [
`.${platform}.tsx`,
`.${platform}.ts`,
`.${platform}.jsx`,
`.${platform}.js`,
".native.tsx",
".native.ts",
".native.jsx",
".native.js",
".tsx",
".ts",
".jsx",
".js",
".mjs",
".cjs",
".json",
"...",
],
enforceExtension: false,
mainFields: ["react-native", "browser", "main", "module"],
conditionNames: ["require", "react-native", "browser"],
alias: {
...buildTsAlias(tsconfig.compilerOptions.paths),
// Packages with malformed exports field (missing "." subpath) - resolve to browser entry
"@aptos-labs/aptos-client": resolveFromPnpmSubmodule(
"node_modules",
"@aptos-labs",
"aptos-client",
"dist",
"browser",
"index.browser.mjs",
),
"rpc-websockets": resolveFromPnpmSubmodule(
"node_modules",
"rpc-websockets",
"dist",
"index.browser.mjs",
),
},
fallback: {
...require("node-libs-react-native"),
fs: require.resolve("react-native-level-fs"),
net: require.resolve("react-native-tcp-socket"),
tls: false,
child_process: false,
cluster: false,
dgram: false,
dns: false,
readline: false,
module: false,
repl: false,
vm: false,
},
},
module: {
rules: [
{
test: /\.[cm]?[jt]sx?$/,
use: {
loader: "@callstack/repack/babel-loader",
parallel: true,
options: {
hermesParserPath,
},
},
resolve: {
fullySpecified: false,
},
type: "javascript/auto",
},
...Repack.getAssetTransformRules(),
],
},
plugins: [
new Repack.RepackPlugin(),
new ReanimatedPlugin({
unstable_disableTransform: true,
}),
new ExpoModulesPlugin(),
],
};
}),
{
enabled: process.env.WITH_ROZENITE === "true",
include: [
"@rozenite/network-activity-plugin",
"@rozenite/react-navigation-plugin",
"@rozenite/redux-devtools-plugin",
"@rozenite/mmkv-plugin",
],
},
);
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The new rspack.config.mjs configuration file lacks test coverage. Given that this is a critical infrastructure change affecting the entire build and bundling process, it would be beneficial to add integration tests that verify the bundler configuration works correctly for both iOS and Android platforms in development and production modes.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +23
for (const entry of readdirSync(pnpmDir)) {
const candidate = path.join(pnpmDir, entry, ...subPath);
if (existsSync(candidate)) return candidate;
}
throw new Error(`Cannot resolve pnpm submodule path: ${path.join(...subPath)}`);
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The error handling in resolveFromPnpmSubmodule could be improved. Currently, if no matching pnpm submodule is found, it throws an error with the path that was being searched. However, this error message doesn't show which specific entry was attempted. Consider including more debugging information in the error message, such as the pnpm directory being searched or the list of entries that were checked.

Suggested change
for (const entry of readdirSync(pnpmDir)) {
const candidate = path.join(pnpmDir, entry, ...subPath);
if (existsSync(candidate)) return candidate;
}
throw new Error(`Cannot resolve pnpm submodule path: ${path.join(...subPath)}`);
const entries = readdirSync(pnpmDir);
for (const entry of entries) {
const candidate = path.join(pnpmDir, entry, ...subPath);
if (existsSync(candidate)) return candidate;
}
throw new Error(
`Cannot resolve pnpm submodule path: ${path.join(
...subPath,
)}; searched in: ${pnpmDir}; checked entries: ${entries.join(", ") || "<none>"}`,
);

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Contributor

github-actions bot commented Jan 23, 2026

⚠️ E2E tests are required

Changes detected require e2e testing before merge (even before asking for any review).

πŸ–₯️ Desktop

-> Run Desktop E2E

  • Select "Run workflow"
  • Branch: feat/repack-bundler
  • Device: nanoSP or stax

πŸ“± Mobile

-> Run Mobile E2E

  • Select "Run workflow"
  • Branch: feat/repack-bundler
  • Device: nanoX

Copilot AI review requested due to automatic review settings January 23, 2026 15:28
@KVNLS KVNLS force-pushed the feat/repack-bundler branch from 1f40bcb to f8938ec Compare January 23, 2026 15:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 11 changed files in this pull request and generated 5 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"@react-native-firebase/remote-config": "22.2.0",
"@react-native-masked-view/masked-view": "0.2.9",
"@react-native/assets-registry": "catalog:",
"@react-native/community-cli-plugin": "0.77.3",
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

@react-native/community-cli-plugin is pinned to 0.77.3 while this app is on the React Native catalog version (0.79.x). This introduces multiple versions of RN CLI/Metro-related packages in the lockfile and risks incompatibilities. Prefer aligning this to the React Native version used in the repo (e.g., via catalog), or remove the explicit dependency if it’s already provided transitively by react-native/@react-native-community/cli.

Suggested change
"@react-native/community-cli-plugin": "0.77.3",
"@react-native/community-cli-plugin": "catalog:",

Copilot uses AI. Check for mistakes.
Comment on lines 66 to 68
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Staging"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The Xcode scheme’s LaunchAction buildConfiguration was changed from Debug to Staging while TestAction remains Debug. This is a significant behavioral change for local Xcode runs and seems unrelated to the bundler migration. If unintentional, revert to Debug; if intentional, consider documenting why Staging should be the default launch configuration and whether TestAction should be updated for consistency.

Copilot uses AI. Check for mistakes.
Comment on lines 229 to 232
androidTestImplementation('com.wix:detox:+')
implementation 'androidx.appcompat:appcompat:1.1.0'
// Needed for Detox getAttributes on Android : https://github.com/wix/Detox/issues/3147
implementation 'com.google.android.material:material:1.6.0'
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

Pinning androidx.appcompat:appcompat to 1.1.0 is very old and may cause dependency resolution conflicts with other AndroidX libraries (or miss fixes needed on newer SDKs). If this is required for Detox, consider aligning to the version recommended by Detox/RN docs or the rest of the project’s AndroidX versions; otherwise avoid forcing an explicit appcompat version here.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +24
const resolveFromPnpmSubmodule = (...subPath) => {
const pnpmDir = path.resolve(projectRootDir, "node_modules", ".pnpm");
for (const entry of readdirSync(pnpmDir)) {
const candidate = path.join(pnpmDir, entry, ...subPath);
if (existsSync(candidate)) return candidate;
}
throw new Error(`Cannot resolve pnpm submodule path: ${path.join(...subPath)}`);
};
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

resolveFromPnpmSubmodule scans every entry under node_modules/.pnpm on each config evaluation to find a matching file. This can be noticeably slow in large workspaces and is brittle if the .pnpm directory layout changes. Prefer resolving from the package root deterministically (e.g., resolve the package.json path with require.resolve using nodeModulesPaths, then join to the desired file), and/or cache results to avoid repeated directory scans.

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +62
setupMiddlewares: middlewares => {
const result = originalSetupMiddlewares(middlewares);
result.unshift((req, res, next) => {
if (req.url?.startsWith("/debugger-frontend/")) {
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

withRozeniteUrlFix wraps devServer.setupMiddlewares but only forwards the first parameter to the original handler. If the underlying devServer implementation passes additional arguments (e.g., the devServer instance), this wrapper will drop them and can break the original middleware setup. Forward all arguments when delegating to originalSetupMiddlewares.

Copilot uses AI. Check for mistakes.
@KVNLS KVNLS force-pushed the feat/repack-bundler branch from f8938ec to 59a539e Compare January 23, 2026 15:48
@KVNLS KVNLS requested a review from a team as a code owner January 23, 2026 15:48
Copilot AI review requested due to automatic review settings January 23, 2026 16:45
@KVNLS KVNLS force-pushed the feat/repack-bundler branch from 59a539e to 83b25b7 Compare January 23, 2026 16:45
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 13 changed files in this pull request and generated 1 comment.


πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=$(command -v node)\n\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\n\nif [[ \"$SKIP_JS_BUNDLING\" == \"true\" ]]; then\n REACT_NATIVE_XCODE=\"\"\n echo \"Skipping JS bundle\"\nelse\n echo \"Not skipping JS bundle\"\n REACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nfi\n\nBUNDLE_REACT_NATIVE=\"$REACT_NATIVE_XCODE\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$BUNDLE_REACT_NATIVE\\\"\"\n";
shellScript = "export NODE_BINARY=$(command -v node)\n\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\n\nif [[ \"$SKIP_JS_BUNDLING\" == \"true\" ]]; then\n REACT_NATIVE_XCODE=\"\"\n echo \"Skipping JS bundle\"\nelse\n echo \"Not skipping JS bundle\"\n REACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nfi\n\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\nexport CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@react-native-community/cli/package.json')) + '/build/bin.js'\")\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The new iOS bundle script always invokes with-environment.sh even when SKIP_JS_BUNDLING=true sets REACT_NATIVE_XCODE to an empty string. In that case, /bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE" will call with-environment.sh without the target script path and can fail the build. Consider short-circuiting the script when SKIP_JS_BUNDLING is true, or only invoking with-environment.sh when REACT_NATIVE_XCODE is non-empty (and keep proper quoting).

Copilot uses AI. Check for mistakes.
@KVNLS KVNLS force-pushed the feat/repack-bundler branch from 83b25b7 to ba876fc Compare January 26, 2026 17:26
Copilot AI review requested due to automatic review settings January 26, 2026 20:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 13 changed files in this pull request and generated 2 comments.


πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +46 to +73
const withRozeniteUrlFix = rozeniteConfig => {
return async env => {
const config = await rozeniteConfig(env);
if (!config.devServer?.setupMiddlewares) {
return config;
}

const originalSetupMiddlewares = config.devServer.setupMiddlewares;

return {
...config,
devServer: {
...config.devServer,
setupMiddlewares: middlewares => {
const result = originalSetupMiddlewares(middlewares);
result.unshift((req, res, next) => {
if (req.url?.startsWith("/debugger-frontend/")) {
const newUrl = req.url.replace("/debugger-frontend/", "/rozenite/");
res.writeHead(302, { Location: newUrl });
res.end();
return;
}
next();
});

return result;
},
},
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

withRozeniteUrlFix wraps devServer.setupMiddlewares but changes the function signature to accept only middlewares. webpack-dev-server passes (middlewares, devServer); dropping the second arg can break upstream middleware setup that relies on devServer.

Recommend preserving the signature by using (...args) => { const result = originalSetupMiddlewares(...args); ... }.

Copilot uses AI. Check for mistakes.
@@ -274,7 +280,7 @@
"babel-jest": "catalog:",
"babel-plugin-styled-components": "2.1.4",
"babel-plugin-transform-inline-environment-variables": "0.4.4",
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

babel-plugin-transform-inline-environment-variables remains in devDependencies, but it was removed from babel.config.js and doesn’t appear to be referenced elsewhere in the repo. Keeping it adds install surface area without effect.

Either re-add it to the Babel plugins list (if still needed) or remove the dependency from this package.

Suggested change
"babel-plugin-transform-inline-environment-variables": "0.4.4",

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings January 27, 2026 17:14
@KVNLS KVNLS force-pushed the feat/repack-bundler branch from 79bc3b9 to c6ca4f4 Compare January 27, 2026 17:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 12 changed files in this pull request and generated 2 comments.


πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +230 to 231
implementation 'androidx.appcompat:appcompat:1.1.0'
// Needed for Detox getAttributes on Android : https://github.com/wix/Detox/issues/3147
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The newly added androidx.appcompat:appcompat:1.1.0 is very old relative to the project’s compileSdkVersion = 35 and can introduce unnecessary version skew in the AndroidX dependency graph. Also, the Detox-related comment below now reads as if it applies to material, not the added AppCompat line.

If AppCompat is required, prefer aligning its version with the rest of the resolved AndroidX set (or relying on the transitive AppCompat brought by Material, if applicable) and update/move the comment to match the dependency it refers to.

Suggested change
implementation 'androidx.appcompat:appcompat:1.1.0'
// Needed for Detox getAttributes on Android : https://github.com/wix/Detox/issues/3147
// Needed for Detox getAttributes on Android : https://github.com/wix/Detox/issues/3147
implementation 'androidx.appcompat:appcompat:1.6.1'

Copilot uses AI. Check for mistakes.
Comment on lines 229 to 233
androidTestImplementation('com.wix:detox:+')
implementation 'androidx.appcompat:appcompat:1.1.0'
// Needed for Detox getAttributes on Android : https://github.com/wix/Detox/issues/3147
implementation 'com.google.android.material:material:1.6.0'
implementation 'com.facebook.soloader:soloader:0.10.4+'
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The Gradle dependencies androidTestImplementation('com.wix:detox:+') and implementation 'com.facebook.soloader:soloader:0.10.4+' use dynamic + versions, which means each build may fetch a newer, unvetted artifact and execute its code with access to your CI environment and secrets. This creates a supply-chain risk where a compromised upstream release or registry could silently introduce malicious code into your test or production builds. To reduce this risk, pin these libraries to explicit, vetted versions (or immutable coordinates) instead of using + or other dynamic version ranges.

Copilot uses AI. Check for mistakes.
@KVNLS KVNLS force-pushed the feat/repack-bundler branch from c6ca4f4 to c5511cc Compare January 28, 2026 10:38
@sonarqubecloud
Copy link

@gre-ledger gre-ledger mentioned this pull request Jan 30, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mobile Has changes in LLM

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants