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 renderersrc/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:
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:
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:
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:
// 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:
/* 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:
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:
{
"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:
{
"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:
// 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:
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:
{
"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:
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:
// 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:
{
"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):
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.*:
{
"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
cndari alias yang salah — pastikanutilsdicomponents.jsonmengarah ke@renderer/lib/utils, bukan@/lib/utils. Kalau salah, komponen akan error saat runtime. - Tailwind tidak aktif di renderer — pastikan plugin
tailwindcss()ada di bagianrenderer.plugins, bukan di level rootdefineConfig. - CLI Shadcn tidak mengenali project — ini terjadi kalau
vite.config.tstidak ada di root. File ini wajib ada meski isinya sama denganelectron.vite.config.ts. - TypeScript error pada
resolve— install@types/nodekalau muncul error di fungsiresolvedari paketpath.
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.







