AcoranGonzalezMoray/DownCV

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.

JavaScript

11

5 commits

updated Oct 12, 2026

See the code

See what people are saying

SourceMessageScoreDate

DownCV - An open-source tool to create ATS-optimized resumes using Markdown (r/coolgithubprojects)

Hi everyone! I created **DownCV**, a Markdown resume tool for creating, editing, analyzing, and exporting resumes (CVs) that are optimized for Applicant Tracking Systems (ATS) using Markdown syntax. # Key Features * Markdown editor + live A4 preview click and format text directly on the page…

1

Oct 8, 2026

README

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

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.

RulePointsWhat it fails on
text10The PDF has almost no selectable text (a scan or an image)
pages8More than two pages
length3Fewer than 200 or more than 900 words
contact9Fewer than two of email, phone and profile link
sections9Fewer than three standard sections found as headings
headings4A source heading that never reaches the sheet as a heading (a title too long, wrapped into loose lines)
residue6Markdown or HTML syntax visible in the text layer
emoji3An emoji or an image/table placeholder a parser cannot read
verbs10Fewer than four action verbs
metrics8Fewer than two numbers behind the achievements
phrasing5Fillers such as "responsible for" or "hard-working", with the verb that says it better
duplicates3The same bullet copied into two jobs
keywords5Fewer than four relevant terms, including the ones the detected role expects
bullets4More than 30% of the experience bullets with no verb and no number
language2Headings in one language and bullets in another
dates4A date in the future, two date styles mixed, or two jobs claiming the same months
filename2A file name without your name, with spaces, or marked "final" / "v2"
density3A single page over 750 words (the densest page, not the average)
stuffing2A 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

LayerTechnologyPurpose
Frontend FrameworkReact 18 & Vite 6Fast SPA rendering & modern build pipeline
Styling & UITailwind CSS 4 + Lucide IconsResponsive layout, dark mode, CSS custom properties
Markdown ProcessingMarked.js (Custom Renderer)AST block tagging & bi-directional source mapping
PDF GenerationjsPDFNative vector text streams (WinAnsi fallback, standard A4 layout)
ATS Text ExtractionPDF.js (pdfjs-dist)Worker-based text layer parsing mimicking Workday/Taleo
Word / RTF Exportdocx (OOXML)Native .docx block generation and .rtf document creation
Testing SuiteVitest 5 + React Testing LibraryUnit & integration tests for parser, builders, and UI
Deployment / ContainerDocker + Nginx AlpineLightweight 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

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

docker compose up -d --build

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

Manual Docker Build

docker build -t down-cv .
docker run -d -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! Whether you want to fix a bug, add a new ATS scoring rule, translate to a new language, or suggest a feature:

  1. Fork the project.
  2. Create your feature branch (git checkout -b feature/AmazingFeature).
  3. Commit your changes (git commit -m 'Add some AmazingFeature').
  4. Ensure tests and linting pass (npm run lint && npm run test:run).
  5. Push to the branch (git push origin feature/AmazingFeature).
  6. Open a Pull Request.

πŸ“„ License

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

Crafted with ❀️ for privacy and career success.

ats-resume
ats-scanner
ats-score
cv
cv-builder
cv-builder-app
cv-builder-tool
cv-building
cv-template
resume-builder

AcoranGonzalezMoray/DownCV

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.

JavaScript

11

5 commits

updated Oct 12, 2026

See the code

See what people are saying

SourceMessageScoreDate

DownCV - An open-source tool to create ATS-optimized resumes using Markdown (r/coolgithubprojects)

Hi everyone! I created **DownCV**, a Markdown resume tool for creating, editing, analyzing, and exporting resumes (CVs) that are optimized for Applicant Tracking Systems (ATS) using Markdown syntax. # Key Features * Markdown editor + live A4 preview click and format text directly on the page…

1

Oct 8, 2026

README

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

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.

RulePointsWhat it fails on
text10The PDF has almost no selectable text (a scan or an image)
pages8More than two pages
length3Fewer than 200 or more than 900 words
contact9Fewer than two of email, phone and profile link
sections9Fewer than three standard sections found as headings
headings4A source heading that never reaches the sheet as a heading (a title too long, wrapped into loose lines)
residue6Markdown or HTML syntax visible in the text layer
emoji3An emoji or an image/table placeholder a parser cannot read
verbs10Fewer than four action verbs
metrics8Fewer than two numbers behind the achievements
phrasing5Fillers such as "responsible for" or "hard-working", with the verb that says it better
duplicates3The same bullet copied into two jobs
keywords5Fewer than four relevant terms, including the ones the detected role expects
bullets4More than 30% of the experience bullets with no verb and no number
language2Headings in one language and bullets in another
dates4A date in the future, two date styles mixed, or two jobs claiming the same months
filename2A file name without your name, with spaces, or marked "final" / "v2"
density3A single page over 750 words (the densest page, not the average)
stuffing2A 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

LayerTechnologyPurpose
Frontend FrameworkReact 18 & Vite 6Fast SPA rendering & modern build pipeline
Styling & UITailwind CSS 4 + Lucide IconsResponsive layout, dark mode, CSS custom properties
Markdown ProcessingMarked.js (Custom Renderer)AST block tagging & bi-directional source mapping
PDF GenerationjsPDFNative vector text streams (WinAnsi fallback, standard A4 layout)
ATS Text ExtractionPDF.js (pdfjs-dist)Worker-based text layer parsing mimicking Workday/Taleo
Word / RTF Exportdocx (OOXML)Native .docx block generation and .rtf document creation
Testing SuiteVitest 5 + React Testing LibraryUnit & integration tests for parser, builders, and UI
Deployment / ContainerDocker + Nginx AlpineLightweight 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

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

docker compose up -d --build

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

Manual Docker Build

docker build -t down-cv .
docker run -d -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! Whether you want to fix a bug, add a new ATS scoring rule, translate to a new language, or suggest a feature:

  1. Fork the project.
  2. Create your feature branch (git checkout -b feature/AmazingFeature).
  3. Commit your changes (git commit -m 'Add some AmazingFeature').
  4. Ensure tests and linting pass (npm run lint && npm run test:run).
  5. Push to the branch (git push origin feature/AmazingFeature).
  6. Open a Pull Request.

πŸ“„ License

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

Crafted with ❀️ for privacy and career success.

ats-resume
ats-scanner
ats-score
cv
cv-builder
cv-builder-app
cv-builder-tool
cv-building
cv-template
resume-builder