Node.js: O Guia Essencial Para Devs e Gestores
Node.js revolucionou o desenvolvimento backend com JavaScript. Descubra por que empresas como Netflix, PayPal e Uber confiam nesta tecnologia.
Descubra como Electron permite construir aplicativos desktop nativos para Windows, Mac e Linux usando HTML, CSS e JavaScript - a mesma stack que você já domina.
Equipe Arkanus
27/10/2025
Visual Studio Code, Slack, Discord, Figma, Notion - o que todos esses aplicativos têm em comum? Todos são construídos com Electron, o framework que permite criar aplicações desktop cross-platform usando tecnologias web que você já conhece.
Electron é um framework open-source criado pelo GitHub que permite construir aplicações desktop nativas usando HTML, CSS e JavaScript. Combina Chromium (engine de renderização do Chrome) com Node.js, dando acesso tanto a APIs web quanto a recursos nativos do sistema operacional.
┌─────────────────────────────────────┐
│ Sua Aplicação (HTML/CSS/JS) │
├─────────────────────────────────────┤
│ Chromium (Rendering) + Node.js │
├─────────────────────────────────────┤
│ Electron Framework │
├─────────────────────────────────────┤
│ Windows / macOS / Linux │
└─────────────────────────────────────┘
Chromium: Renderiza sua interface (como um navegador) Node.js: Acessa filesystem, processos, hardware Electron APIs: Bridge entre web e sistema nativo
Se você tem uma aplicação web, pode transformá-la em desktop app:
// main.js - Ponto de entrada Electron
const { app, BrowserWindow } = require('electron');
function createWindow() {
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
// Carregar app web local
win.loadFile('index.html');
// Ou carregar de URL
// win.loadURL('https://meuapp.com');
}
app.whenReady().then(createWindow);
Escreva uma vez, publique em:
# Build para todas plataformas
npm run build:win
npm run build:mac
npm run build:linux
Electron combina poder do navegador com Node.js:
// APIs Web (Chromium)
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
// APIs Node.js (filesystem, etc)
const fs = require('fs');
const data = fs.readFileSync('/path/file.txt', 'utf8');
// APIs Electron (nativas)
const { dialog, shell } = require('electron');
// Abrir diálogo de arquivo
const files = await dialog.showOpenDialog({
properties: ['openFile', 'multiSelections']
});
// Abrir arquivo externo
shell.openPath('/path/to/file');
Use ferramentas modernas:
// React
import React from 'react';
import ReactDOM from 'react-dom';
function App() {
return <h1>Meu App Electron + React</h1>;
}
ReactDOM.render(<App />, document.getElementById('root'));
// Hot reload com Vite
// TypeScript support
// CSS frameworks (Tailwind, etc)
// State management (Redux, Zustand)
Main Process (Node.js puro):
Renderer Process (Chromium):
// main.js (Main Process)
const { app, BrowserWindow, ipcMain } = require('electron');
let mainWindow;
app.whenReady().then(() => {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false // Segurança
}
});
mainWindow.loadFile('index.html');
});
// IPC: comunicação Main ↔ Renderer
ipcMain.handle('read-file', async (event, filepath) => {
return fs.readFileSync(filepath, 'utf8');
});
// renderer.js (Renderer Process)
// Não pode acessar Node.js diretamente por segurança
// Usa IPC para comunicar com Main Process
const conteudo = await window.electronAPI.readFile('/path/file.txt');
console.log(conteudo);
// preload.js (Bridge seguro)
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
readFile: (filepath) => ipcRenderer.invoke('read-file', filepath)
});
const fs = require('fs');
const path = require('path');
// Ler arquivo
const data = fs.readFileSync('/path/file.json', 'utf8');
const json = JSON.parse(data);
// Escrever arquivo
fs.writeFileSync('/path/output.txt', 'Conteúdo', 'utf8');
// Assistir mudanças
fs.watch('/path/directory', (eventType, filename) => {
console.log(`${filename} changed: ${eventType}`);
});
const { Notification } = require('electron');
const notificacao = new Notification({
title: 'Título',
body: 'Mensagem da notificação',
icon: '/path/icon.png'
});
notificacao.show();
notificacao.on('click', () => {
console.log('Notificação clicada');
});
const { Tray, Menu } = require('electron');
const tray = new Tray('/path/icon.png');
const contextMenu = Menu.buildFromTemplate([
{ label: 'Abrir', click: () => mainWindow.show() },
{ label: 'Configurações', click: openSettings },
{ type: 'separator' },
{ label: 'Sair', click: () => app.quit() }
]);
tray.setContextMenu(contextMenu);
tray.setToolTip('Meu App');
const { globalShortcut } = require('electron');
app.whenReady().then(() => {
// Ctrl+Shift+X
globalShortcut.register('CommandOrControl+Shift+X', () => {
console.log('Atalho ativado!');
mainWindow.show();
});
});
const { clipboard } = require('electron');
// Copiar texto
clipboard.writeText('Texto copiado');
// Ler texto
const text = clipboard.readText();
// Copiar imagem
const image = nativeImage.createFromPath('/path/image.png');
clipboard.writeImage(image);
const { dialog } = require('electron');
// Abrir arquivo
const result = await dialog.showOpenDialog({
title: 'Selecione arquivo',
filters: [
{ name: 'Imagens', extensions: ['jpg', 'png', 'gif'] },
{ name: 'Todos arquivos', extensions: ['*'] }
],
properties: ['openFile', 'multiSelections']
});
console.log(result.filePaths);
// Salvar arquivo
const savePath = await dialog.showSaveDialog({
title: 'Salvar como',
defaultPath: 'documento.txt',
filters: [
{ name: 'Text', extensions: ['txt'] }
]
});
// Message box
const response = await dialog.showMessageBox({
type: 'question',
buttons: ['Cancelar', 'Confirmar'],
title: 'Confirmação',
message: 'Tem certeza?'
});
if (response.response === 1) {
// Confirmar clicado
}
const { Menu } = require('electron');
const template = [
{
label: 'Arquivo',
submenu: [
{
label: 'Novo',
accelerator: 'CmdOrCtrl+N',
click: () => createNewDocument()
},
{
label: 'Abrir',
accelerator: 'CmdOrCtrl+O',
click: () => openFile()
},
{ type: 'separator' },
{
label: 'Sair',
accelerator: 'CmdOrCtrl+Q',
click: () => app.quit()
}
]
},
{
label: 'Editar',
submenu: [
{ role: 'undo', label: 'Desfazer' },
{ role: 'redo', label: 'Refazer' },
{ type: 'separator' },
{ role: 'cut', label: 'Cortar' },
{ role: 'copy', label: 'Copiar' },
{ role: 'paste', label: 'Colar' }
]
},
{
label: 'Ajuda',
submenu: [
{
label: 'Documentação',
click: async () => {
const { shell } = require('electron');
await shell.openExternal('https://docs.meuapp.com');
}
}
]
}
];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
Atualizações automáticas:
const { autoUpdater } = require('electron-updater');
autoUpdater.checkForUpdatesAndNotify();
autoUpdater.on('update-available', () => {
dialog.showMessageBox({
type: 'info',
title: 'Atualização disponível',
message: 'Uma nova versão está disponível. Baixando...'
});
});
autoUpdater.on('update-downloaded', () => {
dialog.showMessageBox({
type: 'info',
title: 'Atualização pronta',
message: 'Reinicie para aplicar a atualização.',
buttons: ['Reiniciar', 'Mais tarde']
}).then((result) => {
if (result.response === 0) {
autoUpdater.quitAndInstall();
}
});
});
npx create-react-app meu-app
cd meu-app
npm install --save-dev electron electron-builder concurrently wait-on
# package.json
{
"main": "public/electron.js",
"scripts": {
"electron:dev": "concurrently \"BROWSER=none npm start\" \"wait-on http://localhost:3000 && electron .\""
}
}
vue create meu-app
cd meu-app
vue add electron-builder
npm run electron:serve
npm install --save-dev electron electron-builder electron-is-dev
# Use next export para build estático
CLI oficial:
npx create-electron-app meu-app
cd meu-app
npm start
# Build
npm run make
Electron apps podem ser vulneráveis se não seguir best practices:
webPreferences: {
contextIsolation: true, // ✅ Sempre true
nodeIntegration: false, // ✅ Sempre false
preload: path.join(__dirname, 'preload.js')
}
// ❌ Nunca
const data = JSON.parse(untrustedInput);
eval(untrustedCode);
// ✅ Sempre valide
const data = safeParse(input);
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'">
// Renderer não deve ter Node.js direto
nodeIntegration: false
// preload.js - Bridge seguro
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('api', {
// Exponha apenas o necessário
saveFile: (data) => ipcRenderer.invoke('save-file', data),
loadFile: () => ipcRenderer.invoke('load-file')
});
// Carregue janelas sob demanda
let settingsWindow = null;
function openSettings() {
if (settingsWindow) {
settingsWindow.focus();
return;
}
settingsWindow = new BrowserWindow({ width: 600, height: 400 });
settingsWindow.loadFile('settings.html');
settingsWindow.on('closed', () => {
settingsWindow = null;
});
}
win.webContents.setBackgroundThrottling(false);
// Disable para apps que rodam em background
Renderização em background:
const { BrowserWindow } = require('electron');
const win = new BrowserWindow({
width: 800,
height: 600,
show: false,
webPreferences: {
offscreen: true
}
});
win.webContents.on('paint', (event, dirty, image) => {
// Processar frame
});
// package.json
{
"build": {
"appId": "com.arkanus.meuapp",
"productName": "Meu App",
"directories": {
"buildResources": "assets"
},
"files": [
"dist/**/*",
"node_modules/**/*",
"package.json"
],
"win": {
"target": ["nsis", "portable"],
"icon": "assets/icon.ico"
},
"mac": {
"target": ["dmg", "zip"],
"icon": "assets/icon.icns",
"category": "public.app-category.productivity"
},
"linux": {
"target": ["AppImage", "deb", "rpm"],
"icon": "assets/icon.png",
"category": "Utility"
}
},
"scripts": {
"build": "electron-builder",
"build:win": "electron-builder --win",
"build:mac": "electron-builder --mac",
"build:linux": "electron-builder --linux"
}
}
macOS:
export CSC_LINK=/path/certificate.p12
export CSC_KEY_PASSWORD=password
npm run build:mac
Windows:
export CSC_LINK=/path/certificate.pfx
export CSC_KEY_PASSWORD=password
npm run build:win
Editores de Código: VS Code, Atom Comunicação: Slack, Discord, Microsoft Teams Design: Figma (desktop), InVision Produtividade: Notion, Obsidian, Todoist Desenvolvimento: Postman, GitKraken, MongoDB Compass Streaming: OBS Studio, Streamlabs
Electron:
Tauri:
NW.js:
PWA:
Electron democratizou desenvolvimento desktop. Desenvolvedores web podem criar aplicações desktop nativas profissionais sem aprender tecnologias nativas específicas de cada plataforma.
Vantagens: ✅ Web technologies: HTML/CSS/JS que você conhece ✅ Cross-platform: Windows, Mac, Linux com um código ✅ Acesso nativo: Filesystem, notificações, hardware ✅ Ecosystem: React, Vue, frameworks modernos ✅ Rápido desenvolvimento: Reutilize código web
Desvantagens: ❌ Bundle size: Apps grandes (70MB+ base) ❌ Memória: Chromium consome RAM ❌ Startup: Mais lento que nativo puro
Na Arkanus, usamos Electron para:
Se você precisa transformar sua aplicação web em desktop, ou criar uma nova ferramenta desktop cross-platform, Electron é uma ótima escolha - e podemos ajudar.
Quer criar um aplicativo desktop com Electron? Nossa equipe domina web technologies e Electron. Fale conosco.

Equipe Arkanus
Equipe Arkanus escreve sobre tecnologia, transformação digital e engenharia de software na Arkanus.
Node.js revolucionou o desenvolvimento backend com JavaScript. Descubra por que empresas como Netflix, PayPal e Uber confiam nesta tecnologia.
Descubra por que React é a biblioteca mais popular para criar interfaces de usuário modernas e como ela pode transformar seus projetos web.
Entenda como TypeScript adiciona segurança de tipos ao JavaScript, reduzindo bugs e aumentando a produtividade em projetos de larga escala.