Lewati ke konten
RazinSaid

Menyimpan Data Lokal di Aplikasi Electron (electron-store & SQLite)

RS
Razin Said
7 menit baca
Bagian 6 dari 12 · Seri Belajar Electron dari Nol sampai Mahir

Hampir semua aplikasi butuh nyimpen data lokal. Pengaturan tema, ukuran window terakhir, daftar tugas, sampai catatan pengguna—semuanya harus tetap ada walaupun aplikasinya udah ditutup. Untungnya, di Electron kamu punya beberapa cara buat ngelakuin ini tanpa perlu server. Kita bakal fokus ke dua pilihan yang paling sering dipakai, sekalian ngebahas kapan masing-masing paling cocok. Satu hal dulu: kalau kamu butuh baca atau nulis file mentah lewat dialog, mending mampir dulu ke bab mengakses file & dialog sistem.

Pilihan menyimpan data (ringan vs terstruktur)

Aturannya sebenarnya gampang banget. Kalau datamu kecil dan cuma berupa pengaturan, pakai yang ringan. Tapi kalau datanya banyak, saling nyambung, dan perlu dicari atau diurutkan, baru deh pakai database.

Dua opsi yang bakal kita pakai di sini:

  • electron-store buat data dan pengaturan ringan. Isinya disimpan sebagai satu file JSON. Pas banget buat preferensi pengguna, token kecil, atau status terakhir aplikasi.
  • better-sqlite3 buat data yang terstruktur dan jumlahnya gede. Ini database SQLite yang jalan langsung di dalam aplikasi. Cocok kalau kamu butuh tabel, relasi, filter, sampai ribuan baris.

Dua-duanya jalan di main process, bukan di renderer—dan ini penting banget. Main process punya akses penuh ke Node.js dan ke disk. Sementara renderer (yang megang UI) sebaiknya nggak nyentuh file sistem secara langsung, demi keamanan. Nanti kita lihat gimana UI ngambil datanya lewat jembatan IPC.

electron-store: cepat buat pengaturan

Buat kebutuhan ringan, electron-store ini pilihan paling cepet. Nggak ada konfigurasi yang ribet. Pasang dulu paketnya:

npm install electron-store

Habis itu, bikin satu instance store di main process. Kamu bisa nyimpen, baca, dan hapus nilai cuma pakai tiga method utama.

// main.js (proses main)
import Store from 'electron-store';

const store = new Store();

// menyimpan nilai
store.set('tema', 'gelap');
store.set('window.lebar', 1024);

// membaca nilai (dengan default kalau belum ada)
const tema = store.get('tema', 'terang');

// menghapus nilai
store.delete('window.lebar');

Coba perhatiin window.lebar tadi. Kamu bisa pakai notasi titik buat bikin objek bersarang tanpa ribet. Store-nya bakal otomatis nyimpen strukturnya ke JSON.

Kamu juga bisa ngasih skema awal biar ada nilai default sekaligus validasi tipe:

const store = new Store({
  defaults: {
    tema: 'terang',
    notifikasi: true,
  },
});

Dengan begini, pas aplikasi pertama kali jalan, nilai default-nya udah langsung ada. Kamu nggak perlu repot-repot ngecek datanya kosong atau nggak.

Kelebihan utama electron-store jelas ada di kesederhanaannya. Tapi karena isinya cuma satu file JSON, dia kurang cocok buat data yang gede. Bayangin baca file 50 MB cuma buat ngambil satu nilai—jelas boros banget. Nah, di sinilah SQLite mulai masuk.

Datanya disimpan di mana? (userData)

Pertanyaan yang sering muncul: file-nya disimpen di mana sih? Electron punya folder khusus per aplikasi yang aman dan nggak bakal ketimpa pas aplikasi di-update. Lokasinya bisa kamu ambil lewat app.getPath('userData').

import { app } from 'electron';

console.log(app.getPath('userData'));
// Windows: C:\Users\<nama>\AppData\Roaming\<NamaApp>
// macOS:   ~/Library/Application Support/<NamaApp>
// Linux:   ~/.config/<NamaApp>

electron-store otomatis naruh file-nya di folder ini, jadi kamu nggak perlu ngatur path sendiri. Kalau buat SQLite, mendingan kamu bikin file database-nya di folder yang sama juga—biar konsisten dan kebawa per pengguna.

Folder ini dipilih bukan tanpa alasan, lho. Lokasinya bisa ditulisin tanpa butuh hak admin, kepisah dari folder instalasi, dan tetap aman antar update. Jadi jangan simpan data di folder instalasi aplikasi ya, soalnya di banyak sistem folder itu cuma bisa dibaca doang.

SQLite (better-sqlite3): buat data yang lebih besar

Begitu datamu mulai berubah jadi daftar panjang dengan banyak kolom, saatnya mikirin database. Contohnya aplikasi catatan yang punya ribuan entri, atau aplikasi keuangan dengan transaksi yang seabrek. Nyari dan ngurutin data kayak gitu di JSON bakal lambat dan bikin repot.

better-sqlite3 jadi pilihan favorit banyak orang soalnya API-nya sinkron dan ngebut. Kamu nulis query kayak manggil fungsi biasa aja, tanpa await yang bertebaran di mana-mana. Pasang dulu:

npm install better-sqlite3

Terus buka database-nya dan bikin tabel di main process:

// main.js (proses main)
import path from 'node:path';
import { app } from 'electron';
import Database from 'better-sqlite3';

const dbPath = path.join(app.getPath('userData'), 'data.db');
const db = new Database(dbPath);

