Portfolio projects for junior developers: what recruiters want

How to pick portfolio projects for junior developers that recruiters actually open: 6 questions to score a project, where to find ideas, and a README template.

What should a junior developer build as a portfolio project? A small project that solves a real problem of your own, with a live demo, a README that explains your decisions, and one hard part you can explain in two minutes. Let's score Minh's three projects and see why.

Where is Minh stuck?

In the previous post, Minh fixed 10 mistakes on a resume. Minh is a made-up character, pieced together from situations fresh IT graduates in Vietnam will find very familiar, but the advice applies to you straight away.

The new resume is clean: one page, one column, skills split into groups, a GitHub link. But next to a job ad, Minh sees that the projects section is still thin. The graduation project was a team of four, and Minh's part was only the shopping cart and checkout. The Netflix clone has been crossed off. The personal expense-tracker project is still just an idea.

Minh's question is also the one I'm asked most often: what should I build, and how far do I need to take it?

What does the person looking at your project actually do?

Before choosing a project, picture the person who will open it. It might be a developer on the hiring team, asked to take a quick look at a few applications between two other tasks. They don't have a whole afternoon for you.

I don't have official data on this, but the posts by people who hire that I've read all describe a fairly similar order. First they click the demo link to see whether the app opens and what it does. Then they read the README to understand what problem the project solves. Only if they still have time and are still curious do they open the code, skim one important file and look at the commit history.

That order teaches you one important thing: the project has to convince people in those first steps. Beautiful code with no demo and no README usually loses the reader before they ever see the beautiful code.

Six questions to score a project

So Minh doesn't have to guess, I wrote a scorecard of six questions, each worth 0, 1 or 2 points. You can copy it and use it on your own projects.

Question one asks whose problem the project solves. A class assignment or a project built along with a video scores 0, because someone else already solved the problem. A project that solves a real problem but has no users yet scores 1. Real users, even if that's only you and a few friends, score 2. Real users matter because they bring bugs you would never think of yourself.

Question two asks whether the person reading your resume can try it. No link is 0, a repo only is 1, and a live demo that works on a phone is 2. I stress "phone" because a lot of people read resumes on their phones, and a page whose layout breaks on a small screen leaves a poor impression.

Question three asks what the README answers. According to GitHub's documentation on READMEs, a README usually says what the project does, why it's useful and how to get started with it. For a project you'll use to get hired, I'd add one more part, the technical decisions, because that's where the reader sees how you think.

Question four asks who did the hardest part. No hard part scores 0. A hard part you can't explain yet scores 1. Explaining it in two minutes, including why it was hard, what you tried and what you finally chose, scores 2.

Question five asks whether there are signs of serious work. Every commit says "update" and there are no tests: 0. Meaningful commits, tests for the hard part, error handling: 2. The post on how to write good commit messages has templates you can start using today.

Question six asks whether the project matches the role you're applying for. A PHP project for a React frontend role still has value, but it doesn't prove what the hiring team needs to know.

The maximum is 12. Score 9 or more and the project goes at the top of your Projects section. Between 5 and 8, keep it if there's room, and fix the lowest-scoring question first. Below 5, take it off your resume, or keep working on it until it gets there.

This scorecard isn't any company's official rubric. It's my way of turning what people who review projects tend to notice into a list you can check.

Why doesn't the Netflix clone help Minh?

Minh scores all three projects with the six questions above. The scores below are an illustration, and each comes with a reason so you can score your own projects the same way.

The Netflix clone built along with a video gets 3 out of 12:

  • Question 1 gets 0: it doesn't solve anyone's problem, it only copies an existing interface.
  • Question 2 gets 1: there's a repo, but the demo broke long ago.
  • Question 3 gets 0: the README is still the default file the setup tool generated.
  • Question 4 gets 0: the hardest part was solved by the person who made the video.
  • Question 5 gets 0: every commit says "update" and there are no tests.
  • Question 6 gets 2: it's written in React, the technology the role asks for.

The coffee shop website, a graduation project for a team of four, gets 8:

  • Question 1 gets 1: the topic was assigned by the university and has no real users.
  • Question 2 gets 2: the demo still opens on a phone.
  • Question 3 gets 1: the README has a description and run commands but no technical decisions.
  • Question 4 gets 1: the hardest part was checkout, and Minh only built its interface; another teammate connected the payment gateway.
  • Question 5 gets 1: the commits are meaningful, but there are almost no tests.
  • Question 6 gets 2: it uses React, as the role asks.

