Skip to content

feat: Initialize React Project with Create React App for Angular to React Migration#176

Open
devin-ai-integration[bot] wants to merge 1 commit intomasterfrom
devin/1771277186-react-cra-init
Open

feat: Initialize React Project with Create React App for Angular to React Migration#176
devin-ai-integration[bot] wants to merge 1 commit intomasterfrom
devin/1771277186-react-cra-init

Conversation

@devin-ai-integration
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot commented Feb 16, 2026

feat: Initialize React + TypeScript project (CRA) for Angular migration

Summary

Replaces the entire Angular 9 codebase with a fresh Create React App + TypeScript foundation for the Angular-to-React migration. This is a scaffolding PR — all route components are placeholders (TODO).

Key changes:

  • Initialized CRA with TypeScript template (React 19, TypeScript 4.9)
  • Configured Prettier (.prettierrc) matching the Angular app's rules: trailingComma: es5, tabWidth: 4, singleQuote: true, printWidth: 120
  • Configured ESLint with react-app + prettier integration
  • Added React Router v6 with routes mirroring the Angular app (/news, /newest, /show, /ask, /jobs, /item, /user)
  • Created folder structure: src/components/, src/contexts/, src/hooks/, src/services/, src/types/
  • Added SettingsContext provider, useDocumentTitle hook, TypeScript type definitions for HN API models
  • Set up .env.development and .env.production environment files
  • Updated public/index.html with SEO meta tags (Open Graph, Twitter cards) and PWA-related tags from the Angular app
  • Updated manifest.json with app name and theme color (#b92b27)

Deleted: All Angular-specific files (angular.json, TSLint, Karma, Protractor e2e, SCSS, Angular components/modules/services, .travis.yml, yarn.lock, all original icon assets).

Screenshot of running React app

Review & Testing Checklist for Human

  • Confirm deleting the entire Angular codebase in this single PR is acceptable — 120 files changed; this removes all original components, services, styles, e2e tests, icons, and CI config. Consider whether the Angular code should be preserved on a separate branch first.
  • Verify the API URL https://node-hnapi.herokuapp.com in .env files is still live — Heroku removed its free tier in 2022 and this endpoint may be dead.
  • Acknowledge CRA is officially deprecated — the CRA init itself prints a deprecation warning. Confirm CRA is still the desired tool vs. Vite or Next.js.
  • Review the 9 npm vulnerabilities (3 moderate, 6 high) from CRA's dependency tree — run npm audit to assess.
  • Check that remaining Firebase config files (.firebaserc, firebase.json, database.rules.json) are still compatible — the React build outputs to build/ whereas the Angular app used dist/angular-hnpwa.

Suggested test plan:

  1. Clone branch, run npm install, then npm start — verify app loads at http://localhost:3000 and redirects to /news/1
  2. Navigate to each route (/news/1, /newest/1, /show/1, /ask/1, /jobs/1) — all should show placeholder text
  3. Run npm run build — verify production build succeeds
  4. Run npm run lint — verify no lint errors
  5. Test the API URL manually: curl https://node-hnapi.herokuapp.com/news — confirm it returns data

Notes

  • All routes currently render placeholder <div>TODO</div> components — actual HN feed/item/user components will be implemented in follow-up PRs.
  • Original PWA icon assets (android-chrome, apple-touch-icon variants, etc.) were deleted; only CRA's default logo192.png and logo512.png remain. Custom icons will need to be re-added.
  • Travis CI config (.travis.yml) was removed; no replacement CI is configured yet.
  • The @types/react-router-dom package was installed but may be redundant since react-router-dom v6+ ships its own types.

Link to Devin run: https://app.devin.ai/sessions/e51e6443a5ab4e0e895822be13c76402
Requested by: @matthewguerra-cog


Staging: Open in Devin
Open with Devin

- Replace Angular 9 project with React 19 + TypeScript 4.9 (CRA template)
- Configure Prettier with matching rules (trailingComma: es5, tabWidth: 4, singleQuote: true, printWidth: 120)
- Configure ESLint with react-app preset and Prettier integration
- Set up React Router v6 with routes matching Angular app (/news, /newest, /show, /ask, /jobs, /item, /user)
- Create folder structure: components/, contexts/, hooks/, services/, types/
- Add SettingsContext provider for app-wide settings
- Add TypeScript type definitions for HN API data models
- Set up environment config files (.env.development, .env.production)
- Update public/index.html with SEO meta tags (Open Graph, Twitter cards) from Angular app
- Update manifest.json for PWA with matching theme color (#b92b27)
- Add useDocumentTitle custom hook
- Add API base URL service configuration

Co-Authored-By: Matthew Guerra <matthew.guerra@cognition.ai>
@devin-ai-integration
Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Copy Markdown
Author

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment thread src/App.test.tsx

test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🟡 Test searches for 'learn react' text that doesn't exist in the App component

The test at src/App.test.tsx:7 uses screen.getByText(/learn react/i) to find an element, but the App component (src/App.tsx) renders "React HN" and "Hacker News client built with React + TypeScript" — neither of which contains the string "learn react".

Root Cause

This appears to be a leftover from the default Create React App template test that was not updated to match the actual App component content. getByText will throw an error when it cannot find a matching element, causing the test to always fail.

Impact: The npm test command will always produce a failing test, breaking CI and giving a false impression that the application is broken.

Suggested change
const linkElement = screen.getByText(/learn react/i);
const linkElement = screen.getByText(/React HN/i);
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

@staging-devin-ai-integration staging-devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 3 potential issues.

🐛 1 issue in files not directly in the diff

🐛 Firebase hosting public directory points to dist instead of CRA's build output (firebase.json:6)

The firebase.json file at line 6 sets "public": "dist", which was the Angular CLI output directory. CRA's react-scripts build outputs to build/, not dist/.

Root Cause

The firebase.json was not updated as part of this migration. When running firebase deploy, Firebase Hosting will look for files in the dist/ directory, which won't exist after npm run build. The deployment will either fail or serve an empty/stale site.

Impact: Firebase deployments will not serve the React app — the production site will be broken after deploying.

View 3 additional findings in Devin Review.

Staging: Open in Devin
Debug

Playground

Comment thread src/App.test.tsx
Comment on lines +5 to +8
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Test searches for non-existent "learn react" text, will always fail

The test in App.test.tsx uses screen.getByText(/learn react/i) to find an element, but the App component (src/App.tsx:10-11) renders <h1>React HN</h1> and <p>Hacker News client built with React + TypeScript</p> — there is no text matching "learn react" anywhere in the rendered output.

Root Cause

This is the default CRA test that was left unchanged after the App component was customized with the HN routes and content. getByText throws when no matching element is found, so npm test will always fail with a TestingLibraryElementError.

Impact: The test suite is broken — npm test will fail, blocking any CI pipeline that runs tests.

Suggested change
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
test('renders app heading', () => {
render(<App />);
const headingElement = screen.getByText(/React HN/i);
expect(headingElement).toBeInTheDocument();
Staging: Open in Devin

Was this helpful? React with 👍 or 👎 to provide feedback.

Debug

Playground

Comment thread src/services/api.ts
@@ -0,0 +1,3 @@
const API_BASE_URL = process.env.REACT_APP_API_URL || 'https://node-hnapi.herokuapp.com';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚩 API_BASE_URL fallback duplicates .env value — no actual fallback if env vars are misconfigured

In src/services/api.ts:1, the fallback || 'https://node-hnapi.herokuapp.com' is identical to the value in both .env.development:2 and .env.production:2. CRA embeds REACT_APP_* env vars at build time, so process.env.REACT_APP_API_URL will always be the string from .env files (never undefined) unless someone explicitly removes the variable. The fallback is therefore unreachable in practice. This isn't a bug, but if the Heroku endpoint is dead (Heroku removed free tier in 2022), both the env files and the fallback will point to a non-functional URL.

Staging: Open in Devin

Was this helpful? React with 👍 or 👎 to provide feedback.

Debug

Playground

Comment thread src/index.tsx
import { SettingsProvider } from './contexts/SettingsContext';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

add a comment above this line

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