Building Tailor.me: Automating the Resume Tailoring Process with AI

Published on Wed Jan 14 2026
Screenshot of an AI resume builder interface: the left panel shows a “Full-stack Product Engineer” job details card with required skills, keywords, and responsibilities, plus an editable Education section. On the right, a live PDF preview displays a one-page resume with sections for Education, Experience, Technical Skills, and Projects, and a “Download PDF” button in the top-right.

The Problem: Resume Fatigue

If you've ever applied to multiple jobs, you know the drill. You spend hours carefully crafting each resume, tweaking bullet points, highlighting relevant experiences, and ensuring your skills match the job description. It's tedious, repetitive, and frankly, exhausting.

I found myself in this exact position—doing the same manual work over and over again. Copy the job description, analyze the requirements, scan through my experiences, pick the most relevant projects, rewrite bullets to emphasize the right skills, and format everything perfectly. Each application took 30-45 minutes of focused effort, and after the tenth one, I thought: there has to be a better way.

That's when I decided to build Tailor.me—an AI-powered resume builder that automates the entire resume tailoring process.

The Solution: AI-Powered Resume Automation

Tailor.me is a full-stack application that takes a job description and automatically generates a tailored resume by:

  1. Parsing the job description to extract requirements, skills, and company metadata
  2. Intelligently selecting the most relevant experiences and projects from your profile
  3. Rewriting bullet points using AI to emphasize the skills and achievements that matter most for that specific role
  4. Generating a professional PDF ready to submit

The entire process takes about 30-60 seconds and happens in the background while you can queue up to 10 jobs concurrently.

Technical Architecture

I built Tailor.me as a TypeScript monorepo using modern, production-ready technologies:

Frontend (Next.js 14)

  • Next.js App Router with TypeScript for type safety
  • Tailwind CSS and shadcn/ui for a clean, accessible UI
  • RTK Query for efficient API state management
  • Socket.IO client for real-time job progress updates

Backend API (NestJS)

  • NestJS for a well-structured, scalable API
  • Prisma ORM with PostgreSQL for robust data management
  • Socket.IO for WebSocket connections to push real-time updates
  • BullMQ integration to manage the job queue

Worker Service (NestJS)

  • Dedicated NestJS worker service for processing resume jobs
  • BullMQ with Redis for reliable job queue management
  • OpenAI API integration for intelligent content generation
  • Supports up to 10 concurrent jobs with configurable concurrency

Additional Services

  • LaTeX service for professional PDF generation
  • Docker Compose for easy local development
  • Turborepo for efficient monorepo builds

How It Works: The AI Workflow

When you submit a job description, here's what happens behind the scenes:

1. Job Description Parsing

The OpenAI API analyzes the job description to extract:

  • Required and preferred skills
  • Key responsibilities
  • Company name, position, and team information
  • Technical requirements and qualifications

2. Profile Retrieval

Your profile is stored with rich metadata:

  • Work experiences with atomic, tagged bullets
  • Skills organized by categories
  • Projects with associated technologies
  • Education and coursework

3. Content Selection

The AI intelligently selects the most relevant content by:

  • Matching your skills to job requirements
  • Prioritizing experiences that demonstrate required competencies
  • Selecting projects that showcase relevant technologies
  • Balancing depth and breadth of experience

4. Bullet Rewriting

Each selected bullet point is rewritten to:

  • Emphasize skills mentioned in the job description
  • Use language and terminology from the job posting
  • Highlight quantifiable achievements and impact
  • Maintain authenticity while optimizing relevance

5. Resume Assembly & PDF Generation

The final resume is:

  • Structured with your contact information
  • Organized by relevant experiences and projects
  • Formatted professionally using LaTeX
  • Generated as a downloadable PDF

6. Real-Time Progress Updates

Throughout the entire process, you get live updates via WebSockets showing:

  • Current processing stage (Parsing JD, Selecting Content, Rewriting, etc.)
  • Progress percentage
  • Queue position if jobs are backed up

Technical Highlights

Monorepo Architecture

Using Turborepo and pnpm workspaces, the project maintains:

  • Shared TypeScript types and DTOs across all apps
  • Efficient caching and parallel builds
  • Clear separation of concerns
  • Easy local development with pnpm dev

Real-Time Communication

Socket.IO integration provides:

  • Instant job status updates
  • Live progress bars
  • No polling required
  • Efficient WebSocket connection management

Scalable Job Queue

BullMQ with Redis enables:

  • Reliable job persistence
  • Configurable concurrency (default: 10 concurrent jobs)
  • Automatic retry on failures
  • Job prioritization capabilities

Type Safety Everywhere

  • End-to-end TypeScript from database to UI
  • Prisma generates type-safe database clients
  • Shared package ensures API/frontend contract consistency
  • Zod DTOs for runtime validation

The Database Design

The Prisma schema reflects the core data model:

