Skip to content

Migrate Conduit from Angular to React (TypeScript + Vite)#38

Draft
milind-cognition wants to merge 9 commits into
mainfrom
cursor/bc-0577874e-8921-48c9-9048-7b37dd0d8ed8-2d70
Draft

Migrate Conduit from Angular to React (TypeScript + Vite)#38
milind-cognition wants to merge 9 commits into
mainfrom
cursor/bc-0577874e-8921-48c9-9048-7b37dd0d8ed8-2d70

Conversation

@milind-cognition

@milind-cognition milind-cognition commented Jun 16, 2026

Copy link
Copy Markdown

Summary

Migrates the Conduit RealWorld app from Angular 21 to React 18 + TypeScript + Vite, with full behavioral parity. The framework-agnostic Playwright e2e suite in e2e/ (and its SELECTORS.md contract) is the source of truth and passes unchanged — same routes, CSS classes, name attributes, text labels, localStorage['jwtToken'], /assets/default-avatar.svg, and the window.__conduit_debug__ interface.

No backend changes, no new features, no redesign — a pure framework migration.

What changed

Removed all Angular code/config (src/app/**, angular.json, Angular tsconfigs, vitest.config.ts, etc.).

Added a React app under src/:

  • src/api/fetch-based client (client.ts) replacing Angular's HttpClient + the api/token/error interceptors: prepends the API base URL, attaches Authorization: Token <jwt>, normalizes errors to { errors, status } (with the "Unable to connect" network fallback), triggers global logout on non-/user 401s, and accepts any 2xx (200/204) for deletes. Thin resource modules: auth, articles, comments, profiles, tags.
  • src/auth/AuthContext.tsx — React context replacing UserService + interceptor 401 handling + the app initializer. Implements the 4-state machine (loading/authenticated/unauthenticated/unavailable) with token validation on startup, exponential-backoff retry, and the window.__conduit_debug__ test hook.
  • src/components/ & src/pages/ — every component/page ported (Header, Footer, ListErrors, ArticleMeta/Preview/List/Comment, Favorite/Follow buttons; Home, Auth, Article, Editor, Settings, Profile + nested Articles/Favorites). Routing via react-router-dom v6 with RequireAuth/RequireAnon guards.
  • src/utils/markdown (marked + DOMPurify sanitization, replacing DomSanitizer), image (default avatar), date (longDate), cx (ngClass helper).

Tooling: Vite dev server on :4200 (so Playwright's webServer works unchanged); theme CSS imported from the realworld submodule; media SVGs copied to /assets (unhashed) via vite-plugin-static-copy; public/_redirects for SPA fallback. Scripts (start/build/test/test:e2e/format) remain runner-agnostic (npm or bun).

Tests: Angular TestBed specs replaced with 55 Vitest tests for the API modules, utils, and the AuthProvider state machine.

Docs/CI: README, CLAUDE.md, and the deploy workflow's build path updated for React.

Notable parity decisions (uncovered via runtime testing)

  • Settings omits an empty password from the update payload — the live API rejects empty passwords with 422.
  • RequireAuth latches once access is granted, matching Angular's navigation-time canActivate semantics: a mid-session 401 (e.g. a form submit) keeps you on the page to see the error rather than reactively bouncing you to /login.
  • Article page fetches the article and its comments independently so a slow/failed comments request never blocks the article body.

Verification

  • tsc --noEmit: clean. vite build: clean. prettier --check: clean.
  • Vitest: 55/55 pass.
  • Playwright (against the live api.realworld.show backend): all suites passhealth, navigation, url-navigation, auth, articles, comments, social, settings, null-fields, error-handling, user-fetch-errors, and @security XSS. A few article-creation-heavy tests are occasionally flaky purely due to the shared demo backend's timing and pass on retry (the suite's existing retry config handles this).

Screenshots

Home (global feed) Article detail
Home Article

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

Devin Review

Status Commit
⚪ Not started

Run Devin Review

💡 Connect your GitHub account to enable automatic code reviews.

Open in Devin Review (Staging)

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.

2 participants