Skip to content

feat: React + TypeScript + Vite migration scaffold (Step 1)#245

Draft
devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
react-migration-scaffold
Draft

feat: React + TypeScript + Vite migration scaffold (Step 1)#245
devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
react-migration-scaffold

Conversation

@devin-ai-integration
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot commented May 14, 2026

Summary

This is Step 1 of the Angular-to-React migration. It replaces the Angular build tooling with a Vite + React + TypeScript project and ports the foundational layer (types, API client, utilities, context, and shared components) into the new React architecture.

What's included:

  • Vite + React + TypeScript project initialized with react-ts template
  • Dependencies: react-router-dom, sass
  • Type definitions ported from Angular classes to TypeScript interfaces:
    • src/types/Story.ts, Comment.ts, User.ts, Settings.ts, PollResult.ts
  • API layer (src/api/hackerNewsApi.ts): Plain async functions (fetchFeed, fetchItem, fetchPollContent, fetchUser) using native fetch, replacing the RxJS-based HackerNewsAPIService
  • Utility (src/utils/formatCommentCount.ts): Replaces CommentPipe with a plain function
  • Settings context (src/context/SettingsContext.tsx + src/context/settingsContextValue.ts + src/hooks/useSettings.ts): React Context + useState replacing SettingsService, with localStorage persistence and prefers-color-scheme: dark media query listener
  • Shared components: Loader.tsx and ErrorMessage.tsx ported from Angular with their SCSS styles
  • Angular source files under src/app/ are preserved for reference and excluded from TypeScript compilation and ESLint

Build verification:

  • npm run build passes (tsc + vite build)
  • npm run lint passes (ESLint with react-hooks and react-refresh plugins)

Review & Testing Checklist for Human

  • Verify type interfaces in src/types/ match the Angular models — especially Story.ts which references Comment and PollResult
  • Review src/api/hackerNewsApi.ts — confirm the API endpoint paths match the original HackerNewsAPIService
  • Check SettingsContext logic — confirm localStorage keys and default values match the original SettingsService
  • Run npm install && npm run build locally to confirm the project compiles cleanly
  • Spot-check that src/app/ Angular files are intact and untouched for use as reference in future migration steps

Notes

  • The Angular files under src/app/ are kept intentionally — they will be removed in a later migration step once all components are ported.
  • ESLint config excludes src/app/ to avoid linting legacy Angular code.
  • tsconfig.app.json excludes src/app/ so Angular .ts files don't interfere with the Vite build.

Link to Devin session: https://app.devin.ai/sessions/6eb01ada6ef6467981f60dbeba1c24ad
Requested by: @eashansinha


Devin Review

Status Commit
⚪ Not started

Run Devin Review

💡 Connect your GitHub account to enable automatic code reviews.

Open in Devin Review (Staging)

…act migration

- Initialize Vite project with react-ts template
- Install react-router-dom and sass dependencies
- Port type definitions from Angular classes to TypeScript interfaces:
  Story, Comment, User, Settings, PollResult
- Create hackerNewsApi.ts with async fetch functions replacing
  HackerNewsAPIService (fetchFeed, fetchItem, fetchPollContent, fetchUser)
- Create formatCommentCount.ts utility replacing CommentPipe
- Create SettingsContext with React Context + useState, persisting to
  localStorage with prefers-color-scheme media query listener
- Create Loader and ErrorMessage components ported from Angular
- Exclude Angular src/app/ from TypeScript compilation and ESLint
- All lint and build checks pass

Co-Authored-By: Eashan Sinha <eashan.sinha@cognition.ai>
@devin-ai-integration
Copy link
Copy Markdown
Author

Original prompt from Eashan

Repository: COG-GTM/angular2-hn
Branch: react-migration-scaffold

You are performing Step 1 of an Angular-to-React migration. Complete ALL of the following steps:

  1. Initialize a new React + TypeScript project with Vite (npm create vite@latest . -- --template react-ts) in the repo root. You may need to handle that the directory is not empty — remove Angular build artifacts and config files that conflict, but keep the src/app/ directory for reference until you're done porting. Keep the .git directory.

  2. Install dependencies: react-router-dom, sass.

  3. Port type definitions from src/app/shared/models/ into src/types/:

    • src/app/shared/models/story.tssrc/types/Story.ts (convert class to interface: id, title, points, user, time, time_ago, type, url, domain, comments, comments_count, poll, poll_votes_count, deleted, dead)
    • src/app/shared/models/comment.tssrc/types/Comment.ts (id, level, user, time, time_ago, content, deleted, comments)
    • src/app/shared/models/user.tssrc/types/User.ts (id, crated_time, created, karma, avg, about)
    • src/app/shared/models/settings.tssrc/types/Settings.ts (showSettings, openLinkInNewTab, theme, titleFontSize, listSpacing)
    • src/app/shared/models/poll-result.tssrc/types/PollResult.ts
  4. Create src/api/hackerNewsApi.ts — plain async functions replacing HackerNewsAPIService (currently at src/app/shared/services/hackernews-api.service.ts). Base URL: https://node-hnapi.herokuapp.com. Export functions: fetchFeed(feedType: string, page: number), fetchItem(id: number), fetchPollContent(id: number), fetchUser(id: string). Use native fetch and return parsed JSON.

  5. Create src/utils/formatCommentCount.ts — replaces CommentPipe (at src/app/shared/pipes/comment.pipe.ts). Logic: if count > 0 return ${count} comment(s) (pluralized), else return 'discuss'.

  6. Create src/context/SettingsContext.tsx — replaces SettingsService (`src/app/shared/services/sett... (1059 chars truncated...)

@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/types/User.ts Outdated
@@ -0,0 +1,8 @@
export interface User {
id: string;
crated_time: number;
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.

🟡 Typo in User interface: crated_time should be created_time

The User interface defines a field crated_time which is a typo for created_time. The node-hnapi /user/:id endpoint returns created_time as the field name. Any future code that accesses user.crated_time will get undefined at runtime because the JSON response key is created_time, not crated_time. TypeScript won't catch this since res.json() returns any and is cast to User without validation.

Note: this typo was copied from the original Angular model at src/app/shared/models/user.ts:3, but since the new User type is the interface that all new React code will consume, it should be corrected now.

Suggested change
crated_time: number;
created_time: number;
Open in Devin Review

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

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.

Good catch — fixed. The original Angular model had this typo (crated_time), but since the API returns created_time, the new React interface should use the correct field name to avoid runtime undefined values.

Co-Authored-By: Eashan Sinha <eashan.sinha@cognition.ai>
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