User
├── Profile metadata (name, contact, links)
├── Experiences (with atomic bullets)
├── Projects (with bullets and skills)
├── Education (with coursework)
├── Skills (organized by categories)
└── Resume Jobs (with results)


Each Bullet can be:

  • Associated with an Experience or Project
  • Tagged with multiple skills
  • Reused across multiple resume jobs
  • Tracked for rewrite history

This granular structure enables the AI to make intelligent decisions about which content to include and how to optimize it.

Development Experience

The project is designed for easy local development:

# Install dependencies
pnpm install

# Start PostgreSQL and Redis
docker compose up -d

# Run database migrations
pnpm db:migrate

# Seed with demo data
pnpm db:seed

# Start all services in parallel
pnpm dev


Within seconds, you have:

  • Frontend running on localhost:3000
  • API server on localhost:3001
  • Worker processing jobs in the background
  • WebSocket server for real-time updates
  • Hot module reloading for all services

Challenges & Solutions

Challenge: Managing Concurrent AI Requests

Problem: OpenAI API has rate limits and can be slow for bulk operations.

Solution: Implemented BullMQ job queue with configurable concurrency. Jobs are processed in parallel (up to 10 at once) with automatic retry logic and exponential backoff.

Challenge: Real-Time Progress Without Polling

Problem: Traditional polling creates unnecessary server load and provides poor UX.

Solution: Integrated Socket.IO for bidirectional communication. The worker emits progress events that are relayed to the frontend via WebSocket, providing instant updates.

Challenge: Maintaining Context Across Services

Problem: Worker, API, and frontend need consistent data structures.

Solution: Created a shared package (packages/shared) with TypeScript types, DTOs, and enums. All services import from this single source of truth.

Challenge: Reliable Job Processing

Problem: Jobs can fail due to API errors, timeouts, or other issues.

Solution: BullMQ provides built-in retry mechanisms, job persistence in Redis, and detailed error tracking. Failed jobs are logged with error messages for debugging.

What I Learned

Building Tailor.me taught me several valuable lessons:

  1. AI as a Tool, Not Magic: GPT-4 is powerful, but it requires careful prompt engineering and validation. I spent significant time crafting prompts that consistently produce high-quality, relevant content.
  2. Real-Time UX Matters: WebSocket-based progress updates transformed the user experience from "waiting in the dark" to "watching progress happen." Users are much more patient when they can see what's happening.
  3. Monorepo Benefits: Having all services in one repo with shared types eliminated an entire class of bugs and made refactoring across services trivial.
  4. Queue Systems Are Essential: Offloading heavy AI processing to background workers with a proper queue system is non-negotiable for good UX and scalability.
  5. Type Safety = Confidence: End-to-end TypeScript with Prisma caught countless bugs at compile time and made refactoring fearless.

Future Enhancements

While Tailor.me already saves significant time, there's room for improvement:

Job Application Tracker

Build a comprehensive job tracker to manage the entire application process:

  • Track applications with statuses (Applied, Phone Screen, Interview, Offer, Rejected)
  • Set reminders for follow-ups
  • Store interview notes and feedback
  • Visualize the application pipeline
  • Integration with resume jobs (one-click apply with generated resume)

Multiple Resume Templates

  • Support various resume formats (modern, traditional, academic)
  • Allow users to choose templates per job
  • Custom color schemes and typography

Analytics Dashboard

  • Track which experiences get selected most often
  • Identify your most valuable skills based on AI selection frequency
  • Success metrics: application-to-interview conversion rates

Cover Letter Generation

  • AI-generated cover letters tailored to each job
  • Reference specific experiences and projects
  • Match tone to company culture

Try It Yourself

The project is structured for easy setup and experimentation:

  1. Clone the repository
  2. Add your OpenAI API key to .env
  3. Run docker compose up -d to start databases
  4. Run pnpm install && pnpm db:migrate && pnpm db:seed
  5. Start all services with pnpm dev
  6. Visit localhost:3000 and start generating resumes!

Conclusion

What started as frustration with repetitive resume tailoring turned into a full-stack application that combines AI, real-time communication, and modern TypeScript architecture. Tailor.me doesn't just save time—it produces better, more targeted resumes than I could manually write.

The job hunt is still challenging, but at least now I can focus on preparing for interviews instead of endlessly tweaking bullet points. And with the planned job tracker feature, the entire application lifecycle will be streamlined from start to finish.

If you've ever felt the pain of customizing dozens of resumes, I hope this project inspires you to automate your own repetitive workflows. The future is about working smarter, not harder.

Tech Stack Summary:

  • Frontend: Next.js 14, TypeScript, Tailwind CSS, shadcn/ui, RTK Query, Socket.IO
  • Backend: NestJS, Prisma, PostgreSQL, Socket.IO, BullMQ
  • Worker: NestJS, BullMQ, OpenAI API
  • Infrastructure: Docker, Redis, LaTeX service, Turborepo

Repository: https://github.com/defsanmith/talior.me

Have questions or suggestions? Feel free to reach out or contribute to the project!