Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nayalsaurav/resume-analyzer/llms.txt

Use this file to discover all available pages before exploring further.

Resume Check Karo is built as a full-stack Next.js 15 application using the App Router. All business logic runs as React Server Components or Next.js Server Actions — there is no separate backend API service. The client renders interactive UI pieces (file upload, score display, animated feedback) as isolated "use client" components, while data fetching, AI calls, and database writes stay on the server. This architecture keeps API keys and database credentials off the client entirely and collocates each feature’s UI, logic, and data access in a single codebase.

Technology Layers

Next.js 15 (App Router)

Full-stack React framework powering routing, server components, server actions, and API routes. The App Router’s nested layouts handle Clerk session protection across the (root) route group.

TypeScript 5

End-to-end type safety across client components, server actions, Prisma queries, and the Gemini AI response schema. Shared types in lib/google.ts prevent drift between the AI schema and UI rendering.

Google Gemini (@google/genai)

Drives all resume analysis. PDFs are encoded as base64 inline data and submitted alongside a structured prompt. The model is constrained to return valid JSON matching the resumeAnalysisSchema.

Clerk (@clerk/nextjs)

Handles user authentication, session management, and route protection. ClerkProvider wraps the app in providers.tsx; Clerk middleware guards every route inside app/(root)/.

PostgreSQL + Prisma ORM

Stores every resume submission and its AI analysis result. Prisma provides a type-safe query client generated from prisma/schema.prisma, and migrations are managed with prisma migrate dev.

ImageKit

Hosts uploaded PDF files and resume preview images on a global CDN. The @imagekit/next package provides a React upload component; raw uploads use the imagekit Node.js SDK in server actions.

Tailwind CSS v4

Utility-first CSS framework used across every component. Version 4 drops the tailwind.config.js file in favour of CSS-native configuration via @theme.

Radix UI + Lucide + Tabler Icons

Radix UI provides accessible, unstyled headless primitives (Label, Slot). Lucide React and Tabler Icons supply the icon sets used in the dashboard, cards, and feedback sections.

Framer Motion (motion)

Animates score bars, score circles, and card entrance transitions in the feedback display. The motion package (Framer Motion v12) is imported directly as "motion" in client components.

React Hook Form + Zod

Manages the resume submission form. react-hook-form controls field state and validation; Zod schemas (via @hookform/resolvers) enforce that all required fields are filled before the server action fires.

Sonner

Renders toast notifications for upload success, analysis errors, and other transient feedback without interrupting page flow.

next-themes

Provides system-aware dark/light mode switching. ThemeProvider is mounted in providers.tsx alongside ClerkProvider and ImageKitProvider.

Full Dependency Reference

LayerPackageVersion
Frameworknext15.4.10
Runtimereact19.1.0
AI@google/genai^1.13.0
Auth@clerk/nextjs^6.29.0
Database ORM@prisma/client^6.13.0
Storage (React)@imagekit/next^2.1.2
Storage (Node)imagekit^6.0.0
Stylingtailwindcss^4
Animationsmotion^12.23.12
Formsreact-hook-form^7.62.0
Validationzod^4.0.17
Form resolvers@hookform/resolvers^5.2.1
Headless UI@radix-ui/react-label^2.1.7
Headless UI@radix-ui/react-slot^1.2.3
Iconslucide-react^0.536.0
Icons@tabler/icons-react^3.34.1
Notificationssonner^2.0.7
Themingnext-themes^0.4.6
File uploadreact-dropzone^14.3.8
Class utilitiesclsx^2.1.1
Class utilitiestailwind-merge^3.3.1
Class utilitiesclass-variance-authority^0.7.1

Data Flow

Every resume analysis follows the same linear pipeline from form submission to stored result:
1

Client form submission

The user fills in company name, job title, job description, and drops a PDF onto the upload zone. React Hook Form validates all fields against the Zod schema before the form can be submitted.
2

Server Action validation

app/actions/analyze-resume.tsx (marked "use server") receives the FormData. It re-validates inputs server-side, reads the Clerk session to get the authenticated userId, and checks that a PDF file is present.
3

ImageKit upload

The PDF (and a generated preview image) are uploaded to ImageKit using the Node.js SDK. The action receives back a pdfUrl and imageUrl pointing to CDN-hosted assets.
4

Gemini AI analysis

getAiResponse() in lib/google.ts encodes the PDF as base64 inline data, constructs a structured prompt (company, title, JD injected via prepareInstructions()), and calls ai.models.generateContent() with responseSchema enforced. The model returns a typed Feedback JSON object.
5

Prisma write

The server action calls prisma.resume.create() with all field values including the full Feedback object stored in the nullable analysis JSON column.
6

Client response

The server action returns the created Resume record. The client redirects to the analysis detail page where FeedbackDisplay and ScoreCircle render the results.

Rendering Strategy

Next.js App Router defaults every route segment to a React Server Component. Resume Check Karo follows that default and opts into client rendering only where interactivity demands it.

Server Components (default)

  • Layout components (app/layout.tsx, app/(root)/layout.tsx)
  • Page components that fetch data from Prisma
  • Static sections of the dashboard and landing page

Client Components ("use client")

  • UploadForm — uses react-dropzone, react-hook-form, and calls the server action via useTransition
  • FeedbackDisplay — renders animated score bars with Framer Motion
  • ScoreCircle — SVG-based animated overall score ring
  • ThemeToggle — reads and writes theme state via next-themes
Server Actions cross the server/client boundary cleanly: client components import and call "use server" functions directly. Next.js serialises the call over an internal POST request, keeping API keys on the server.

Providers

app/providers.tsx composes three context providers that wrap the entire app. ClerkProvider is outermost, followed by ThemeProvider, with ImageKitProvider innermost:
// app/providers.tsx
"use client";

import { ClerkProvider } from "@clerk/nextjs";
import { ThemeProvider } from "next-themes";
import { ImageKitProvider } from "@imagekit/next";

const Provider = ({ children }: { children: React.ReactNode }) => {
  return (
    <ClerkProvider>
      <ThemeProvider
        attribute="class"
        defaultTheme="light"
        enableSystem
        disableTransitionOnChange
      >
        <ImageKitProvider
          urlEndpoint={process.env.NEXT_PUBLIC_IMAGEKIT_URL_ENDPOINT || ""}
        >
          {children}
        </ImageKitProvider>
      </ThemeProvider>
    </ClerkProvider>
  );
};

export default Provider;
ClerkProvider must be the outermost wrapper so that every nested server and client component can access the session. ImageKitProvider sits inside ThemeProvider as the innermost provider, scoping ImageKit upload tokens to authenticated users.

Build docs developers (and LLMs) love