Skip to content

Remove Expo dependencies and refactor to bare React Native#1

Open
Maxerns wants to merge 1 commit into
mainfrom
refactor/remove-expo
Open

Remove Expo dependencies and refactor to bare React Native#1
Maxerns wants to merge 1 commit into
mainfrom
refactor/remove-expo

Conversation

@Maxerns

@Maxerns Maxerns commented Feb 7, 2026

Copy link
Copy Markdown
Owner
  • 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

- 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
Copilot AI review requested due to automatic review settings February 7, 2026 17:57
@cursor

cursor Bot commented Feb 7, 2026

Copy link
Copy Markdown

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.

Copilot AI left a comment

Copy link
Copy Markdown

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 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

  • handlePlayClick always forces isPreparationRunning to true, even when the user is resuming from a paused interval/rest phase. Because handlePlayClick doesn’t clear isIntervalRunning / 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 clear isPaused and set isPlaying), 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 to preparationTime. If the user presses play again, currentTime may still be 0, causing the effect to immediately transition phases and skip the intended preparation countdown. Reset the timer state on completion (e.g., set currentTime back to preparationTime and clear phase flags), or ensure handlePlayClick initializes currentTime when starting from a stopped/completed state.
    src/screens/TimerScreen.tsx:111
  • handlePlayClick is listed in this effect’s dependency array, but it isn’t referenced anywhere in the effect body. This can cause unnecessary effect re-runs if handlePlayClick changes (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.

Comment thread metro.config.js
@@ -0,0 +1,5 @@
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment thread package.json
Comment on lines 6 to +10
"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",

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
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