Remove Expo dependencies and refactor to bare React Native#1
Conversation
- Remove all Expo packages (expo-router, expo-font, expo-splash-screen, expo-status-bar, expo-web-browser, expo-constants, expo-system-ui, expo-linking, @expo/vector-icons) - Replace @expo/vector-icons with react-native-vector-icons - Replace expo-router file-based routing with standard RN entry point - Fix parseInt() calls missing radix parameter (parse vulnerability) - Add NaN validation guard on settings form submission - Fix .gitignore that was excluding package.json and package-lock.json - Remove dangerouslySetInnerHTML usage (was in Expo web HTML template) - Remove unused Expo boilerplate (explore tab, themed components, parallax scroll, collapsible, hello wave, external link, etc.) - Fix timer stop not resetting all phase states - Fix settings button positioned with hardcoded left offset - Restructure to src/screens/ layout with clean separation - Add babel.config.js and metro.config.js for bare RN - Update tsconfig.json to standalone config (no Expo base) - Simplify app.json to bare RN format https://claude.ai/code/session_01Rp88EoMTfDVMGJDbBd15tV
|
You have run out of free Bugbot PR reviews for this billing cycle. This will reset on March 11. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
There was a problem hiding this comment.
Pull request overview
This PR migrates the app from an Expo (expo-router) project to a bare React Native structure, removing Expo-specific dependencies/boilerplate and refactoring the UI into src/screens with a standard RN entry point.
Changes:
- Remove Expo Router and related Expo modules/boilerplate, including themed components and the template tab navigation.
- Introduce a bare RN entry (
index.js+App.tsx) and Metro/Babel configuration for non-Expo builds. - Refactor timer + settings screens, including safer
parseInt(..., 10)usage and NaN guarding on settings submission.
Reviewed changes
Copilot reviewed 28 out of 37 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Replaces expo/tsconfig.base with a standalone TypeScript configuration. |
| src/screens/TimerScreen.tsx | Refactors timer logic/UI, replaces Expo vector icons, and embeds settings navigation via local state. |
| src/screens/SettingsScreen.tsx | Refactors settings UI (custom buttons), fixes parseInt radix usage, and adds NaN guards. |
| scripts/reset-project.js | Removes Expo template reset script. |
| package.json | Removes Expo deps/scripts, switches to bare RN scripts and jest preset, adds RN picker + vector icons. |
| metro.config.js | Adds Metro config using @react-native/metro-config. |
| index.js | Adds standard RN entry point registering App. |
| hooks/useThemeColor.ts | Removes Expo template theming hook. |
| hooks/useColorScheme.web.ts | Removes Expo template web color scheme hook. |
| hooks/useColorScheme.ts | Removes Expo template color scheme re-export. |
| expo-env.d.ts | Removes Expo type reference file. |
| constants/Colors.ts | Removes Expo template color constants. |
| components/navigation/TabBarIcon.tsx | Removes Expo template tab bar icon helper. |
| components/tests/snapshots/ThemedText-test.tsx.snap | Removes Expo template snapshot. |
| components/tests/ThemedText-test.tsx | Removes Expo template test. |
| components/ThemedView.tsx | Removes Expo template themed view component. |
| components/ThemedText.tsx | Removes Expo template themed text component. |
| components/ParallaxScrollView.tsx | Removes Expo template parallax component. |
| components/HelloWave.tsx | Removes Expo template animated wave component. |
| components/ExternalLink.tsx | Removes Expo template external link component. |
| components/Collapsible.tsx | Removes Expo template collapsible component. |
| babel.config.js | Adds bare RN Babel preset configuration. |
| app/_layout.tsx | Removes Expo Router root layout. |
| app/+not-found.tsx | Removes Expo Router not-found screen. |
| app/+html.tsx | Removes Expo Router web HTML template. |
| app/(tabs)/route.tsx | Removes Expo Router tab route wrapper. |
| app/(tabs)/explore.tsx | Removes Expo template “Explore” tab. |
| app/(tabs)/_layout.tsx | Removes Expo Router tabs layout. |
| app.json | Simplifies config to bare RN-style name/displayName. |
| App.tsx | Adds bare RN root component with SafeAreaProvider + StatusBar + TimerScreen. |
| .gitignore | Fixes ignores (no longer excludes package manifests) and updates patterns for bare RN. |
Comments suppressed due to low confidence (3)
src/screens/TimerScreen.tsx:43
handlePlayClickalways forcesisPreparationRunningto true, even when the user is resuming from a paused interval/rest phase. BecausehandlePlayClickdoesn’t clearisIntervalRunning/isRestRunning, resuming can leave multiple phase flags true and effectively restart the timer from “Prepare” instead of resuming the paused phase. Consider splitting “start” vs “resume” behavior (resume should typically just clearisPausedand setisPlaying), or explicitly reset the other phase flags when starting over.
src/screens/TimerScreen.tsx:96- When the timer completes (end of the last rest), the code stops the timer but does not reset
currentTime(or phase flags) back topreparationTime. If the user presses play again,currentTimemay still be 0, causing the effect to immediately transition phases and skip the intended preparation countdown. Reset the timer state on completion (e.g., setcurrentTimeback topreparationTimeand clear phase flags), or ensurehandlePlayClickinitializescurrentTimewhen starting from a stopped/completed state.
src/screens/TimerScreen.tsx:111 handlePlayClickis listed in this effect’s dependency array, but it isn’t referenced anywhere in the effect body. This can cause unnecessary effect re-runs ifhandlePlayClickchanges (and it’s confusing to readers). Remove it from the dependency list (or reference it if it’s intended to be used).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,5 @@ | |||
| const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); | |||
There was a problem hiding this comment.
metro.config.js requires @react-native/metro-config, but package.json doesn’t declare it. This will break a clean install (module not found) even if it happens to exist in the current node_modules. Add @react-native/metro-config to devDependencies (matching your React Native version) or adjust the config to avoid the dependency.
| "scripts": { | ||
| "start": "expo start", | ||
| "reset-project": "./scripts/reset-project.js", | ||
| "android": "expo start --android", | ||
| "ios": "expo start --ios", | ||
| "web": "expo start --web", | ||
| "test": "jest --watchAll", | ||
| "lint": "expo lint" | ||
| }, | ||
| "jest": { | ||
| "preset": "jest-expo" | ||
| "start": "react-native start", | ||
| "android": "react-native run-android", | ||
| "ios": "react-native run-ios", | ||
| "test": "jest", |
There was a problem hiding this comment.
The project scripts now use react-native run-android / react-native run-ios, but this repo currently has no android/ or ios/ native projects. As-is, these scripts will fail and the PR’s “bare React Native” goal isn’t met. Either add/commit the native project folders (or a generation step like prebuild) or update the scripts/docs to match the actual build workflow.
Uh oh!
There was an error while loading. Please reload this page.