The expense tracker you use by text message, after three weeks of evenings, gets 11:

  • Question 1 gets 2: Minh and a few friends use it every day.
  • Question 2 gets 2: there's a demo that works right away on a phone.
  • Question 3 gets 2: the README has the problem, a demo image, run commands and a technical decisions section.
  • Question 4 gets 2: Minh built the amount-reading part alone and can explain it.
  • Question 5 gets 1: there are 21 tests, but no error handling yet for when saving data fails.
  • Question 6 gets 2: it uses TypeScript and Next.js, just like the job ad.

The Netflix clone scores only 3, and 2 of those points come from using React. Its problem isn't that it was built along with a video; following videos is a good way to learn. The problem is that every hard decision in the project was made by the person in the video. When the interviewer asks "why did you split the components like this?", the true answer is "because the video did", and both sides know it.

Hundreds of other candidates have exactly this project, with almost exactly this interface. It doesn't help the reader tell you apart from anyone else, and that's the main job of the Projects section.

The team project scores 8, which is quite good. The most notable lost point is question 4, because the hardest part of the project wasn't Minh's. That's why, as the previous post said, the resume needs to state Minh's part clearly, and Minh should only claim what Minh can explain.

The expense tracker is the project Minh will put first. The interesting thing is that it's much smaller than the other two: no fancy interface, no payments. It wins on three things the other two lack: real users, a hard part Minh solved alone, and a story to tell.

Find ideas in the things that annoy you

The hardest question is what to build. What I usually suggest is: don't sit and think, just pay attention for a week. Every time something annoys you, a task you keep repeating, a messy spreadsheet, a group chat arguing about money, write one line in a note on your phone.

At the end of the week, filter the list with four questions.

Does at least one person, you included, run into this every week? Can you finish a first version in two or three weeks of evenings? Does it have at least one hard part that's within your reach? Can you build it with the technology of the role you want?

After a week, Minh's list (an illustration) has five lines. Each line has what annoyed Minh, a project that could fix it, and how it did against the four questions:

  • Minh keeps forgetting how much has been spent this month, so the idea is an app that logs expenses from a text message. It passes all four questions: Minh runs into it every day, a first version fits in three weeks, reading amounts is a hard part within reach, and it can be built with React. Minh picks this one.
  • Minh's class splits the cost of meals in a group chat and argues at the end of every month, so the idea is a group bill-splitting app. It also passes all four, but Minh saves it for later, because you should only build one main project at a time.
  • A university club takes attendance with a Google Form and counts by hand, so the idea is an attendance app with QR codes. It passes on the technical side, but it only gets real users if people in the club agree to use it, so Minh doesn't pick it yet.
  • Minh wants to watch new films, so the idea is a Netflix clone. It fails the very first question, because it doesn't solve anyone's problem.
  • Minh wants to learn Kubernetes, so the idea is to set up a Kubernetes cluster. It fails the last question, because Minh is applying for frontend roles.

The last two lines are two familiar traps. One is choosing a project by what you like to watch rather than by a problem to solve. The other is choosing a project by whatever technology is hot rather than by the role you're applying for. There's nothing wrong with learning Kubernetes, but it won't help Minh get past the resume screen for a frontend role.

A project that solves your own problem has one big advantage: you're its first user, so you run into real bugs. Minh's expense tracker is also the very project built for real in the series Building a side project with AI.

