# Frontend evaluation and migration workbook Use this editable workbook for a new frontend decision or a change to an existing application. Record evidence against the same required behavior before choosing a framework or migration target. Replace bracketed fields. The customer-directory trial and CRA manifest below are fictional examples, not completed framework implementations or a migrated customer project. Project and decision owner: [name / role] Existing revision and review date: [commit / date] ## 1. State the decision - Outcome to improve: [user task and observed problem] - Current application and components to retain: [frontend / backend / authentication / integrations] - Required change and exclusions: [bounded scope] - Who implements, reviews and maintains it: [roles and relevant experience] - Hosting constraints: [static hosting / request-time runtime / existing API / deployment owner] - Time or compatibility constraints: [supported browsers / dependencies / release window] - Evidence that would justify retaining the current stack: [conditions] A framework change needs a reason that survives comparison with a smaller improvement. Keep replacing a build tool, introducing a router and moving data access to a server runtime as separate decisions where possible. ## 2. Map responsibilities before comparing names | Responsibility | Current owner / implementation | Proposed Angular, React or Vue stack | Evidence needed | | --- | --- | --- | --- | | Components and shared UI | [record] | [framework/component conventions] | [one representative change reviewed] | | Routing and data loading | [record] | [integrated framework / chosen router / retained server routes] | [deep link, refresh and failure behavior] | | Forms and validation | [record] | [form APIs / chosen libraries / server validation] | [draft, error and saved-state behavior] | | State ownership | [record] | [URL, component, shared state and server records] | [no unintended coupling or stale result] | | Rendering and interactivity | [record] | [client rendering / build-time output / request-time HTML] | [initial content and usable interaction on a target device] | | Build, deployment and updates | [record] | [tools, runtime and release process] | [repeatable build / hosting configuration / update owner] | Angular includes an integrated set of application capabilities. A React selection also needs a decision about framework or other application tooling. Vue supports both incremental enhancement and fuller application setups. Those descriptions identify responsibilities; they do not determine which option performs best for your project. ## 3. Propose the same small trial for each serious candidate **Scenario:** a customer directory with a query filter and an edit form, using the same synthetic data and API contract in each candidate. Do not compare a minimal example in one framework with a feature-heavy application in another. | Required behavior | Proposed check | Observed result / artifact | | --- | --- | --- | | The query survives a copied URL and refresh | Open a direct customer-directory URL with a query; refresh; navigate back and forward | [record] | | The list explains its state | Inspect loading, successful, empty and failed requests | [record] | | Older responses do not overwrite a newer search | Arrange different response timings for two queries and inspect the final list | [record] | | Editing does not silently change the saved record | Change a draft, cancel, reopen and compare with the server record | [record] | | Validation is understandable | Trigger client feedback and a server rejection; retain useful input and identify the issue | [record] | | Access follows the application's authority | Attempt a request for a record outside the signed-in user's scope; inspect the server response | [record] | | The task is usable with a keyboard | Navigate and operate the form, error feedback and result controls | [record] | | Another maintainer can change the slice | Ask a reviewer to locate the relevant state, request and rendering decisions | [record] | These are proposed checks. No Angular/React/Vue implementation, browser session, accessibility evaluation or performance comparison was executed for this workbook. A frontend route guard or hidden control does not replace a server-side access decision. ## 4. Assign state explicitly | State | Proposed owner in the trial | Changes and acceptance rule | | --- | --- | --- | | Search query | URL plus its defined UI representation | Restored on navigation; normalization and empty-query behavior agreed | | Fetched customer records | Server is authoritative; client holds a defined fetched representation | Responses are associated with the query that requested them | | Unsaved edit | Form draft separate from the last accepted server record | Cancel discards only the draft; validation errors do not imply a save | | Request progress and error | The operation or screen responsible for the request | Visible state changes follow the actual outcome | | Shared selection | Nearest agreed shared owner | Consumers receive a consistent identity without independently overwriting it | Record how the selected framework implements those ownership rules: [props/events, state updates, reactive references, derived values and chosen data library]. Syntax such as a two-way form binding does not decide who owns persisted data. A change in rendering approach does not itself fix an ambiguous state model. ## 5. Inventory an existing CRA application Run this read-only command in the relevant package directory: ```sh npm pkg get scripts dependencies.react-scripts devDependencies.react-scripts dependencies.next devDependencies.next dependencies.vite devDependencies.vite ``` The command requests values declared in that package's `package.json`. It does not execute the listed scripts. The exact fictional manifest used for this inspection was: ```json { "name": "fictional-cra-admin", "version": "0.1.0", "private": true, "description": "Fictional manifest for a read-only migration-planning example.", "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test" }, "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1" } } ``` This fixture illustrates manifest inspection only. It is not a dependency or installation recommendation; do not install these packages to use this workbook. The recorded output was: ```json { "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test" }, "dependencies.react-scripts": "5.0.1" } ``` This exact command was executed with Node v24.19.0 and npm 11.9.0, using npm's offline setting and empty scratch configuration files. It exited successfully, left the manifest hash and fixture directory entries unchanged, and created no lockfile or `node_modules`. These are the execution versions for a manifest inspection, not a supported-runtime recommendation for CRA 5.0.1; CRA itself was not installed or run. Requested fields absent from the manifest are omitted in this output. That does not prove a package is absent from another workspace, a lockfile or the installed dependency tree. Inspect the actual package scope and dependency resolution separately. A declared version range is not a measured installed version. Use the manifest as a starting point: | Inventory area | Record before changing tools | Verification after the change | | --- | --- | --- | | Dependencies and lockfile | Package manager, resolved versions, custom build overrides and compatibility constraints | Repeatable installation and build under the chosen supported runtime | | Scripts and tests | Which commands actually compile, test, lint and produce deployable output | Equivalent checks run; no missing test suite hidden by a successful build | | Routes and authentication | Router, nested URLs, base path, refresh and login callback behavior | Direct links, history and authorized/unauthorized paths behave as agreed | | Environment configuration | Names, build/runtime timing and public/private classification; omit secret values | Required public configuration arrives correctly and private values stay server-side | | Assets and styles | Public directory, imported images/SVGs/fonts, CSS handling and path assumptions | Requests return the intended files on the real deployment path | | API requests and proxies | Existing backend, development proxy, credentials and error behavior | Deployed requests reach the intended service; development proxy assumptions are removed or implemented elsewhere | | Browser-only dependencies | Code relying on window, document, storage or browser lifecycle | It runs only where those APIs exist; no server/build evaluation failure | | Service worker and caching | Registration, cache names, update behavior and retirement plan | Users receive the intended release; stale assets do not keep the old application active | | Hosting and recovery | Build output, subpath, fallback/404 rules and rollback limits | Production-like deployment, direct refresh, missing routes and recovery are checked | ## 6. Select the target for an existing application | Route | Reason to investigate it | Evidence before commitment | | --- | --- | --- | | Retain CRA temporarily while preparing a change | Avoid combining an urgent business change with an unplanned toolchain migration | Current dependency/runtime assessment, known constraints, owner and a dated review point | | Replace the build tooling with Vite | Keep an existing client application and backend while changing its development/build setup | Routing, environment, assets, tests and deployment parity; Vite alone does not supply the full application architecture | | Adopt Next.js incrementally | Use framework routing or rendering/server capabilities that solve an identified problem | Initial compatibility slice, deployment choice, browser-only dependency treatment and evidence for each later framework feature | The React team deprecated CRA for new applications on 14 February 2025 and described existing projects as continuing in maintenance mode. That is neither a new-project recommendation nor a guarantee that your current dependency set remains safe or supported. Record a maintenance decision explicitly instead of assuming a running app needs either no attention or an immediate full rewrite. ## 7. Check public configuration and rendering boundaries - Browser-public prefixes differ: CRA commonly uses `REACT_APP_`, Vite exposes `VITE_` variables by default, and Next.js uses `NEXT_PUBLIC_` for browser-inlined values. These are public configuration channels, not secret storage. Verify the selected versions and configuration before translating names. - Changing an environment-variable prefix does not establish equivalent build-time or runtime behavior. Record when each value is read and how deployments receive changes. - A Next.js Client Component can still be prerendered. A `use client` directive alone is not a guarantee that code touching a browser global will never run outside the browser. - With Next.js static export, Server Components can execute at build time, but dynamic server features do not run in the deployed static files. Do not assume server rewrites, request-time cookie handling or Server Actions work in that mode. - A static host may provide its own routing/fallback rules. Identify which system serves the API and which handles direct navigation to a nested client route. - Keep personalized customer records out of public generated assets. Server-rendered HTML, hydration and authenticated data access are separate design concerns. ## 8. Record the decision and its limits | Candidate / migration slice | Required checks completed | Evidence and unresolved issues | Maintenance/deployment owner | Decision and reason | | --- | --- | --- | --- | --- | | [candidate] | [specific observations] | [artifacts / gaps] | [owner] | [proceed / revise / defer] | | [candidate] | [specific observations] | [artifacts / gaps] | [owner] | [proceed / revise / defer] | If measuring response or interaction performance, record the build, data, route, device, network conditions, repetitions and measurement definition. Compare like-for-like behavior and report uncertainty. No benchmark or framework ranking is supplied here. Useful guides and official references: - https://nomadicsoft.io/blog/angular-vs-react-vs-vue-choosing-the-best-front-end-framework-in-2024 - https://nomadicsoft.io/blog/vue-and-react-ultimate-comparison-of-javascript-frameworks - https://nomadicsoft.io/blog/next-js-vs-react-app-exploring-the-differences-next-js-and-create-react-app - https://react.dev/learn/creating-a-react-app - https://react.dev/blog/2025/02/14/sunsetting-create-react-app - https://vuejs.org/guide/introduction.html - https://angular.dev/overview - https://nextjs.org/docs/app/guides/migrating/from-create-react-app - https://nextjs.org/docs/app/guides/static-exports - https://vite.dev/guide/env-and-mode - https://docs.npmjs.com/cli/v11/commands/npm-pkg