Skip to content
AcoranGonzalezMorayPublic

About

DownCV is a modern, interactive, open-source web platform for creating, editing, analyzing, and exporting resumes (CVs) that are fully optimized for Applicant Tracking Systems (ATS) using Markdown syntax.

Topics

Resources

Contributing

Stars

15 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

12 Commits

Folders and files

Repository files navigation

DownCV Logo

DownCV

The Local-First, Privacy-Focused Markdown CV Builder & ATS Optimizer

License MIT React 18 Vite 6 Tailwind CSS ESLint Vitest 100% Local

Live Demo

DownCV application screenshot

πŸ“Œ Overview

DownCV is a high-performance, open-source web application designed to help job seekers create, format, and optimize professional resumes using Markdown.

Unlike web resume builders that process sensitive personal data on third-party servers, DownCV runs 100% client-side in your browser. It includes an isolated Applicant Tracking System (ATS) evaluation engine that generates real vector PDFs, reads back the text layer using pdf.js (exactly as real ATS parsers do), scores the resume across 12 critical dimensions, and provides one-click automatic Markdown fixes.

✨ Key Features

⚑ Bi-directional Markdown Editor & Live Preview

Edit raw Markdown or select text on the A4 page preview to format elements directly without breaking document syntax.

Bi-directional Markdown Editor Demo

πŸ›‘οΈ Integrated ATS Simulator & Scorer

Scores your generated PDF against realistic ATS rules (text layer integrity, keyword density, action verbs, contact information, bullet quality, etc.). Also analyses a PDF you already have, and exports the report. The score is the sum of the rules that pass, out of 100. Both lexicons are measured together, so a bilingual CV is never punished for the language of its headings or of its interface.

Rule Points What it fails on
text 10 The PDF has almost no selectable text (a scan or an image)
pages 8 More than two pages
length 3 Fewer than 200 or more than 900 words
contact 9 Fewer than two of email, phone and profile link
sections 9 Fewer than three standard sections found as headings
headings 4 A source heading that never reaches the sheet as a heading (a title too long, wrapped into loose lines)
residue 6 Markdown or HTML syntax visible in the text layer
emoji 3 An emoji or an image/table placeholder a parser cannot read
verbs 10 Fewer than four action verbs
metrics 8 Fewer than two numbers behind the achievements
phrasing 5 Fillers such as "responsible for" or "hard-working", with the verb that says it better
duplicates 3 The same bullet copied into two jobs
keywords 5 Fewer than four relevant terms, including the ones the detected role expects
bullets 4 More than 30% of the experience bullets with no verb and no number
language 2 Headings in one language and bullets in another
dates 4 A date in the future, two date styles mixed, or two jobs claiming the same months
filename 2 A file name without your name, with spaces, or marked "final" / "v2"
density 3 A single page over 750 words (the densest page, not the average)
stuffing 2 A term repeated four times in one line, or eating 6% of the document

The panel also groups them into five dimensions (structure, contact, verbs, metrics, keywords), lists what is missing sorted by points lost, and can download the whole report as HTML.

ATS Simulator & Scorer Demo

βœ… Contact Review & Verification

Scans your Markdown for every email, phone and link and makes you approve each one explicitly β€” flagging missing domain extensions, numbers without a country code, links written without https://, and URLs hidden behind link text that the ATS parser never reads. Export stays blocked until every item is verified or dismissed.

Contact Review and Verify Demo

πŸ—‚οΈ CV Versions per Job Offer

Keep one tailored CV per position instead of overwriting a single document. Name each version after the offer (Acme Β· Frontend Engineer), then open, rename, duplicate or delete them independently β€” each one shows the keywords it adds or removes versus the CV on screen, and can be linked to a real .md file on disk.

CV Versions per Job Offer Demo

πŸ€– ATS Rewriting with Local Ollama

Select any paragraph or bullet in the preview and let your own Ollama model rewrite it for ATS parsing β€” same meaning, stronger action verbs, quantified impact. Point the endpoint to http://localhost:11434/v1/chat/completions, pick a model and test the connection: no data ever leaves your machine.

ATS Rewriting with Local Ollama Demo

πŸ“„ Cover Letter Generator