There, two very everyday bugs showed up in just two evenings. Sending "coffee 35 thousand" recorded 35 đồng (Vietnam's currency, where a coffee costs tens of thousands), and an expense at 6:30 a.m. on 1 December was counted in November, because the server runs on UTC. No class assignment gives you bugs like that, and they're exactly what's worth talking about in an interview.

A scope small enough to finish

The most common mistake I see in personal projects isn't picking the wrong idea; it's not finishing. An expense app with login, categories, charts, budgets and Excel export, each 60% done, has no demo anyone can use. On the scorecard above, it loses points straight away on question 2.

The way to cut scope that I find most effective is to write exactly one sentence in the form "the user can do X in Y seconds". Minh's sentence is: I can log an expense in 5 seconds without opening an app. Every feature that doesn't serve that sentence waits for a later version. Categories, charts and multiple users are all out of the first version.

A small first version gets finished in three weeks of evenings, gets early users and gets real bugs to fix. A small finished project is always worth more than a big half-finished one.

A hard part within reach is the part worth talking about

In the interview round, "tell me about your project" is almost certain to come up, and the interviewer will dig into the hardest part. So when you choose a project, make sure it has one hard part that you solved yourself.

"Hard" here doesn't mean a complex algorithm. In Minh's project, the hard part is reading amounts in all the ways people in Vietnam write them: "35k", "45.000", "1tr2" (*tr* for *triệu*, million, so 1.2 million), "35 thousand". It's within a junior's reach, but enough to involve decisions, experiments and mistakes. A two-minute answer about it can follow four steps (this is an illustration):

The hardest part was reading amounts, because people in Vietnam write them in lots of ways, and the dot in "45.000" separates thousands, it isn't a decimal point. My first rushed version read "train ticket 32K" as 32 billion, because the function multiplied by a million whenever it saw the letters "tr", and "train" contains them. So I switched to writing a table of examples first, one test per row, and only then writing the code. There was one decision I thought about for quite a while: when a message has two amounts, I reject it, because recording the wrong amount is worse than asking the user to send it again. The app still doesn't understand "1 million 2", and I wrote that down in the spec as not supported yet.

That answer has a problem, a failed attempt, a decision with its reason, and a limit it admits to. The interviewer doesn't need a perfect project. They need to see how you think when you hit a problem.

A README turns your project into a story

After the demo, the README is the first page people read, so I treat it as part of the project, not as extra work. Below is the complete README for Minh's expense tracker. You can copy it as a template and replace the content with your own project. The links and images in it are examples:

README.md (template for the expense tracker)
# Expense tracker by text message

Send `coffee 35k` and the expense is logged. Send `/total` to see this month's total.

Demo: expense-tracker.vercel.app · Image: docs/demo.gif (send 3 expenses, then see the total)

## Why I built it
I kept forgetting how much I'd spent, and I was too lazy to open an app with a 5-field form. Sending one line is too easy to skip.

## What it does
- Reads amounts the way people in Vietnam write them: `35k`, `45.000`, `1tr2`, `35 thousand`.
- Asks again instead of guessing: `coffee 35k 40k` is rejected because it has two amounts.
- `/total` adds up the month in Vietnam time, even when the server runs on UTC.

## Technical decisions
- I wrote the amount parser myself, without a library, because the rules are specific to how amounts are written in Vietnam. Each rule is one line in SPEC.md and one test.
- Reject when ambiguous, because recording the wrong amount is worse than asking the user to send it again.
- Months are computed in Asia/Ho_Chi_Minh. This was a real bug: an expense at 6:30 a.m. on 1 December was counted in November because the server runs on UTC.

## Run it locally
npm install
npm test
npm run dev

## Next
Save to a database; receive messages through Telegram.

The section I most want you to notice is "Technical decisions". Its three lines do something the code can't: they show the reader the reason behind each choice. Someone skimming the README for one minute already knows that Minh writes tests, weighs the user's experience and has dealt with a time zone bug. Those are also three interview questions Minh has already prepared answers for.

The other sections are simpler, but their order has a reason. The description and the demo link sit at the top, because those are the two things the reader needs in the first ten seconds. The commands to run it locally sit near the end, because only someone who wants to read the code needs them. GitHub's guide linked above covers each part in more detail.

One big project or several small ones?

In my view, for a junior, one really good main project plus one or two side projects is enough. Three 11-point projects are much harder to build than one, and the reader rarely opens all of them anyway.

A side project can be a team project, as long as you state your part clearly, or a small tool you wrote for yourself. Projects that score below 5 belong on GitHub, not on your resume. They don't do harm, but they take the place of something better.

And don't forget that time is always limited. Three weeks of evenings on the main project, then stop, polish the README and send your resume out. You can keep improving the project while you wait to hear back, and every improvement becomes another story to tell.

You have the project. Where do you show it so people click?

Three weeks later, Minh's expense tracker has a demo, a README and 21 tests. But Minh's GitHub page is still a mess: every repo is pinned, the bio is empty, and on LinkedIn nobody knows the project exists. GitHub lets you pin up to six repositories and gists to your profile, and choosing those six is a story of its own.

The next post in the series works with Minh on GitHub and LinkedIn so that the profile makes people want to click. You can follow the whole journey in the series The junior journey. And if you'd like to practise "if you could redo this project, what would you change?" ahead of time, that question is in the interview question bank.

Get the next post by email.

One email a week, only when there is something worth reading. No spam.