Shadcn/UI di Electron-Vite: Panduan Setup
TutorialJavaScriptFrontend#tutorial#react#javascript#frontend

Shadcn/UI di Electron-Vite: Panduan Setup

A
Abd. Asis
Bagikan:

Membangun aplikasi desktop dengan JavaScript sudah jauh lebih nyaman sejak Electron hadir. Tapi ada satu titik yang masih bikin frustasi: menyiapkan stack UI yang modern. Mengintegrasikan Shadcn/UI ke dalam project Electron-Vite butuh beberapa langkah ekstra yang tidak terdokumentasi di satu tempat — dan kalau salah urutan, CLI Shadcn akan mengeluh tidak menemukan framework yang didukung.

Artikel ini memandu proses setup dari awal: mulai membuat project Electron-Vite, menambahkan Tailwind CSS, mengonfigurasi TypeScript dengan benar, hingga komponen Shadcn pertama berjalan di window desktop.

Kenapa Electron-Vite, Bukan Electron Biasa?

Electron-Vite adalah build tool yang membungkus Vite di atas Electron. Dengan ini, kita mendapat Hot Module Replacement (HMR) untuk renderer process, konfigurasi terpadu untuk main, preload, dan renderer dalam satu file, serta build yang jauh lebih cepat dibanding setup Webpack klasik.

Struktur project Electron-Vite memisahkan tiga konteks dengan jelas:

  • src/main/ — Node.js process (akses sistem file, IPC)
  • src/preload/ — jembatan aman antara main dan renderer
  • src/renderer/ — UI React yang berjalan di Chromium

Pemisahan ini penting karena Shadcn/UI dan Tailwind hanya hidup di layer renderer — bukan di main process.

Membuat Project Electron-Vite Baru

Jalankan perintah scaffold resmi untuk membuat project baru:

BashBASH
npm create @quick-start/electron@latest my-desktop-app

Pilih template React dengan TypeScript saat prompt muncul. Setelah selesai, masuk ke folder dan install dependencies:

BashBASH
cd my-desktop-app
npm install
npm run dev

Window Electron akan terbuka dengan halaman default. Ini titik awal sebelum kita mulai konfigurasi.

Menambahkan Tailwind CSS ke Renderer

Shadcn/UI bergantung sepenuhnya pada Tailwind CSS untuk styling-nya. Install dua paket berikut:

BashBASH
npm install -D tailwindcss @tailwindcss/vite

Buka electron.vite.config.ts dan tambahkan plugin Tailwind hanya di bagian renderer — jangan di main atau preload karena keduanya berjalan di Node.js, bukan browser:

TypeScriptTYPESCRIPT
// electron.vite.config.ts
import { resolve } from 'path'
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  main: {
    plugins: [externalizeDepsPlugin()]
  },
  preload: {
    plugins: [externalizeDepsPlugin()]
  },
  renderer: {
    resolve: {
      alias: {
        '@renderer': resolve('src/renderer/src')
      }
    },
    plugins: [react(), tailwindcss()]
  }
})

Selanjutnya buka file CSS utama renderer di src/renderer/src/assets/main.css, tambahkan import Tailwind di baris paling atas:

CSSCSS
/* src/renderer/src/assets/main.css */
@import "tailwindcss";

Pastikan file ini sudah di-import di src/renderer/src/main.tsx. Kalau belum, tambahkan baris berikut di bagian atas file tersebut:

TypeScriptTYPESCRIPT
import './assets/main.css'

Konfigurasi TypeScript dan Path Alias

Ini bagian yang paling sering menyebabkan error saat inisialisasi Shadcn. CLI Shadcn membaca tsconfig.json dan vite.config.ts di root project untuk memvalidasi path alias. Ada dua hal yang perlu dikonfigurasi.

Menambahkan Path Alias di tsconfig

Buka tsconfig.node.json dan tambahkan paths di dalam compilerOptions:

