First Day With Vitest, and It Immediately Exposed Two Bugs
A Next.js frontend got its first vitest suite: 12/12 green, yet two bugs surfaced while writing the tests, before they could become complaints.
TL;DR
Installed Vitest on a Nextjs frontend that had no tests and wrote twelve passing checks. Writing them revealed two hidden issues, a client name duplicated across industry groups and a token gate whose glob missed files directly under src. The takeaway is to add a test harness early, since building tests finds bugs even when everything stays green.
The Next.js frontend of a company-profile project had been running for weeks without a single unit test. Builds passed, pages rendered, so I assumed it was healthy. That night I installed a test harness for the first time: pinned vitest 4.1.11, wrote the first twelve tests, ran npm run test. Twelve out of twelve green. Except that while writing those tests, two bugs surfaced.
My initial expectation was flat: the suite would be formal proof that things already work. Tests I wrote myself, surely all green, finding nothing. It turned out the act of writing the tests was the inspection tool.
The Count Assertion That Forced a Comparison
The first test covered client name data: a long list grouped by industry. I wrote a simple invariant: per-group counts must exactly match the raw list, and no group may contain a duplicate name. Once that assertion existed, I had to scroll the data top to bottom and compare it line by line against the raw list. The rule is easy: a name that already appears in one group must not appear in another. It surfaced: one client name appeared in two different industry groups. Most likely that was deliberate; the company is publicly listed and has divisions in two sectors. But nobody had recorded it, and whether cross-group duplicates are allowed should be the content owner's call, not the person who happened to type the data.
The second finding was more technical. There is a gate script called validate-tokens.cjs whose job is to block hex colors that show up outside the token sheets. To test it, the test builds a throwaway git repo: mkdtemp for a temp folder, copy the script in, git init, git add, then check exit codes. Those sixteen lines of scenario-building made me wonder: if a component file sits directly under src/, not in a subfolder, does the gate still see it?
It does not. The pathspec src/**/*.tsx lets files directly under src/ slip through. The glob mechanics are interesting and mildly counterintuitive; I cover them fully in a separate article.
A Minimal Setup Worth Copying
Installation is standard: npm install -D vitest, then pin the version; at writing time 4.1.11 [1]. It requires Vite >= 6.4.0 and Node >= 22.12.0 [1].
Test file names must contain .test. or .spec. to be picked up automatically [1]. So I colocate: the test file sits next to the file it tests. Easy to find, easy to delete together.
One thing I did differently from the docs examples: the test script runs once and exits instead of the default watch mode [1]. The vitest run command does exactly that: one execution, done, exit [2]. For a CI gate that beats a process waiting for file changes forever.
Mocking next/server Without the Drama
The third test I enjoyed most: the locale redirect in the proxy. Its logic is pure data types and URL decisions, so next/server gets mocked with vi.mock [4]. One common trap: the vi.mock call is hoisted to the top of the file by Vitest, so where you write it does not matter [4]. But it only works for modules that are imported, not required [4]. If your mock seems dead, check those two things before touching the test logic.
A Harness That Finds Nothing Was Installed Too Late
Out of the first twelve tests, zero failed, yet two bugs surfaced. My favorite part of this story is not the findings themselves but their timing: before they could become complaints. The duplicate name, if not now, would have appeared when someone got suspicious about odd-looking data. The gate blind spot, if not now, would have appeared when someone deliberately dropped a file into src/ to dodge review.
So here is my firm opinion: a test harness is a bug finder, not a ceremony for rounding up coverage numbers. Install it while the codebase is still young, because day one is the most productive moment for finding something. If your first suite finds nothing at all, I don't suspect your code is great. I suspect you installed it too late.
## Sources
[1] https://vitest.dev/guide — Getting Started | Vitest (install, npm install -D vitest, vitest run) [2] https://vitest.dev/guide/cli — Command Line Interface | Vitest (vitest run = single run without watch) [4] https://vitest.dev/api/vi.html — Vi | Vitest (vi.mock hoisting, next/server mock)
Sources
1. the official Vitest guide
2. the Vitest CLI docs
4. the vi.mock API reference