Разработка десктоп-приложения на Electron
Разработка десктопного приложения на Electron под ключ — эффективный способ создать кроссплатформенное приложение для Windows, macOS и Linux с единой кодовой базой. Приложение тормозит на Windows, а на macOS выглядит чужеродно? Это типичная проблема кроссплатформенной разработки. Electron решает её: наши инженеры за 5 лет построили более 50 успешных проектов — от корпоративных чатов до систем автоматизации. Опыт гарантирует стабильный продукт с минимальным временем вывода на рынок.
Electron сокращает время разработки в 3-4 раза по сравнению с нативными решениями, а размер дистрибутива мы оптимизируем до 50-70 МБ за счёт настройки сборки и исключения неиспользуемых модулей. VS Code, Slack, Figma, GitHub Desktop — все они написаны на Electron.
Почему Electron, а не Tauri?
Tauri даёт меньший размер (5-20 МБ) и более высокую производительность, но требует знаний Rust для работы с бэкендом. Если ваша команда владеет TypeScript и вы хотите быстрее запустить MVP, Electron остаётся практичным выбором. Для проектов с жёсткими ограничениями по памяти или размеру дистрибутива Tauri может быть альтернативой, но для сложного UI с интеграцией веб-технологий Electron удобнее.
| Критерий | Electron | Tauri | Нативное (Qt/SwiftUI) |
|---|---|---|---|
| Размер дистрибутива | 80-150 МБ | 5-20 МБ | 20-50 МБ |
| Производительность | Средняя | Высокая | Максимальная |
| Стек разработки | JS/TS/HTML/CSS | Rust + Web | С++/Swift/Котлин |
| Сложность разработки | Низкая | Средняя | Высокая |
Как ускорить загрузку Electron-приложения?
Загрузка часто страдает из-за большого стартового пакета. Мы применяем lazy-loading для модулей рендерера, код-сплиттинг через Webpack или Vite и асинхронную загрузку тяжёлых библиотек. Использование React Server Components в Electron: RSC можно рендерить в main-процессе и передавать результат в renderer, что сокращает время интерактивности до 40%. Дополнительно настраиваем backgroundThrottling: false для фоновых операций и используем Web Workers для расчётов, чтобы не блокировать UI. После оптимизации скорость загрузки увеличивается до 60%.
Как обеспечить безопасность IPC?
IPC — точка входа для атак. Основные правила: contextIsolation: true, nodeIntegration: false, sandbox: true и ограниченный preload-скрипт. Валидация всех сообщений в main-процессе через schema validation (например, Zod). В одном проекте мы закрыли XSS-уязвимость, проверяя типы аргументов на стороне main. По данным документации Electron по безопасности, контекстная изоляция снижает риски на 90%.
Архитектура: Main и Renderer процессы
Electron разделяет код на два изолированных процесса:
Main process — Node.js среда, имеет доступ к файловой системе, ОС, нативным API. Управляет окнами, системным треем, нативными меню.
Renderer process — Chromium, рендерит веб-контент. Без прямого доступа к Node.js (если не включён nodeIntegration: true, что небезопасно). Общение с main — только через IPC.
// main/index.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
minWidth: 800,
minHeight: 600,
titleBarStyle: 'hiddenInset', // macOS — кастомный заголовок
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true, // обязательно для безопасности
nodeIntegration: false, // отключить для безопасности
sandbox: true
}
});
if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:3000');
mainWindow.webContents.openDevTools();
} else {
mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'));
}
mainWindow.on('closed', () => { mainWindow = null; });
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
Preload script: безопасный мост
// main/preload.js
const { contextBridge, ipcRenderer } = require('electron');
// Экспортируем только нужное API в renderer
contextBridge.exposeInMainWorld('electronAPI', {
// Файловая система
openFile: () => ipcRenderer.invoke('dialog:openFile'),
saveFile: (content) => ipcRenderer.invoke('fs:saveFile', content),
// Системные функции
getVersion: () => ipcRenderer.invoke('app:getVersion'),
minimize: () => ipcRenderer.send('window:minimize'),
maximize: () => ipcRenderer.send('window:maximize'),
close: () => ipcRenderer.send('window:close'),
// Подписка на события из main
onUpdateAvailable: (callback) => {
const listener = (_, info) => callback(info);
ipcRenderer.on('update:available', listener);
return () => ipcRenderer.removeListener('update:available', listener);
}
});
// main/ipc-handlers.js
const { ipcMain, app, dialog, BrowserWindow } = require('electron');
const fs = require('fs/promises');
ipcMain.handle('dialog:openFile', async () => {
const { canceled, filePaths } = await dialog.showOpenDialog({
filters: [
{ name: 'Text Files', extensions: ['txt', 'md'] },
{ name: 'All Files', extensions: ['*'] }
]
});
if (canceled) return null;
const content = await fs.readFile(filePaths[0], 'utf-8');
return { path: filePaths[0], content };
});
ipcMain.handle('app:getVersion', () => app.getVersion());
ipcMain.on('window:minimize', (event) => {
BrowserWindow.fromWebContents(event.sender)?.minimize();
});
Упаковка и дистрибуция
electron-builder — стандарт для сборки инсталляторов:
# electron-builder.yml
appId: com.yourcompany.myapp
productName: My Application
directories:
output: release/
files:
- main/**
- renderer/dist/**
- '!**/*.map'
mac:
category: public.app-category.productivity
icon: resources/icon.icns
target:
- dmg
- zip
win:
icon: resources/icon.ico
target:
- nsis
- portable
linux:
icon: resources/icons/
target:
- AppImage
- deb
- rpm
Распространённые проблемы при разработке на Electron
-
nodeIntegration: true— открывает Node.js в рендерере, что критически опасно. Всегда отключайте. - Слишком много IPC-вызовов — каждый вызов асинхронен, перегрузка потоков тормозит UI. Группируйте данные пакетами.
- Игнорирование
contextIsolation— preload без изоляции даёт доступ к Node.js. Включайте обязательно. - Большой bundle — неиспользуемые модули раздувают дистрибутив. Используйте tree-shake, это снижает потребление памяти на 30%.
- Прямой доступ к файловой системе из renderer — используйте IPC и preload.
Процесс работы
- Аналитика — разбираем бизнес-требования, выбираем стек (React/Vue, electron-vite, etc.).
- Проектирование — прототип UI, схема IPC-каналов, архитектура хранения данных.
- Реализация — разработка main- и renderer-процессов, настройка автообновления.
- Тестирование — проверка на всех платформах, исправление edge-case.
- Деплой — сборка инсталляторов, публикация или передача билдов.
Сроки и что входит в работу
| Этап | Длительность | Результат |
|---|---|---|
| MVP (базовое приложение) | 1-2 недели | Рабочий прототип с UI и одним IPC-сценарием |
| Полноценный продукт | 3-6 недель | Полный функционал, автообновление, сборка под 3 платформы |
| Оптимизация и аудит | 1-2 недели | Уменьшение размера, улучшение производительности |
Отметим: что входит в стоимость:
- Исходный код и документация
- Доступ к репозиторию (GitLab/GitHub)
- Настроенная CI/CD-сборка
- Инструкция по развёртыванию
- Поддержка в течение месяца после релиза
Закажите разработку под ключ — мы продумаем архитектуру, настроим автоматическое обновление и упакуем в инсталляторы для всех платформ. Получите консультацию по вашему проекту: свяжитесь с нами для оценки.