Automatically drafts a tailored, professional cover letter derived from your resume's key achievements and contact information.

Cover Letter Generator Demo

πŸ“€ Multi-Format Export

Export to native vector PDF (via jsPDF), Microsoft Word (.docx via OOXML), or Rich Text Format (.rtf).

Multi-Format Export Demo

πŸ“₯ Universal Resume Importer

Import existing resumes from .pdf, .docx, .txt, .md, or raw text into clean, structured Markdown.

Universal Resume Importer Demo


πŸ› οΈ Tech Stack

Layer Technology Purpose
Frontend Framework React 18 & Vite 6 Fast SPA rendering & modern build pipeline
Styling & UI Tailwind CSS 4 + Lucide Icons Responsive layout, dark mode, CSS custom properties
Markdown Processing Marked.js (Custom Renderer) AST block tagging & bi-directional source mapping
PDF Generation jsPDF Native vector text streams (WinAnsi fallback, standard A4 layout)
ATS Text Extraction PDF.js (pdfjs-dist) Worker-based text layer parsing mimicking Workday/Taleo
Word / RTF Export docx (OOXML) Native .docx block generation and .rtf document creation
Testing Suite Vitest 5 + React Testing Library Unit & integration tests for parser, builders, and UI
Deployment / Container Docker + Nginx Alpine Lightweight containerized production distribution

πŸ“ Architecture & ATS Pipeline

flowchart TD
    subgraph Editor ["Markdown Workspace"]
        MD[Markdown Source] --> MP[marked Parser + Offset Mapping]
        MP --> PREVIEW[A4 Interactive Preview]
        PREVIEW -. Selection Sync .-> MD
    end

    subgraph PDFEngine ["PDF & Export Layer"]
        MD --> PM[pdfModel.js - Styled Blocks]
        PM --> PB[pdfBuilder.js - jsPDF Vector Stream]
        PB --> PA[pdfArtifact.js - Content-Keyed Cache]
        PA --> EXPORT[Export: PDF / DOCX / RTF]
    end

    subgraph ATSPipeline ["ATS Analyzer Engine (Local)"]
        PA --> PT[pdfText.js - pdf.js Text Layer Extractor]
        PT -->         EVAL[atsPdfEvaluation.js - 19 Scoring Rules]
        EVAL --> SCORE[ATS Score % + Gaps + Report]
        SCORE --> FIXES[markdownFixes.js - 1-Click Fixes]
        FIXES -. Apply Fix .-> MD
    end
Loading

How the ATS Evaluation Works

  1. Vector Document Build: pdfModel.js converts Markdown into structured style blocks. pdfBuilder.js renders real vector text via jsPDF.
  2. Content-Keyed Caching: pdfArtifact.js caches generated binary blobs based on a hash of the Markdown text and layout settings, ensuring scores and downloads never drift.
  3. Text Layer Extraction: pdfText.js invokes pdf.js to extract plain text per page, replicating how Enterprise ATS software (Workday, Taleo, Greenhouse) ingests resumes.
  4. Scoring & Diagnostics: atsPdfEvaluation.js checks 19 rules worth 100 points (see the table above): text layer existence, length, contact info, section structure, headings the parser cannot read, Markdown residue, exotic characters, action verbs, numbers, weak phrasing, duplicated bullets, keywords, bullet formatting, document language, dates and chronology, file name, page density and keyword stuffing. It can also score any PDF you already have (evaluatePdfFile).
  5. Undoable Pure Fixes: Detected formatting bugs (e.g. bold hashes, missing email prefix, invalid section headers) trigger single-click fixes applied via pure Markdown string transformations.

How the Local AI Rewriter Works