db.exec(`
  CREATE TABLE IF NOT EXISTS catatan (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    judul TEXT NOT NULL,
    isi TEXT,
    dibuat INTEGER
  )
`);

Kalau tabelnya udah jadi, query-nya ringkas kok. Pakai prepare buat bikin statement, terus tinggal jalanin. Satu hal: selalu pakai parameter (tanda ?), jangan pernah nyambung string mentah-mentah, biar aman dari SQL injection.

// menambah data
const tambah = db.prepare(
  'INSERT INTO catatan (judul, isi, dibuat) VALUES (?, ?, ?)'
);
tambah.run('Belajar Electron', 'Catatan hari ini', Date.now());

// mengambil banyak baris
const semua = db.prepare('SELECT * FROM catatan ORDER BY dibuat DESC').all();

// mengambil satu baris
const satu = db.prepare('SELECT * FROM catatan WHERE id = ?').get(1);

// menghapus
db.prepare('DELETE FROM catatan WHERE id = ?').run(1);

Ada satu hal yang wajib kamu tahu: better-sqlite3 itu native module. Maksudnya, dia punya bagian yang dikompilasi khusus buat versi Node tertentu. Masalahnya, versi Node yang ada di dalam Electron biasanya beda sama Node di sistemmu. Makanya, modul ini perlu di-rebuild dulu biar cocok sama Electron.

Cara paling gampang ya pakai tool resminya:

npm install --save-dev @electron/rebuild
npx electron-rebuild

Jalanin perintah ini tiap kali kamu ganti versi Electron atau masang native module baru. Kalau kelupaan, siap-siap ketemu error "was compiled against a different Node.js version" pas aplikasinya dijalanin.

Mengakses data dari UI lewat IPC

Karena store dan database-nya hidup di main process, halaman UI nggak bisa manggil mereka secara langsung. Jembatannya adalah IPC. Kalau kamu belum ngeh sama polanya, baca dulu bab IPC di Electron.

Intinya gini: main daftarin handler, renderer manggil handler itu, terus hasilnya dikirim balik. Ini contoh singkatnya buat ngambil daftar catatan.

// main.js
import { ipcMain } from 'electron';

ipcMain.handle('catatan:ambil-semua', () => {
  return db.prepare('SELECT * FROM catatan ORDER BY dibuat DESC').all();
});

ipcMain.handle('catatan:tambah', (event, judul, isi) => {
  const stmt = db.prepare(
    'INSERT INTO catatan (judul, isi, dibuat) VALUES (?, ?, ?)'
  );
  const info = stmt.run(judul, isi, Date.now());
  return info.lastInsertRowid;
});

Di file preload, kamu buka pintu kecil yang aman menuju fungsi-fungsi tadi:

// preload.js
import { contextBridge, ipcRenderer } from 'electron';

contextBridge.exposeInMainWorld('dataApi', {
  ambilSemua: () => ipcRenderer.invoke('catatan:ambil-semua'),
  tambah: (judul, isi) => ipcRenderer.invoke('catatan:tambah', judul, isi),
});

Nah, sekarang dari kode UI kamu tinggal manggil kayak fungsi biasa:

// renderer (kode halaman)
const daftar = await window.dataApi.ambilSemua();
await window.dataApi.tambah('Judul baru', 'Isi catatan');

Pola kayak gini bikin renderer tetap "bego" soal database. UI cuma minta data terus nerima hasilnya. Semua logika penyimpanan tetap ngumpul di main—jadinya lebih rapi dan lebih aman.

Tips: jangan simpan rahasia sebagai teks polos

Satu peringatan penting nih. Baik electron-store maupun file SQLite biasa itu nyimpen isinya sebagai teks polos di disk. Artinya, siapa pun yang buka folder userData bisa baca isinya. Jadi jangan sekali-kali naruh password, access token, atau API key mentahan di situ.

Beberapa cara aman buat nyimpen data sensitif:

  • Pakai API enkripsi bawaan Electron, yaitu modul safeStorage, buat ngenkripsi nilai sebelum disimpan. Modul ini manfaatin mekanisme keamanan dari sistem operasi.
  • Buat kredensial yang penting, mending simpan di keychain atau credential manager OS lewat library khusus, bukan di file aplikasi.
  • Kalau cuma butuh enkripsi ringan di file store, electron-store punya opsi encryptionKey. Tapi inget ya, ini lebih ke ngehalangin orang iseng yang mau ngintip aja, bukan pengamanan tingkat tinggi—soalnya kuncinya tetap nyimpen di dalam aplikasi.

Intinya, anggap aja disk pengguna itu bisa dibaca orang lain. Data biasa simpan apa adanya, tapi data rahasia wajib kamu lindungi.

Kesimpulan

Nyimpen data lokal di Electron sebenarnya nggak ribet asal kamu milih tool yang pas. Pakai electron-store buat pengaturan dan data kecil yang berbentuk JSON. Sedangkan better-sqlite3 buat data yang gede, terstruktur, dan perlu dicari-cari. Simpan semuanya di folder userData, taruh logikanya di main process, dan sambungin ke UI lewat IPC. Oh iya, jangan lupa rebuild native module tiap habis ganti versi Electron.

Sekarang aplikasimu udah bisa nyimpen data dengan rapi. Langkah selanjutnya? Mastiin aplikasi itu aman dipakai. Lanjut aja ke bab keamanan Electron, dan sempetin juga balik ke seri Belajar Electron buat lihat gambaran utuh perjalanannya.

Bagikan: XWhatsAppFacebookLinkedIn

Artikel terkait