A dilemma before adopting Vitest… are unit tests really necessary?
The reason I started thinking about whether unit tests are necessary is that, while I was writing only E2E tests for a project, a UI/UX overhaul of the project itself got scheduled. With the UI/UX redesign coming up, I ended up halting the E2E test work, and it left me wishing that if only I had had unit tests at that point.
Concerns about adopting unit tests
I think I always wondered whether unit tests would be genuinely helpful in a project made up of React components.
And I remember that figuring out how best to separate the logic contained within components was not an easy point either.
Many projects run just fine without unit tests, and there's also an anxiety about the resources needed to write and maintain tests.

Advantages of adopting unit tests
We already know that having tests in a project helps in various ways, including stability. Detecting problems caused by simple mistakes when modifying code, and verifying existing functionality when refactoring, are examples that come to mind.
Personally, a part I think could be both an advantage and a disadvantage is that it naturally (?) leads you to modularize your code, separating it by functionality or concern. The reason I see it as an advantage is that separating code by functionality or concern reduces the complexity of the logic, which can improve code comprehension and minimize the impact when making changes. The reason I see it as a disadvantage is a concern that you might end up writing code unnaturally, insisting on modularizing purely for the sake of unit testing.
Disadvantages of adopting unit tests
The biggest barrier, I think, is the time to spare for writing and maintaining tests. Schedules that start from planning tend to get backed up, and as you go, logic with tests and logic without tests get mixed together, and afterward the priority of writing tests keeps getting pushed back—situations like that have happened. Looking back, I also think my own laziness… played a part in this.
Next, there's the question of how to isolate logic within React components—including state management, hooks, and events—for unit testing. For example, when there's a dependency between components, you have to rethink the component design from scratch in order to build the tests… and reconstructing components just for the sake of testing can feel like the tail wagging the dog.
The last is trust in the tests themselves. As you write unit tests, you can run into situations where you question whether a test really guarantees success, or whether it's a meaningful test at all. For example, when testing an a + b function, I've sometimes wondered whether it's truly meaningful to feed in 1 and 1 and confirm that 2 comes out.
Are unit tests necessary?
Organizing the thoughts above, my conclusion is that unit tests aren't absolutely! necessary, but they feel like a kind of insurance within a project. Just as there's no such thing as a perfect project, putting mechanisms in place for problems isn't essential—but isn't it good to minimize problems and prepare for them?
Also, as I've been working on React projects lately, repeating the process of composing pages by assembling components, I've come to wonder whether I've been developing with my focus only on how components behave. I have a personal hope that, if writing unit tests were an available option during the work, I might break behavior down into finer pieces, modularize it, and think more carefully about the function of the logic (?).
What kind of unit tests?
If I were to write unit tests within a React project, the elements that come to mind are state management, hooks, API requests, and utility functions—these are what I aim to target with unit tests. Component rendering seems like an area prone to frequent changes, and along with parts that are hard to control, such as event handling, it's likely to be difficult to cover with unit tests. If rendering and event handling are verified with E2E tests, I think it could make up for what unit tests leave wanting.

Vitest?
I decided to adopt Vitest into the project to write unit tests. There were various pros and cons and comparisons between libraries, but here I'll just briefly summarize why I chose to adopt Vitest.
If it's a vite-based project, you can reuse the project's vite configuration as-is, reducing the overhead of introducing testing. The vite plugins you're already using work in the test environment as well, and the consistency between the dev server and the test environment helps reduce context-switching costs. On top of that, ESM-based execution, per-file parallelization, and HMR support bring performance benefits.
Vitest vs Jest
Before adopting Vitest, I briefly applied both test libraries to the current project and compared them.
The process of introducing Jest itself wasn't difficult, but applying it required adding extra dependencies.
- jest
- ts-jest
- @jest/globals
- @types/jest
It also requires adding a jest.config.json configuration for Jest to work.
In a project already using vite, adopting vitest itself was very simple—just installing the vitest module and running the tests. When additional configuration is needed, you can add the required settings via the tests option in vite.config.
Finally, after configuring a simple function to not use cache and running it 100 times to measure the time, I found roughly a 3x or greater difference in time.
Jest

Vitest

| Jest | Vitest | |
|---|---|---|
| dependency | ts-jest @jest/globals @types/jest | reuses the plugins set up in vite |
| config | requires adding a jest.config file | reuses vite.config |
| time (same function) | 1.429s | 427ms |
In conclusion
Since I'm still at the point before actually adopting Vitest and writing unit tests in the project, writing a section titled "conclusion" feels a bit awkward. When it comes to testing, far more thought and deliberation is needed than the narrow views I've laid out above. Even when I've occasionally talked with developers around me, we couldn't find an exact right answer—it felt more like a discussion where we were searching for the way out of a maze together. Still, even if we don't reach the right answer, I believe that simply talking together to find the best option for each situation is what lets us take on new challenges as we are now and get closer to building a better (?) project.

-How do you approach testing?-