No Word templates. No Canva. No $19/month subscriptions. Just code.
This is what the generated
resume.docxlooks like when opened in Microsoft Word or Google Docs.
70–80% of resumes are rejected by ATS (Applicant Tracking Systems) before a human ever reads them — often because of formatting issues, not missing qualifications.
Common ATS failure points:
- ❌ Multi-column layouts the parser can't read linearly
- ❌ Text inside tables, text boxes, or headers/footers
- ❌ PDFs exported from Canva or Figma
- ❌ Non-standard section headings ("My Journey" vs "Experience")
- ❌ Icons and graphics replacing actual text
This script generates a .docx file — the gold standard format for ATS compatibility — with clean semantic structure, standard section headings, and zero layout tricks that could trip up a parser.
- ✅ ATS-optimized
.docxoutput — parsed reliably by all major ATS platforms - ✅ Single-column layout — no multi-column confusion for scanners
- ✅ Standard section headings —
EXPERIENCE,SKILLS,EDUCATION,PROJECTS - ✅ Right-aligned dates — using proper tab stops, not tables
- ✅ Inline hyperlinks — GitHub, LinkedIn, certificates, publications
- ✅ Composable bullet system — mix bold, normal, and accent text in one line
- ✅ Skills table — keyword-dense and fully readable by ATS
- ✅ 4-variable color system — reskin everything by changing 4 lines
- ✅ Zero external services — runs fully offline
ATS-Friendly-Resume-Template/
├── resume.js ← Main generator script (edit this)
├── sample-resume.docx ← Pre-generated sample output
├── images/
│ └── sample.png ← Preview image for README
├── package.json ← Project metadata and dependencies
└── README.md ← You are here
- Node.js v18 or higher
- npm (comes with Node.js)
git clone https://github.com/ShreyashPG/ATS-Friendly-Resume-Template.git
cd ATS-Friendly-Resume-Templatenpm installOpen resume.js and look for STEP 2 in the comments. Replace the sample data with your own:
// ── NAME ──
"YOUR FULL NAME"
// ── TAGLINE ──
"Your Role · Your Specialty · Your Focus Area"
// ── CONTACT BAR ──
"Your City, Country"
"+91 XXXXXXXXXX"
link("your@email.com", "mailto:your@email.com")
link("linkedin.com/in/yourprofile", "https://linkedin.com/in/yourprofile")
link("github.com/yourusername", "https://github.com/yourusername")node resume.js
# ✅ resume.docx generated successfully!Your resume.docx will appear in the current directory. Open it in Microsoft Word, Google Docs, or LibreOffice.
At the top of resume.js, update the four color constants:
const COLOR_ACCENT = "1A56A0"; // Blue — headings, bullets, links
const COLOR_DARK = "1A1A2E"; // Near-black — name, company names
const COLOR_MID = "444444"; // Body text
const COLOR_LIGHT = "666666"; // Dates, subtitles, captionsThat's it. Every element in the document updates automatically.
jobHeader("Company Name", "Your Role", "Month Year – Month Year", "https://certificate-link.com")
bullet([normal("Led development of "), bold("key feature"), normal(" that improved "), accent("metric by X%"), normal(".")])
bullet([normal("Another bullet describing your impact.")])Pass
nullas the 4th argument tojobHeaderif you have no certificate link.
projHeader("Project Title", "2025", "https://github.com/you/project")
new Paragraph({
children: [
new TextRun({ text: "Stack: ", bold: true, size: 18, color: COLOR_DARK, font: "Arial" }),
new TextRun({ text: "Tech · Stack · Here", size: 18, color: COLOR_LIGHT, font: "Arial", italics: true })
]
})
bullet([normal("What the project does and the impact it had.")])skillRow("Category", "Skill 1, Skill 2, Skill 3, Skill 4")In the numbering config at the top of the Document, change text: "▸" to any character you prefer — •, –, →, etc.
| Helper | Purpose |
|---|---|
bold(text) |
Dark bold text run |
normal(text) |
Regular body text run |
accent(text) |
Accent-colored bold text — use for metrics and numbers |
bullet(runs[]) |
Bulleted paragraph — pass an array of text runs |
sectionHeading(text) |
Section header with bottom border (auto-uppercased) |
jobHeader(company, role, period, certUrl) |
Experience entry header with right-aligned date |
projHeader(title, period, githubUrl) |
Project entry header with right-aligned date |
skillRow(label, value) |
Two-cell table row for the skills section |
link(displayText, url) |
Styled external hyperlink |
spacer(before, after) |
Vertical whitespace paragraph |
rule(color, size) |
Horizontal divider line |
Before submitting your resume, verify:
- File saved as
.docx(not PDF, not.doc) - No text inside headers, footers, or text boxes
- Section names match ATS keywords (
EXPERIENCE,EDUCATION,SKILLS,PROJECTS) - Dates present on all experience and education entries
- Single-column layout (no side columns)
- No tables used for layout (only for skills — text remains readable)
- Contact information in the document body, not in a header
This script handles all of the above by default. ✅
- Multi-role variants — Extract content into a
data.jsfile; maintaindata-swe.js,data-de.jsetc. and swap with one import line - GitHub Actions — Auto-generate and commit the latest
resume.docxon every push so it's always current - PDF export — Add
soffice --headless --convert-to pdf resume.docxafter generation for a PDF copy - ATS keyword scorer — Extract text from the generated file and match against a job description
- CLI flags —
node resume.js --role=backendto swap skill emphasis automatically
A detailed walkthrough of the script design, ATS optimization decisions, and how to customize it for your own use:
👉 I Wrote a Node.js Script to Generate an ATS-Friendly Resume — Here's the Full Breakdown
Contributions are welcome! If you have ideas for improvements — new sections, better ATS heuristics, CLI support — feel free to open an issue or submit a PR.
- Fork the repository
- Create your branch:
git checkout -b feature/your-feature - Commit your changes:
git commit -m 'Add your feature' - Push to the branch:
git push origin feature/your-feature - Open a Pull Request
This project is licensed under the MIT License — see the LICENSE file for details.
Made with ☕ by Shreyash Ghanekar
If this helped your job search, consider giving it a ⭐
