Migrating from Electron
VeloxKit targets Electron developers directly. This guide maps Electron concepts and APIs to their VeloxKit equivalents.
You don't need to rewrite your entire app at once. VeloxKit supports a side-by-side migration — run both apps from the same codebase during transition.
What changes
| Electron | VeloxKit | Notes |
|---|---|---|
BrowserWindow | veloxWindow | Similar API, no main/renderer split |
ipcMain / ipcRenderer | Not needed | No process boundary |
contextBridge | Not needed | JS runs in the same process as native APIs |
app.getPath() | fs.appDataDir() | — |
shell.openExternal() | Not yet available | Open a GitHub issue if you need this |
dialog.showOpenDialog() | dialog.openFile() | — |
electron-store | db (SQLite) or @velox/store | More powerful, SQL |
node-fetch | network.fetch() | — |
require('fs') | fs from veloxkit | — |
Notification | notification | — |
clipboard | clipboard (text only) | Images not yet supported |
nativeTheme | @velox/design useTheme() | System dark mode detection |
safeStorage | credentials or @velox/keychain | OS keychain |
autoUpdater | updater | Ships via GitHub Releases |
The big difference: no process split
Electron has a main process and renderer processes. IPC is required to cross the boundary. VeloxKit has one process — your React code and native APIs run together:
// Electron — renderer process, needs IPC
window.electron.ipcRenderer.invoke('read-file', path)
// VeloxKit — direct call, no IPC
const content = await fs.readText(path)This eliminates the entire preload.js / contextBridge pattern.
Window management
// Electron
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 1200, height: 800 })
win.loadFile('index.html')
// VeloxKit — veloxkit.config.ts
window: {
width: 1200,
height: 800,
}Multiple windows:
// VeloxKit
import { veloxWindow } from 'veloxkit'
function openPreferences() {
veloxWindow.create({
component: PreferencesWindow,
title: 'Preferences',
width: 600,
height: 500,
})
}File dialogs
// Electron
const { dialog } = require('electron')
const result = await dialog.showOpenDialog({ properties: ['openFile'] })
const filePath = result.filePaths[0]
// VeloxKit
import { dialog } from 'veloxkit'
const filePath = await dialog.openFile()Storing data
// Electron + electron-store
const Store = require('electron-store')
const store = new Store()
store.set('theme', 'dark')
const theme = store.get('theme')
// VeloxKit — use db directly
db.execute("INSERT OR REPLACE INTO settings VALUES ('theme', 'dark')")
const theme = db.query("SELECT value FROM settings WHERE key = 'theme'")[0]?.valueOr use @velox/store for a React-hook-based key-value store:
import { createStore } from '@velox/store'
const useSettings = createStore('settings', { theme: 'dark' })
// In a component:
const { state, set } = useSettings()
set({ theme: 'light' })Menu bar / tray
Tray support is not yet implemented. Track it in the GitHub issues if you need it.
The recommended pattern for now is using a system notification to bring the window to the foreground:
// Workaround — bring window to foreground
veloxWindow.show()
veloxWindow.focus()React migration
If your Electron app already uses React, migration is mostly:
- Replace
react-domrendering withcreateApp - Replace DOM-dependent libraries with VeloxKit equivalents
- Replace
window,document,localStoragewith VeloxKit APIs - Remove IPC code — call native APIs directly
- Replace
electron-*packages withveloxkitequivalents
// Before (Electron + React DOM)
import ReactDOM from 'react-dom/client'
ReactDOM.createRoot(document.getElementById('root')!).render(<App />)
// After (VeloxKit)
import { createApp } from 'veloxkit'
createApp({ component: App })What doesn't migrate
- Browser DevTools extensions — use CDP via
veloxkit dev --inspectinstead <webview>tag — VeloxKit doesn't embed a browser;openURLis not yet available — open a GitHub issue if you need it- Node.js
require()— use the VeloxKit binding equivalents - Electron-specific npm packages (
electron-updater,electron-builder) — replaced byveloxkit
Performance comparison
Migrating a typical Electron app to VeloxKit typically yields:
- Cold startup: 800ms → ~50ms (~16× faster)
- Binary size: 130MB → ~20MB (~6.5× smaller)
- Idle memory: ~100MB → ~18MB (~5.5× less)
These are real measurements on a notes-style app. Results vary by app complexity.