In short
Everyone has a calculator project. Yours stands out if it never breaks: keyboard support, no eval, and no 0.30000000000000004 on screen. Small project, big polish.
Revisit the calculator project with production polish — clean architecture, keyboard support, history, and thorough edge-case handling — a strong 'simple but well-executed' portfolio piece.

Think of it like this
The billing counter at a sweet shop
The person at the counter adds up your order fast and never gets it wrong, even when you change your mind halfway. A good calculator feels the same: quick, calm and always correct.
Watch it happen
What happens when you type 0.1 + 0.2
a=0.1, op=+, b=0.2
1/5Each key updates state: the first number, then the operator, then the second number.
The big ideas
What you need to know
Works with the keyboard
Numbers, operators, Enter for equals, Backspace and Escape. It shows you think about real users.
No eval()
Parse the input yourself. Recruiters reading your code will notice, because eval is a security red flag.
Handles edge cases
Divide by zero, two operators in a row, many decimals and very long numbers.
Shows history
A small list of past calculations proves you can manage state beyond one value.
How it works
Build plan
- 1
Layout first
Grid of buttons and a display, responsive down to a small phone.
- 2
Store state
Keep current input, previous value and operator in state.
- 3
Write the logic
A pure calculate(a, op, b) function you can test on its own.
- 4
Add the keyboard
One keydown listener that maps keys to the same handlers as buttons.
- 5
Polish and deploy
Edge cases, history, a README with a GIF, then deploy to Vercel.
See it in code
Walk through the code
1function calculate(a, op, b) {2 switch (op) {3 case "+": return a + b;4 case "-": return a - b;5 case "*": return a * b;6 case "/": return b === 0 ? NaN : a / b;7 }8}9 10// Avoid 0.1 + 0.2 = 0.30000000000000004 on screen11const display = (n) =>12 Number.isNaN(n) ? "Can't divide by 0" : String(parseFloat(n.toFixed(10)));13 14display(calculate(0.1, "+", 0.2)); // "0.3"1/4A plain switch handles each operator. No eval anywhere.
Keeping calculate() pure means you can unit test it without any UI. toFixed(10) rounds off the floating point noise, and parseFloat drops trailing zeros.
Save yourself the pain
Common mistakes
Oops
Using eval(display) to get the answer.
Do this instead
Handle each operator yourself. eval runs any code, and recruiters treat it as a red flag.
Oops
Copying a YouTube tutorial line by line.
Do this instead
Build it once from your own head, even if it's messier. Add features the tutorial didn't have.
Oops
Only testing the happy path like 2 + 2.
Do this instead
Try 5 ÷ 0, pressing + twice, and typing 0.1 + 0.2 before you call it done.
Your mission
Milestone 1: a calculator that can't be broken
Quick check
What does 0.1 + 0.2 give in JavaScript?
Go deeper
- 1Add calculation history and the ability to reuse a previous result.
- 2Write unit tests for the arithmetic logic, separated from the UI.
- 3Polish the UI with proper animations and responsive design.
More projects at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.