{}JSON
{
  "extends": "@electron-toolkit/tsconfig/tsconfig.node.json",
  "include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*"],
  "compilerOptions": {
    "composite": true,
    "types": ["electron-vite/node"],
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/renderer/src/*"]
    },
    "moduleResolution": "bundler"
  }
}

Lakukan hal yang sama di tsconfig.json root:

{}JSON
{
  "files": [],
  "references": [
    { "path": "./tsconfig.node.json" },
    { "path": "./tsconfig.web.json" }
  ],
  "compilerOptions": {
    "composite": true,
    "types": ["electron-vite/node"],
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/renderer/src/*"]
    }
  }
}

Membuat vite.config.ts untuk CLI Shadcn

CLI Shadcn hanya mencari vite.config.ts atau vite.config.js di root project — bukan electron.vite.config.ts. Buat file baru vite.config.ts di root dengan menyalin isi dari electron.vite.config.ts:

TypeScriptTYPESCRIPT
// vite.config.ts
import { resolve } from 'path'
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  main: {
    plugins: [externalizeDepsPlugin()]
  },
  preload: {
    plugins: [externalizeDepsPlugin()]
  },
  renderer: {
    resolve: {
      alias: {
        '@renderer': resolve('src/renderer/src')
      }
    },
    plugins: [react(), tailwindcss()]
  }
})

File ini dibutuhkan agar npx shadcn init tidak mengeluh "a supported framework was not found".

Jangan lupa menginstal @types/node sebelum inisialisasi Shadcn — CLI membutuhkannya untuk resolver path: npm install -D @types/node

Inisialisasi Shadcn/UI

Setelah konfigurasi TypeScript dan Vite siap, jalankan inisialisasi Shadcn:

BashBASH
npx shadcn@latest init

CLI akan bertanya beberapa hal seperti style (gunakan "default") dan warna base. Setelah selesai, buka file components.json yang baru dibuat dan sesuaikan bagian aliases agar mengarah ke path renderer yang benar:

{}JSON
{
  "aliases": {
    "components": "@/components",
    "utils": "@renderer/lib/utils",
    "ui": "@/components/ui",
    "lib": "@renderer/lib",
    "hooks": "@renderer/hooks"
  }
}

Konfigurasi ini memastikan utilitas cn() dari Shadcn diimport dari alias @renderer yang sudah terdaftar di Vite — bukan dari @ yang mungkin tidak dikenali oleh TypeScript di konteks renderer.

Menambahkan dan Menggunakan Komponen Shadcn

Tambahkan komponen pertama dengan perintah berikut:

BashBASH
npx shadcn@latest add button

Shadcn akan menyalin file komponen ke src/renderer/src/components/ui/button.tsx. Buka src/renderer/src/App.tsx dan gunakan komponen tersebut:

TypeScriptTYPESCRIPT
// src/renderer/src/App.tsx
import { Button } from '@renderer/components/ui/button'
import { Badge } from '@renderer/components/ui/badge'

function App(): React.JSX.Element {
  return (
    <div className="flex flex-col items-center justify-center min-h-svh gap-4">
      <h1 className="text-2xl font-bold text-slate-800">Desktop App Siap</h1>
      <Badge variant="secondary">Electron + Vite + Shadcn</Badge>
      <Button variant="default" size="lg">
        Mulai Eksplorasi
      </Button>
    </div>
  )
}

export default App

Jalankan npm run dev dan window Electron akan menampilkan UI yang sudah distyling dengan Tailwind dan komponen Shadcn.

Di Tailwind v4, kursor button mengikuti default browser (panah biasa), bukan pointer. Ini perubahan desain yang disengaja — baca penjelasannya di dokumentasi Tailwind v4 Shadcn.

Menghindari Duplikasi Config Vite

Kita sekarang punya dua file config Vite: electron.vite.config.ts dan vite.config.ts. Ini bisa jadi sumber kebingungan saat project berkembang. Solusi yang lebih bersih: gunakan hanya vite.config.ts dan arahkan Electron-Vite untuk membacanya.

Update package.json untuk menambahkan flag --config di setiap script yang relevan:

{}JSON
{
  "scripts": {
    "dev": "electron-vite --config ./vite.config.ts dev",
    "start": "electron-vite --config ./vite.config.ts preview",
    "build:mac": "electron-vite --config ./vite.config.ts build && electron-builder --mac",
    "build:linux": "electron-vite --config ./vite.config.ts build && electron-builder --linux",
    "build:win": "npm run typecheck && electron-vite build && electron-builder --win"
  }
}

Update electron-builder.yml untuk mengecualikan vite.config.ts dari bundle aplikasi final (gantikan baris lama yang mengecualikan electron.vite.config):

YMYAML
files:
  - '!**/.vscode/*'
  - '!src/*'
  - '!vite.config.{js,ts,mjs,cjs}'
  - '!{.eslintcache,eslint.config.mjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'
  - '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'
  - '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}'

Terakhir, update tsconfig.node.json untuk menyertakan vite.config.ts menggantikan electron.vite.config.*:

{}JSON
{
  "include": ["vite.config.ts", "src/main/**/*", "src/preload/**/*"]
}

Setelah ini, electron.vite.config.ts bisa dihapus. Project tetap berjalan dengan satu file config yang konsisten.

Hal yang Perlu Diperhatikan

Beberapa gotcha yang sering muncul saat setup ini:

  • Import cn dari alias yang salah — pastikan utils di components.json mengarah ke @renderer/lib/utils, bukan @/lib/utils. Kalau salah, komponen akan error saat runtime.
  • Tailwind tidak aktif di renderer — pastikan plugin tailwindcss() ada di bagian renderer.plugins, bukan di level root defineConfig.
  • CLI Shadcn tidak mengenali project — ini terjadi kalau vite.config.ts tidak ada di root. File ini wajib ada meski isinya sama dengan electron.vite.config.ts.
  • TypeScript error pada resolve — install @types/node kalau muncul error di fungsi resolve dari paket path.

Kesimpulan

Stack Electron-Vite dengan Shadcn/UI memberi titik awal yang solid untuk membangun desktop app modern — UI yang accessible dan konsisten tanpa harus merancang komponen dari nol. Langkah yang paling krusial adalah konfigurasi path alias yang benar dan keberadaan vite.config.ts di root agar CLI Shadcn bisa bekerja. Dari sini, setiap komponen baru tinggal satu perintah npx shadcn@latest add jauhnya.

Referensi

  1. 1 Electron-Vite — Official Documentation
  2. 2 shadcn/ui — Instalasi di Vite
  3. 3 shadcn/ui — Perubahan di Tailwind v4
  4. 4 shadcn/shadcn-electron-app — Template Resmi di GitHub
Abd. Asis
Ditulis oleh
Abd. Asis

Software Developer dari Madura. Menulis tentang PHP, Laravel, dan pengembangan web modern dalam Bahasa Indonesia.