Who This Is For: This workflow is designed for developers and technical professionals who are comfortable with command-line tools, enjoy working in code editors like VSCode, and who prefer markdown for writing (or are willing to give it a try). If you’re already using git for version control and don’t mind a bit of setup for long-term efficiency gains, this approach could save you significant time during your job search.
Introduction 💡
Job applications are tedious. Between customizing resumes, writing cover letters, tweaking formatting, and tracking applications, I was spending hours on administrative work instead of finding and responding to great opportunities–or working on side projects which I find infinitely more interesting.
A little while ago I wrote a blog post on writing with markdown, which has greatly sped up my writing process. I’ve been using it for several weeks now and have made a bunch of automation improvements which enable me to quickly create a job application, customize a resume, draft a new cover letter, and track each application’s progress.
I also took this opportunity to give Claude Code a test drive and see how it could help me build out some new automation scripts. In the past I’ve found agents like Cursor to be too aggressive–cranking out code faster than I can wrap my head around it. If I’m trying to learn something I want to go slow, ask questions, and understand what’s being built. Agents can’t reason but they’re good at replicating patterns, so I want to make sure it stays on track. (I’ll write more on Claude Code later–but so far I really like it!)
The result of this collaboration is my new workflow, which I wanted to share with others: Markdown Writer. It’s still a work in progress, but if you like working in an IDE and are comfortable with a CLI you might find this a good way to manage your job applications.
Why not use existing job tracking tools? TBH, I didn’t even research what’s available–I just knew I wanted to stay in my IDE where I’m most comfortable and productive. As developers, we often build our own tools not because existing solutions don’t exist, but because we have specific workflows and preferences. I wanted something that felt like coding: version-controlled, scriptable, and integrated with my daily development environment. Plus I wanted a small project to experiment with AI.
Get Set Up ⚙️
I use VSCode because it has great integration of file/project navigation, editing, helpful extensions, terminal integration, key bindings, snippets, and custom command integration. However this will also work with your favorite code editor and either zsh
or bash
in your terminal.
This project is available as a GitHub template repository, making it easy to create your own private copy with one click. Simply visit the Markdown Writer repository and click “Use this template” to create a new repository in your GitHub account.
If you prefer to clone and experiment first, you can use the repository directly:
git clone git@github.com:nickhart/markdown-writer.git
However, for ongoing use, I recommend creating your own repository from the template so you can customize it and track your applications privately. When there are updates to the main Markdown Writer repository, you can use the included script (scripts/sync.sh
) to copy updates from the upstream repository to your own, or manually copy specific files you want to update.
Requirements 📋
zsh
orbash
- VSCode or other code editor
- clone Markdown Writer
Installing ⬇️
git clone git@github.com:nickhart/markdown-writer.git
cd markdown-writer
./setup.sh
NOTE PDF formatting is supported, but requires installation of a LaTeX package. Out of the box Markdown Writer works great for creating DOCX files.
Configuring 🔧
Edit .writing.yml
with your information. You can see an example .writing.yml here.
Edit your resume and cover letter templates:
templates/resume/default.md
templates/cover_letter/default.md
If you wish to customize your document formatting you can edit the styles in the files located below. Be sure to modify the standard styles (Heading, Heading 2, Body, etc…), then save the changes to reference.docx. Pandoc will use these reference files and use the styles in them when generating your formatted resume or cover letter.
templates/resume/reference.docx
templates/cover_letter/reference.docx
You should now be ready to go. The system supports multiple resume templates. For many people “default” might suffice, but I find myself applying to a few different kinds of roles and have one tailored more towards mobile, frontend or fullstack… so I have resume templates with each of those names.
Workflow 🔄
Applying To a New Job 📝
When I want to apply to a new job from the terminal I run
job-apply Acme "Engineering Manager" default "http://acme.com/jobs/engineering-manager/1234"
Or if I want to use a specific resume template other than default:
job-apply Acme "Engineering Manager" fullstack "http://acme.com/jobs/engineering-manager/1234"
This creates a new job application in the applications/active/acme_engineering_manager_20250624
directory. It copies my “default” resume template and standard cover letter and performs the variable substitution using my .writing.yml
. It downloads the job description at the provided URL and saves it as an html file (job_description.html
). It creates a metadata file (application.yml
) which contains the company name, role, job description URL, and date created.
Then I go in and tweak the resume as needed (perhaps just the title, maybe the intro blurb), and then crank out a few brief paragraphs for the cover letter. Usually I want to customize the intro to the cover-letter, but often I’ve already got some good content from prior cover letters which addresses particular needs/requirements in the job description. The organization of the applications makes it super easy for me to find a prior cover letter, lift a few sentences and add them into my new cover letter.
Then I run job-format acme_engineering_manager_20250624
and it automatically formats my markdown resume and cover letter into DOCX
format, using reference template files with my preferred styles and page format. The formatted versions go into a formatted
subdirectory of the application. The .gitignore
automatically excludes the formatted docs from being committed–but if one wished they could tweak that and commit the formatted files too.
From here it’s a matter of uploading the DOCX files to the job application and filling out the rest of the application information.
Some applications require some essay-style questions, in which case I add another markdown file to the application folder (eg: application_questions.md
) and use my same editing process. I don’t bother formatting these into DOCX but it’s nice to have a record of my responses and then it’s easy to copy/paste them into the application form.
Submitting and Tracking the Application 📤
When I’m satisfied with the application I have a helpful command to commit it to my repo:
job-commit acme_engineering_manager_20250624
Once I’ve submitted the application, and as it moves through the review process I have a command to update its status:
job-status acme_engineering_manager_20250624 submitted
job-status acme_engineering_manager_20250624 interview
job-status acme_engineering_manager_20250624 offered
job-status acme_engineering_manager_20250624 rejected
Each of these statuses has its own sub-folder inside the applications
folder in the project root. The job-status
command moves the application from one folder to another and updates the status in the application.yml metadata file.
If I get to the interview stage (w00t!) I take notes in a markdown file which I keep in the application’s folder, eg:
applications/
interview/
acme_engineering_manager_20250624/
recruiter_notes.md
hiring_manager_notes.md
interview_loop_notes.md
I also have a job-log
command which will show a summary of all my applications, or just ones in a certain status. Right now the summary is terse, but I intend to make it a bit fancier in case someone in the state unemployment office decides to challenge me. It will be trivial to take the metadata and generate a log of each job application in DOCX format to prove I’ve exceeded their “three job activities a week” requirement.
VSCode Integration 🛠️
I mentioned in my prior post about how I like to use VSCode for my markdown writing. For those who are also using VSCode it will recommend some extensions that I find handy:
- Markdown All in One
- Code Spell Checker
- markdownlint
- Word Count
- YAML
The VSCode configuration adds some helpful settings for Markdown and YAML editing, as well as allowlisting some common words that the spell checker might flag.
It also adds some commands to the command palette. With a simple cmd-shift-p
to open the command palette, select Run Tasks
, and choose one of my commands like Create Job Application
. It’ll prompt me for the company name, role, which resume template (or use default
), and the URL for the job description. It’ll run the command in a terminal and show me the output!
Wrapping Up and Next Steps 🚀
In my last post on this topic it was taking me an hour to do what now takes me 20 minutes–and most of that time is me thinking about what I want to write and entering it into a markdown file. I still only apply to a few jobs a day, but I can focus on applying to the roles that really interest me, take the time to craft a thoughtful cover letter, and then have more time to work on my other projects or write a blog post.
I will continue to use the Markdown Writer to craft my job applications. I also use it for blog posts and format the results into HTML which I can copy/paste into WordPress. No doubt I will continue to refine this aspect of my writing workflow.
And if you’re curious about some of the other features I’m planning for my job application workflow, take a look at the TODO!