DEV Community

Yuri Ramos
Yuri Ramos

Posted on

Why You Should Use npm (and Not pnpm... Yet) to Build Electron + React + Vite + Tailwind Apps

If you’ve ever wanted to build a desktop app using tools you already know from the web — React, Vite, Tailwind — you’re going to love this stack. I recently built a desktop tool using these exact technologies and it was smoother than I expected.

Here's the catch: use npm, not pnpm, especially when you're working with Electron. This is important if you're just starting out, which applies to me and probably to you too.

Let’s break down why.


First reason: The Stack

We’re talking about:

  • Electron – to create desktop apps with web tech
  • React – for building UI
  • Vite – for super-fast development
  • Tailwind CSS – for styling with ease
  • npm – to manage it all

You can spin all of this up in under 10 minutes. But the way you install and structure your dependencies matters. That’s where npm vs pnpm comes in.


Why you should use npm?

It’s Familiar

If you've done anything with JavaScript, you’ve used npm. The learning curve is basically zero.

It Plays Nice with Electron

Electron expects dependencies to be laid out in a certain way. When you package your Electron app for production, tools like electron-builder scan your node_modules to include required files.

With npm, that's straightforward. The node_modules folder is flat and easy to traverse.

But…


Why pnpm Can Cause Headaches with Electron

pnpm is great — it's fast, efficient, and deduplicates packages like a boss. But its performance gain comes from a symlinked folder structure, not the flat node_modules you're used to.

That’s where the pain begins.

The Problem:

Electron builders (like electron-builder) or runtime expectations often fail to properly resolve packages when they’re symlinked in the way pnpm sets them up. You might get weird runtime errors like:

  • Cannot find module 'electron' (i hate this one)
  • Module not found: path-to-your-lib
  • Your app builds but crashes on startup

Or even worse: everything works in dev, but breaks in production packaging

Unless you’re experienced with pnpm overrides or ready to tinker with buildResources, asarUnpack, and manual packaging configs — stick with npm to avoid that rabbit hole.


Okay, you convinced me to use npm. Now What?

You can scaffold the whole thing like this:

npm create vite@latest my-app -- --template react
cd my-app
npm install
npm install --save-dev electron concurrently wait-on electron-builder
Enter fullscreen mode Exit fullscreen mode

Set up your Electron main process (e.g. in electron/main.js), add Tailwind, wire up your package.json scripts:

"scripts": {
  "dev": "concurrently \"vite\" \"npm:electron-dev\"",
  "electron-dev": "wait-on http://localhost:5173 && electron .",
  "build": "vite build && electron-builder"
}
Enter fullscreen mode Exit fullscreen mode

Image description

Boom. You’re building desktop apps.


Final Thoughts

I really like pnpm, it’s fast, smart, and a great choice for most projects. But if you’re using Electron, especially with tools like electron-builder, do yourself a favor and stick with npm until you're comfortable with Electron’s internals.

This combo — Electron + React + Vite + Tailwind + npm — is powerful, fast to set up, and surprisingly stable. Whether you’re building an internal tool, a personal project, or your next big product — it just works.

Top comments (0)