Skip to content

refactor: migrate frontend from next.js to vite + tanStack router#148

Merged
webdevcody merged 60 commits intomainfrom
refactor/frontend
Dec 19, 2025
Merged

refactor: migrate frontend from next.js to vite + tanStack router#148
webdevcody merged 60 commits intomainfrom
refactor/frontend

Conversation

@Shironex
Copy link
Collaborator

@Shironex Shironex commented Dec 17, 2025

PR Description: Frontend Migration (Next.js → Vite)

Summary

This PR completes the migration of the frontend application from Next.js to Vite with TanStack Router. The migration eliminates unnecessary framework overhead since we were using less than 5% of Next.js capabilities (no SSR, no API routes, no image optimization).

Key Changes

  • Bundler: Next.js → Vite
  • Routing: Next.js App Router → TanStack Router (file-based)
  • Directory: apps/appapps/ui
  • Entry Point: page.tsxrenderer.tsx + App.tsx

What's Changed

Build Infrastructure

  • Added vite.config.mts with Electron, React, and TailwindCSS plugins
  • Converted Electron main.ts and preload.ts to TypeScript
  • Created index.html as Vite entry point
  • Configured TanStack Router with file-based routing
  • Added memory history for Electron (no URL bar)
  • Dynamic Vite port configuration via TEST_PORT env var

Code Migration

  • Created route files in src/routes/ for all views
  • Replaced all setCurrentView() Zustand calls with TanStack Router navigate()
  • Removed all "use client" directives (not needed in Vite)
  • Updated environment variables from NEXT_PUBLIC_* to VITE_*
  • Fixed ES module imports (replaced require() with import)
  • Removed PostCSS config (using @tailwindcss/vite plugin instead)

CI/CD Updates

  • Composite Action: Created .github/actions/setup-project/ to DRY up workflow files
    • Reduced ~90 lines of duplicated YAML across 3 workflows
    • Configurable inputs: node-version, check-lockfile, rebuild-node-pty-path
  • Updated e2e-tests.yml for apps/ui workspace and VITE_* env vars
  • Updated pr-check.yml to use faster build:electron:dir for CI
  • Updated test.yml with lockfile check
  • Added build:electron:dir script for faster CI builds (unpacked only)
  • Fixed SSH URL in package-lock.json (converted to HTTPS)

AutoMode Improvements

  • Context Files Loading: Agent now loads .automaker/context/ files (CLAUDE.md, etc.) as system prompt
    • Added getContextDir() utility in automaker-paths.ts
    • Added loadContextFiles() method with cross-platform path handling
    • Context passed as systemPrompt for higher priority (not user prompt)
  • Infinite Loop Fix: Fixed executeFeatureresumeFeatureexecuteFeatureWithContext loop
    • Skip context check when continuationPrompt is provided

Component Refactoring

Bug Fixes

  • Added null checks for mainWindow in Electron IPC handlers (CodeRabbit suggestion)

Routes Created

Route View
/ Welcome (home)
/board Kanban Board
/agent Agent Chat
/settings Settings
/setup Setup Wizard
/terminal Terminal
/spec Spec Editor
/context Context Files
/profiles AI Profiles
/interview Interview Mode
/wiki Wiki
/analysis Analysis
/agent-tools Agent Tools
/running-agents Running Agents

Issues Closed

Expected Benefits

Metric Before (Next.js) After (Vite)
Dev server startup ~8-15s ~1-3s
HMR speed ~500ms-2s ~50-100ms
Production build ~45-90s ~15-30s
Bundle overhead Next.js runtime None

Migration Status

See docs/migration-plan-nextjs-to-vite.md for full details.

  • Phase 1: Foundation (Vite config, Electron TypeScript, TanStack Router)
  • Phase 2: Core Migration (routes, stores, API client)
  • Phase 3: Component Refactoring (spec-view folder pattern)
  • Phase 4: Package Extraction (shared libs - future PR)
  • Phase 5: Polish & Testing (future PR)

Files Changed Summary