The AI assistant is entirely optional and entirely local. DownCV never proxies your CV to anyone: it only issues one POST request to the endpoint you configure, and it talks to Ollama's OpenAI-compatible API, so any local runtime exposing /v1/chat/completions works.

  1. Enable it: open the AI Assistant dialog (sparkles icon or Ctrl+K β†’ Open AI assistant) and turn on Enable AI in the preview.
  2. Configure it: set the endpoint (default http://localhost:11434/v1/chat/completions), the model name and, if your runtime requires it, an API key. Press Test connection to confirm the model answers.
  3. Select and rewrite: highlight any paragraph, bullet or heading in the A4 preview and press Improve with AI. DownCV first offers instant offline suggestions from enhanceBulletPoint() (weak-verb replacement, metric detection), then Generate with Ollama asks your model to rewrite the fragment keeping the exact same meaning but with stronger action verbs and quantified impact.
  4. Apply it: the answer arrives as one more suggestion; clicking it replaces only the selected range in the Markdown, so it stays undoable with Ctrl+Z.

The system prompt (aiEnhancer.js) is set to "You are an expert ATS resume writer and career coach", and the request is stripped of quotes so the result can be pasted straight back into the document.


πŸš€ Quick Start

Prerequisites

  • Node.js >= 22.0.0
  • npm >= 9.0.0

Local Development

  1. Clone the repository:

    git clone https://github.com/AcoranGonzalezMoray/DownCV.git
    cd DownCV
  2. Install dependencies:

    npm install
  3. Start the development server:

    npm run dev

    Open your browser at http://localhost:3000.

  4. Run tests:

    npm run test:run
  5. Lint and format code:

    npm run lint
    npm run format

Optional: Enable the Local AI Rewriter

The ATS rewriter needs a local model runtime. With Ollama:

ollama serve            # start the server (default port 11434)
ollama pull llama3      # or any other chat model you prefer

Then in DownCV open the AI Assistant dialog, enable it, and press Test connection. Any runtime that speaks the OpenAI /v1/chat/completions schema (Ollama, LM Studio, llama.cpp server, vLLM…) works by changing the endpoint.


🐳 Docker Setup

DownCV can be easily containerized and served using Nginx.

Using Docker Compose

npm run docker:up

Access DownCV in your browser at http://localhost:8080.

Manual Docker Build

docker build -t down-cv --build-arg VITE_APP_COMMIT=$(git rev-parse HEAD) .
docker run -d --name DownCV -p 8080:80 down-cv

πŸ“‚ Project Structure

DownCV/
β”œβ”€β”€ public/                 # Static assets, app icons & PWA manifest
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ components/         # React components
β”‚   β”‚   β”œβ”€β”€ ATSAnalyzer.jsx       # ATS score display, recommendations, 1-click fixes
β”‚   β”‚   β”œβ”€β”€ AIAssistantModal.jsx  # Ollama endpoint / model settings & connection test
β”‚   β”‚   β”œβ”€β”€ AiRewritePopover.jsx  # AI rewrite suggestions popover
β”‚   β”‚   β”œβ”€β”€ ContactWarnings.jsx   # Unverified email/phone/link banner & validator
β”‚   β”‚   β”œβ”€β”€ CoverLetterModal.jsx  # Cover letter generator & PDF exporter
β”‚   β”‚   β”œβ”€β”€ CVPreview.jsx         # A4 paper preview with direct formatting tools
β”‚   β”‚   β”œβ”€β”€ ExportMenu.jsx        # Dropdown menu for PDF, DOCX, RTF, PNG, JSON, HTML
β”‚   β”‚   β”œβ”€β”€ ImportModal.jsx       # Import PDF, DOCX, TXT, or MD into Markdown
β”‚   β”‚   β”œβ”€β”€ MarkdownEditor.jsx    # Caret shortcuts, sample CVs, search, draft history
β”‚   β”‚   β”œβ”€β”€ StyleControls.jsx     # Font, color palette, margin, line height & layout presets
β”‚   β”‚   β”œβ”€β”€ ThemeToggle.jsx       # Dark / light mode toggle
β”‚   β”‚   └── VariantsPanel.jsx     # Named CV versions per job offer & local .md file
β”‚   β”œβ”€β”€ data/               # Static seed data & i18n strings
β”‚   β”‚   β”œβ”€β”€ sampleCVs.js         # Ready-to-edit sample CVs per language
β”‚   β”‚   β”œβ”€β”€ snippets.js          # Reusable section snippets
β”‚   β”‚   β”œβ”€β”€ templates.js         # Layout template presets
β”‚   β”‚   └── translations.js      # English & Spanish UI strings
β”‚   β”œβ”€β”€ hooks/              # Custom React hooks
β”‚   β”‚   β”œβ”€β”€ useContactVerification.js # Verification logic for email/phone/URLs
β”‚   β”‚   β”œβ”€β”€ useKeyboardShortcuts.js   # Global hotkeys (Ctrl+S, Ctrl+Z, etc.)
β”‚   β”‚   β”œβ”€β”€ useLocalFile.js           # File System Access API .md linking
β”‚   β”‚   β”œβ”€β”€ useLocalStorage.js        # Synced localStorage state
β”‚   β”‚   └── useMarkdownHistory.js     # Pure undo/redo state stack
β”‚   β”œβ”€β”€ utils/              # Pure business logic & formatting modules
β”‚   β”‚   β”œβ”€β”€ aiEnhancer.js        # Local bullet enhancer + Ollama OpenAI-compatible client
β”‚   β”‚   β”œβ”€β”€ atsDimensions.js     # Rule groups behind the radar chart
β”‚   β”‚   β”œβ”€β”€ atsPdfEvaluation.js   # Main ATS evaluation orchestration (19 rules / 100 pts)
β”‚   β”‚   β”œβ”€β”€ atsReport.js          # Standalone HTML score report
β”‚   β”‚   β”œβ”€β”€ atsScorer.js          # Action verbs, keywords & weak phrase lexicons
β”‚   β”‚   β”œβ”€β”€ contactScan.js        # Contact parser & regex scanner
β”‚   β”‚   β”œβ”€β”€ coverLetter.js        # Template logic for cover letter creation
β”‚   β”‚   β”œβ”€β”€ cvImport.js           # Converter from arbitrary text to clean MD
β”‚   β”‚   β”œβ”€β”€ cvVariants.js         # CV version creation & keyword diffing
β”‚   β”‚   β”œβ”€β”€ docxGenerator.js      # OOXML (.docx) and RTF document exporter
β”‚   β”‚   β”œβ”€β”€ jobMatcher.js         # Job description keyword match score
β”‚   β”‚   β”œβ”€β”€ jsonResume.js         # JSON Resume (jsonresume.org) import/export
β”‚   β”‚   β”œβ”€β”€ markdownFixes.js      # Pure 1-click Markdown issue resolution
β”‚   β”‚   β”œβ”€β”€ markdownParser.js     # marked AST parser with source line offsets
β”‚   β”‚   β”œβ”€β”€ pdfBuilder.js         # Vector PDF rendering engine using jsPDF
β”‚   β”‚   └── pdfText.js            # pdf.js text layer reader worker
β”‚   β”œβ”€β”€ App.jsx             # Main application layout & state coordinator
β”‚   └── main.jsx            # Application entry point
β”œβ”€β”€ Dockerfile              # Multi-stage production build
β”œβ”€β”€ docker-compose.yml      # Local Docker configuration
└── vite.config.js          # Vite build configuration

πŸ—ΊοΈ Roadmap & Improvement Plan

We have an active product roadmap! Check out our planned features and technical improvements:

  • 🎨 Multi-column & Visual Template System (Sidebar skills/contacts vs main timeline).
  • 🌍 More languages: the UI is fully translated to English and Spanish today; French, German and Portuguese are next.
  • 🧩 Plugin-style ATS rule packs: let users define their own scoring rules as JSON instead of hardcoding them.
  • πŸ§ͺ Snapshot tests for the generated PDF text layer, to lock the ATS score against regressions.
  • ⌨️ Richer keyboard navigation across the preview, the variants panel and the command palette.

🀝 Contributing

Contributions are warmly welcomed! See CONTRIBUTING.md for the workflow, the pull request checklist and where to put your change.


πŸ“„ License

Distributed under the MIT License. See LICENSE for more information.

Crafted with ❀️ for privacy and career success.

About

DownCV is a modern, interactive, open-source web platform for creating, editing, analyzing, and exporting resumes (CVs) that are fully optimized for Applicant Tracking Systems (ATS) using Markdown syntax.

Topics

Resources

Contributing

Stars

15 stars

Watchers

0 watching

Forks

Used by

Contributors

Languages