Skip to content

chore(angular-react): Migrate Angular 9 HN PWA to React 18 + TypeScript + Vite#325

Open
devin-ai-integration[bot] wants to merge 4 commits into
masterfrom
devin/1781118972-angular-to-react-migration
Open

chore(angular-react): Migrate Angular 9 HN PWA to React 18 + TypeScript + Vite#325
devin-ai-integration[bot] wants to merge 4 commits into
masterfrom
devin/1781118972-angular-to-react-migration

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 10, 2026

Copy link
Copy Markdown

Summary

Migrates the Angular 9 Hacker News PWA to React 18 + TypeScript + Vite, preserving all user-facing behavior: the same URL structure, the three-theme engine, the Hacker News API data contracts, and PWA/offline support. The app now lives in react-app/. The Angular source has been removed in this PR (cleanup phase) after the React app was verified running locally against the live API.

Build, lint and type-check all pass with zero errors:

react-app$ npm run build   # tsc -b && vite build  -> OK (sw.js + manifest generated)
react-app$ npm run lint    # eslint .              -> 0 problems
react-app$ npm run typecheck  # tsc -b --noEmit    -> 0 errors

Architecture mapping (Angular → React)

Angular React
HackerNewsAPIService (RxJS Observable + lazyFetch) src/services/hackernewsApi.tsfetch/async-await + AbortController; keeps the unfetch fallback and the same https://node-hnapi.herokuapp.com base URL and endpoints
SettingsService (DI singleton + matchMedia) src/context/SettingsContext.tsx — React Context with localStorage persistence and prefers-color-scheme listener
app.component + router-outlet src/App.tsx<Routes> + theme class + GA pageview on location change
core/header, core/footer, core/settings src/components/Header.tsx, Footer.tsx, Settings.tsx
feeds/feed, feeds/item (+ comment) src/components/Feed.tsx, Item.tsx, ItemDetails.tsx, Comment.tsx (recursive)
lazy item/user NgModules React.lazy + <Suspense> for ItemDetails/User
loading / error states src/components/Loader.tsx, ErrorMessage.tsx
shared/models/* src/models/index.ts
component .scss + shared/scss themes src/**/*.scss (ported 1:1; :host >>> rewritten to class scoping)
ngsw-config.json (Workbox) vite-plugin-pwa (generateSW) in vite.config.ts — app-shell precache + runtime caching for /assets/ and the HN API
index.html (GA, theme-color, app-loader SVG, skip-link, manifest/icons) react-app/index.html (ported verbatim)

Routes preserved (React Router v6)

/ → redirect /news/1; /news/:page, /newest/:page, /show/:page, /ask/:page, /jobs/:page; /item/:id; /user/:id. Pipe equivalents (timeAgo, domain, points) reimplemented as plain TS.

Theming

All three themes work and persist via localStorage: Default, Night, Black (AMOLED), plus auto-switch to Night on prefers-color-scheme: dark.

PWA status

vite-plugin-pwa generates sw.js + manifest.webmanifest during build (precaches 33 entries / ~308 KiB app shell; runtime caching mirrors the old ngsw-config.json).

CI/CD

  • .travis.yml now runs cd react-app && npm ci && npm run lint && npm run build on Node 18 and deploys via firebase deploy.
  • firebase.json public changed distreact-app/dist (SPA rewrites unchanged).

Verification

Ran npm run dev and exercised the app against the live API:

  • News feed loads 30 stories with titles/points/users/comments.
  • Item detail renders the nested comment tree; [-]/[+] collapse toggles work.
  • All 3 themes switch live from the Settings panel.
  • Jobs feed renders the YC job-header.
  • /user/:id shows the error UI — note the upstream node-hnapi /user endpoint currently 404s for all users (including pg), so this matches the original Angular app's behavior and is not a migration regression.

Screenshots

News feed (Default theme):
news feed

Item detail with nested comments:
item detail

Night theme:
night theme

Black (AMOLED) theme:
amoled theme

Settings panel (theme/links/font/spacing):
settings

Jobs feed:
jobs feed

Link to Devin session: https://app.devin.ai/sessions/20a1c7bc50864105bfaedd552aef24f8
Requested by: @lburgers


Devin Review

Status Commit
🟢 Reviewed 97f0e22
Open in Devin Review (Staging)

devin-ai-integration Bot and others added 2 commits June 10, 2026 19:24
Migrate the Angular 9 HN PWA to React 18 + TypeScript + Vite:
- Services: HackerNewsAPIService -> fetch/async-await with AbortController; SettingsService -> SettingsContext (localStorage + matchMedia)
- Components: Header, Footer, Settings, Feed, Item, ItemDetails, Comment, User, Loader, ErrorMessage
- Routing: React Router v6 with same URLs; lazy-loaded Item/User via React.lazy/Suspense
- Theming: ported SCSS (Default, Night, AMOLED)
- PWA: vite-plugin-pwa + workbox; ported index.html metadata/GA/app-loader/skip-link
- CI/CD: Travis + firebase.json updated to build/deploy react-app

Co-Authored-By: Lukas Burger <lukaskburger@gmail.com>
…erified

The React + Vite app in react-app/ has been verified running (feeds, item
detail with comments, user error handling, all 3 themes, navigation).
Per the playbook cleanup phase, remove Angular-specific files (src/, e2e/,
angular.json, karma/tslint configs, ngsw-config.json, Angular tsconfigs,
package.json, yarn.lock) and update the README to document the React/Vite
build and run process.

Co-Authored-By: Lukas Burger <lukaskburger@gmail.com>
@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, CI, and merge conflict monitoring

staging-devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

Restore Angular DomSanitizer parity by sanitizing all dangerouslySetInnerHTML
content (comments, item/poll content, user about) via a shared sanitizeHtml util.

Co-Authored-By: Lukas Burger <lukaskburger@gmail.com>

@staging-devin-ai-integration staging-devin-ai-integration Bot 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.

Devin Review found 1 new potential issue.

⚠️ 1 issue in files not directly in the diff

⚠️ CONTRIBUTING.md not updated after Angular-to-React migration, rendering all setup instructions non-functional (CONTRIBUTING.md:4-20)

The PR removes the root package.json, Angular CLI configuration, and all Angular source code, but does not update CONTRIBUTING.md. Steps 4–10 in CONTRIBUTING.md are now completely broken: step 4 tells contributors to install Angular CLI, step 5 says to run ng init, step 7 says npm start and localhost:4200, step 9 says npm run build at the root—none of these commands work anymore. The README was updated with the new react-app/ workflow (Vite dev server, npm run dev on port 5173, etc.), but CONTRIBUTING.md was not.

Open in Devin Review (Staging)
Debug

Playground

devin-ai-integration[bot]

This comment was marked as resolved.

Removing <base href="/"> during migration left relative favicon/icon/splash
URLs that 404 on direct navigation to sub-routes (e.g. /item/123). Convert them
to root-absolute paths; avoids a <base> tag which would break the #content skip-link.

Co-Authored-By: Lukas Burger <lukaskburger@gmail.com>

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

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.

Devin Review found 0 new potential issues.

View 5 additional findings in Devin Review.

Open in Devin Review

@staging-devin-ai-integration staging-devin-ai-integration Bot 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.

Devin Review found 0 new potential issues.

Open in Devin Review (Staging)
Debug

Playground

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