Chrome Extension for AI-Powered Resume Tailoring
Manifest V3 Chrome extension with React, TypeScript, and Claude API for intelligent job application assistance
Overview
Developed a Chrome extension that detects job postings on LinkedIn, Indeed, and other job sites, then uses Claude API to intelligently reframe resume experience using the job posting's language. Never fabricates experience - only translates existing skills into target vocabulary.
The Problem
Job seekers submit the same generic resume to every application. ATS systems scan for keyword matches. The disconnect: you have the skills but describe them differently than the job posting. Manual tailoring takes 20-30 minutes per application.
Architecture Decisions
Why Manifest V3?
Required for Chrome Web Store as of 2024. Service workers for background processing. Better security model.
Why React in an extension?
Popup and options pages benefit from component architecture. State management for complex UI. Reuse of existing React knowledge.
Why user-provided API key?
No backend server needed. User controls their own usage/costs. Privacy: resume data never touches a third-party server.
Key Features
- Job Detection: Auto-detects job postings on LinkedIn, Indeed, Hiring Cafe
- Resume Reframing: Translates experience into job posting vocabulary
- Match Score: Calculates fit percentage based on skill overlap
- Cover Letter Generation: Creates tailored cover letters
- Application Tracker: Track status across applications
Challenges & Solutions
| Challenge | Solution |
|---|---|
| Manifest V3 service worker limits | Implemented message passing for long operations |
| Job site DOM variations | Built fallback selectors and regex patterns |
| API key security | Stored in chrome.storage.local (never synced) |
| Large resume + job posting context | Chunked processing with context summaries |
Results
- ✓Reduces tailoring time from 25 min to 2 min per application
- ✓85%+ match scores on targeted applications
- ✓Zero fabrication - verified through diff comparison
- ✓Tracks 50+ applications with status management
Code Sample - Resume Reframing
// Service Worker - Claude Integration
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.type === 'REFRAME_RESUME') {
reframeResume(request.resume, request.jobPosting)
.then(result => sendResponse({ success: true, result }))
.catch(error => sendResponse({ success: false, error: error.message }));
return true; // Keep channel open for async response
}
});
async function reframeResume(resume: string, jobPosting: JobPosting) {
const apiKey = await chrome.storage.local.get('claudeApiKey');
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey.claudeApiKey,
'anthropic-version': '2023-06-01'
},
body: JSON.stringify({
model: 'claude-sonnet-4-20250514',
max_tokens: 4096,
messages: [{
role: 'user',
content: buildReframePrompt(resume, jobPosting)
}]
})
});
const data = await response.json();
return parseReframedResume(data.content[0].text);
}What I'd Do Differently
- →Add support for more job sites (Glassdoor, ZipRecruiter)
- →Build comparison view (original vs reframed)
- →Implement batch processing for multiple job applications