New Files

  • .github/actions/setup-project/action.yml - Reusable CI setup composite action
  • apps/ui/src/routes/*.tsx - TanStack Router route files
  • apps/ui/vite.config.mts - Vite configuration
  • apps/ui/index.html - Vite entry point

Modified Files

  • apps/server/src/lib/automaker-paths.ts - Added getContextDir()
  • apps/server/src/services/auto-mode-service.ts - Context loading + infinite loop fix
  • apps/ui/src/main.ts - Electron main process (TypeScript + null checks)
  • apps/ui/src/preload.ts - Electron preload (TypeScript)
  • .github/workflows/*.yml - CI workflow refactoring

Testing

  • Dev server starts correctly (npm run dev --workspace=apps/ui)
  • All routes navigate correctly
  • Spec creation works with feature count selector
  • Sidebar setup dialog works with analyzeProject checkbox
  • E2E tests pass
  • TypeScript compilation passes
  • Context files loaded by agent (verified via debug logs)
  • No SSH URLs in package-lock.json

Summary by CodeRabbit

  • Refactor

    • Migrated frontend from Next.js to Vite-based architecture.
    • Transitioned app navigation from state-based to route-based system.
  • New Features

    • Added responsive Kanban board column layout.
    • Introduced structured spec generation output.
  • Improvements

    • Increased AI turn limits for suggestion generation and analysis workflows.
    • Enhanced Git branch handling with improved cross-platform compatibility.
  • Chores

    • Updated CI workflows and dependency versions.
    • Improved configuration management across development and production environments.

✏️ Tip: You can customize this high-level summary in your review settings.

Shironex and others added 7 commits December 17, 2025 18:32
- Resolved conflicts from apps/app to apps/ui migration
- Moved worktree-panel component to apps/ui
- Moved dependency-resolver.ts to apps/ui
- Removed worktree-selector.tsx (replaced by worktree-panel)
- Merged theme updates, file browser improvements, and Gemini fixes
- Merged server dependency resolver and auto-mode-service updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ation

- Finalized core migration to Vite, ensuring feature parity and functionality.
- Updated migration plan to reflect completed tasks and deferred items.
- Renamed `apps/app` to `apps/ui` and adjusted related configurations.
- Verified Zustand stores and HTTP API client functionality remain unchanged.
- Added additional tasks completed during migration, including environment variable updates and memory history configuration for Electron.

This commit marks the transition to the new build infrastructure, setting the stage for further component refactoring.
- Change workspace from apps/app to apps/ui
- Update env vars from NEXT_PUBLIC_* to VITE_*
- Update artifact paths for playwright reports

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added new build commands for Electron to support directory output for Windows, macOS, and Linux.
- This update improves the flexibility of the build process for different deployment scenarios.
- Introduced new build commands for Electron in package.json to support directory output.
- Updated CI workflow to utilize the new directory-only build command for faster execution.
@Shironex Shironex self-assigned this Dec 17, 2025
@Shironex Shironex added Testers-Requested Request for others to test an enhancement or bug fix/etc. Refactor A complete logic rewrite is requested or being performed for an issue. Do Not Merge Use this label if something should not be merged. labels Dec 17, 2025
Remove git+ssh:// URLs that fail CI lint check

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Shironex, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request represents a major architectural shift for the frontend, moving away from Next.js to a more lightweight and performant Vite-based setup. The core motivation is to optimize developer experience and application performance by shedding unused framework features. This migration also modernizes the Electron integration with TypeScript and introduces a robust file-based routing solution, setting the stage for future component refactoring and modularization.

Highlights

  • Frontend Migration: The frontend application has been migrated from Next.js to Vite, leveraging TanStack Router for file-based routing. This change aims to significantly reduce development server startup times, improve Hot Module Replacement (HMR) speed, and decrease production build times.
  • Build System & Performance: The new build system, based on Vite, eliminates the overhead of Next.js, which was largely unused (no SSR, API routes, or image optimization). This results in faster development cycles and a leaner production bundle.
  • Electron Integration: The Electron main and preload processes have been converted to TypeScript, enhancing type safety and maintainability. The Electron build process has also been updated to integrate seamlessly with Vite.
  • Routing & Code Structure: TanStack Router has been implemented for declarative, file-based routing, replacing Next.js's App Router. All views have been adapted to this new routing system, and 'use client' directives have been removed where no longer necessary.
  • Environment Variables & CI/CD: Environment variables have been updated from NEXT_PUBLIC_* to VITE_* to align with Vite's conventions. CI/CD pipelines have been adjusted to support the new apps/ui workspace and faster Electron builds.
Ignored Files
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/e2e-tests.yml
    • .github/workflows/pr-check.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully migrates the frontend from Next.js to Vite and TanStack Router, which is a significant improvement for development speed and bundle size. The changes are extensive and well-executed. I've identified a few issues: the CLAUDE.md documentation is outdated and needs to be updated to reflect the new architecture. Additionally, there are a couple of minor bugs in the theme-switching logic, both in the new root layout component and in the anti-flicker script in index.html, which could cause visual glitches. I've provided suggestions to fix these. Overall, this is a great step forward for the project's frontend infrastructure.

Shironex and others added 4 commits December 17, 2025 21:14
- Use /api/setup/verify-claude-auth instead of removed Next.js route
- Add placeholder for Gemini test (needs backend endpoint)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- index.html: Apply actual theme class instead of only 'dark'
- __root.tsx: Use themeOptions to dynamically generate theme classes
  - Fixes missing themes: cream, sunset, gray

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Deleted the CLAUDE.md file which provided guidance for the Claude Code project.
- This file contained project overview, architecture details, development commands, code conventions, and environment variables.
The vite-plugin-electron was trying to spawn Electron during the Vite
dev server startup, which fails in CI because there's no X11 display.

- Use Vite's function config to check command type (serve vs build)
- Only skip electron plugin during dev server (command=serve) in CI
- Always include electron plugin during build for dist-electron/main.js
- Add VITE_SKIP_ELECTRON env var support for explicit control
- Update playwright.config.ts to pass VITE_SKIP_ELECTRON in CI

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shironex and others added 5 commits December 17, 2025 22:08
The index route (/) now shows WelcomeView instead of auto-redirecting
to board view. Updated test utilities to navigate directly to the
correct routes:

- navigateToBoard -> /board
- navigateToContext -> /context
- navigateToSpec -> /spec
- navigateToAgent -> /agent
- navigateToSettings -> /settings
- waitForBoardView -> navigates to /board first

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The zustand store may not have hydrated from localStorage by the time
the board view first renders, causing board-view-no-project to appear
briefly. Use waitForFunction to poll until board-view appears.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The router was using memory history with initial entry "/" which caused
all routes to render the index component regardless of the browser URL.

Changes:
- Use browser history when not in Electron (for e2e tests and dev)
- Use memory history only in Electron environment
- Update test utilities to use persist version 2 to match app store

This fixes e2e tests that navigate directly to /board, /context, /spec

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Updated the branch listing command to remove quotes around branch names, ensuring compatibility across platforms.
- Enhanced worktree path comparisons in tests to normalize path separators, improving consistency between server and client environments.
- Adjusted workspace root resolution to reflect the correct directory structure for the UI.

This addresses potential discrepancies in branch names and worktree paths, particularly on Windows systems.
The git branch --format option needs proper quoting to work
cross-platform. Single quotes are preserved literally on Windows,
while unquoted format strings may be misinterpreted on Linux.
Using double quotes works correctly on both platforms.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@Shironex Shironex changed the title Migrate Frontend from Next.js to Vite + TanStack Router refactor: Migrate Frontend from Next.js to Vite + TanStack Router Dec 17, 2025
@Shironex Shironex changed the title refactor: Migrate Frontend from Next.js to Vite + TanStack Router refactor: migrate frontend from next.js to vite + tanStack router Dec 17, 2025
Shironex and others added 3 commits December 18, 2025 00:14
…ctor

Closes #151

- Refactor spec-view.tsx from 1,230 lines to ~170 lines following folder-pattern.md
- Create unified CreateSpecDialog with all features from both dialogs:
  - featureCount selector (20/50/100) - was missing in spec-view
  - analyzeProject checkbox - was missing in sidebar
- Extract components: spec-header, spec-editor, spec-empty-state
- Extract hooks: use-spec-loading, use-spec-save, use-spec-generation
- Extract dialogs: create-spec-dialog, regenerate-spec-dialog
- Update sidebar to use new CreateSpecDialog with analyzeProject state
- Delete deprecated project-setup-dialog.tsx

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added useNavigate hook to facilitate programmatic navigation.
- Implemented a useEffect to redirect to the board view if a project was previously open and the root path is accessed.
- Updated theme class application to ensure proper filtering of theme options.

This improves user experience by ensuring the correct view is displayed upon navigation and enhances theme management.
…sed max turns

- Updated MAX_TURNS to allow for more iterations in suggestion generation: quick (5 to 50), standard (20 to 100), and extended (50 to 250).
- Introduced a JSON schema for structured output in suggestions, improving the format and consistency of generated suggestions.
- Modified the generateSuggestions function to utilize structured output when available, with a fallback to text parsing for compatibility.

This enhances the suggestion generation process, allowing for more thorough exploration and better output formatting.
…th bounds and improve margin calculations

- Changed minimum column width from 240px to 280px to better align with design requirements.
- Enhanced margin calculations to account for the actual container width and sidebar positioning, ensuring more accurate layout testing.
- Deleted the CoursePromoBadge component from the sidebar and its associated logic.
- Removed references to the hideMarketingContent setting from the settings view and appearance section.
- Cleaned up related tests for marketing content visibility as they are no longer applicable.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/ui/src/components/layout/sidebar.tsx (1)

1814-1814: Typo in Tailwind class: mt1 should be mt-1.

The class mt1 is invalid in Tailwind CSS. This will cause the margin-top not to be applied when the sidebar is collapsed.

🔎 Proposed fix
-        <nav className={cn("flex-1 overflow-y-auto px-3 pb-2", sidebarOpen ? "mt-5" : "mt1")}>
+        <nav className={cn("flex-1 overflow-y-auto px-3 pb-2", sidebarOpen ? "mt-5" : "mt-1")}>
🧹 Nitpick comments (1)
apps/ui/src/components/layout/sidebar.tsx (1)

1209-1213: Consider using startsWith for nested route matching.

The current implementation uses exact pathname matching, which won't highlight parent routes when viewing child routes (e.g., /settings/general won't highlight the Settings nav item).

If all routes are leaf-level this is fine, but if nested routes exist or are planned, consider:

🔎 Suggested enhancement for nested route support
 const isActiveRoute = (id: string) => {
   // Map view IDs to route paths
   const routePath = id === "welcome" ? "/" : `/${id}`;
-  return location.pathname === routePath;
+  return routePath === "/"
+    ? location.pathname === "/"
+    : location.pathname.startsWith(routePath);
 };
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9dba8c and a26ef43.

📒 Files selected for processing (3)
  • apps/ui/src/components/layout/sidebar.tsx (17 hunks)
  • apps/ui/src/components/views/settings-view.tsx (0 hunks)
  • apps/ui/src/components/views/settings-view/appearance/appearance-section.tsx (0 hunks)
💤 Files with no reviewable changes (2)
  • apps/ui/src/components/views/settings-view.tsx
  • apps/ui/src/components/views/settings-view/appearance/appearance-section.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
apps/ui/src/components/layout/sidebar.tsx (2)
apps/server/src/services/auto-mode-service.ts (1)
  • analyzeProject (1158-1239)
apps/ui/src/components/views/spec-view/dialogs/create-spec-dialog.tsx (1)
  • CreateSpecDialog (17-202)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (11)
apps/ui/src/components/layout/sidebar.tsx (11)

1-2: LGTM!

The TanStack Router hooks are correctly imported and will be used throughout the component for route-based navigation.


83-84: LGTM!

Imports correctly reference the reorganized spec-view component structure and use proper type-only import syntax.


222-224: LGTM!

Router hooks are correctly initialized at the component's top level, following React's rules of hooks.


251-257: LGTM!

Environment variable access correctly migrated to Vite's import.meta.env pattern with proper VITE_ prefix.


290-291: LGTM!

The analyzeProject state is correctly initialized with a sensible default value of true, enabling project analysis by default during spec creation.


493-529: LGTM!

The analyzeProject flag is correctly passed to the spec regeneration API and properly included in the useCallback dependency array.


1175-1204: LGTM!

Keyboard shortcuts correctly use navigate() for route-based navigation. The dependency array properly includes navigate.


1291-1292: LGTM!

Logo click correctly navigates to the root route using TanStack Router's navigate function.


1849-1849: LGTM!

Nav item click handlers correctly use route-based navigation consistent with the rest of the component.


1948-1948: LGTM!

Wiki, Running Agents, and Settings buttons consistently use route-based navigation with correct route paths.

Also applies to: 2008-2008, 2103-2103


2264-2281: LGTM!

The CreateSpecDialog is correctly integrated with all required props. The customizable title and description props allow this unified dialog to serve the initial project setup flow with appropriate messaging.

@webdevcody webdevcody merged commit d104a24 into main Dec 19, 2025
4 checks passed
@webdevcody webdevcody deleted the refactor/frontend branch December 19, 2025 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Do Not Merge Use this label if something should not be merged. Refactor A complete logic rewrite is requested or being performed for an issue. Testers-Requested Request for others to test an enhancement or bug fix/etc. Tests Adding / Updating / Removing tests across the project.

Projects

None yet

5 participants