Desktop Development for the Web Developer - Part 1

vite, vue 3, electron, and tailwind for desktop development

So many times as a web app developer I've been curious about the desktop landscape. My day-to-day work is completely reliant on desktop apps on MacOS. It would be great to be able to quickly make high quality desktop apps.

Unfortunately, at least in my experience, every time I try to get a feel for the technologies in desktop app development I'm left frustrated. There are some solid technologies like Java and C# that offer a pretty nice setup, but good luck making something engaging for the user. MacOS offers Cocoa/Objective C and Swift which is nice. But now you are mostly stuck with an interface builder and constantly jumping back and forth tying UI code to app code. Also, all this is fine but what if you want to build once but deploy to all major OS's?

It is just... frustrating. Maybe it is my personal expectations on what coding something should feel like but the options are kind of a let-down.

This all led me back to electron. I say "back" because it isn't completely new. And I'm sure you have heard the debates on electron based apps. But in 2021 being able to pair something like Vue or React with Tailwind CSS gives me something to get excited about. Hot module replacement, lightning fast dev builds, familiar technologies... Now I can put more energy into the app's code instead of some clunky work-flow.

Let's dive in.


We are going to do this in a few parts. At its heart this setup is just a web app.

By now I'm sure that you have heard the debates on making desktop apps with web technologies. Honestly, this post isn't trying to answer to that. There is no right answer. If you clicked through to read this then you have some interest in the stack, so let's build something cool.

Vue via Vite

We'll start by using Vite to install Vue as the base of our app.

➜ yarn create @vitejs/app

Run through the prompts and pick vue as the template to use and name it vvte-qs. This will create the template to start the project with. After that is done make your project the working directory, run yarn to install all dependencies and run the "dev" script to run the project in dev mode:

cd vvte-qs && yarn && yarn dev

You should end up seeing something either identical or very similar to this:

Vue running on the command line

If we go the browser and go to localhost:3000 we should see:

Vue running in the browser with Vite

Perfect! That was easy.

A Tailwind UI

Now that we have base for our app, let's bring in Tailwind CSS to build the UI. I personally am always underwhelmed with UI offerings for native app development. It is so hard to find a package that you are going to want to invest in that won't result with a UI that looks like a CS 101 project.

Ultimately what I want in a UI framework/library is a programatic approach with the ability to make something that looks really cool. Having a seperate piece of software to build out the UI and then stitch things together with code is a real bummer to me. For something like game development, I get it. How else would you do that. But for application development, it is just too much.

Say what you will about CSS/HTML but it is actually pretty great at making it easy to build out a UI. Enter Tailwind CSS. What I love about Tailwind is it leverages the component based UI architecture we will be building in Vue. You can build out some really engaging work by just putting Tailwind classes directly in your HTML. It will really encourage you to keep things DRY by reusing entire components instead of CSS classes. It is great.

To add Tailwind as a dependency:

➜ yarn add --dev tailwindcss@latest postcss@latest autoprefixer@latest @tailwindcss/jit

Next, generate your tailwind.config.js and postcss.config.js files:

➜ npx tailwindcss init -p

We'll need to add the following to the postcss.config.js to get all the Tailwind JIT benefits:

// postcss.config.js
module.exports = {
  plugins: {
    '@tailwindcss/jit': {},
    autoprefixer: {},

And then the following to the purge property in the tailwind.config.js config to purged what is unused from the build:

// tailwind.config.js
module.exports = {
  purge: [
  theme: {
    // ...
  // ...

We are going to need a place to import tailwind into our app:

➜ touch src/assets/index.css

Then open the file and add:

@tailwind base;
@tailwind components;
@tailwind utilities;

Save that and include your css in your main entry point for main.js.

import { createApp } from 'vue'
import App from './App.vue'
import './assets/index.css'


Now if you we run:

yarn dev

we get:

Show Vite running Vue with Tailwind

Pretty underwhelming? Ha, well you are right. Tailwind is a utility UI tool so we are going to have to utilize its classes to see all it can do.


Now we have a great base to start our app. Nothing really custom yet, but we'll get to that.


github repo - part 1