Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Medinaallan/ContabilidadISV/llms.txt

Use this file to discover all available pages before exploring further.

The Electron packaging mode turns ContabilidadISV into a fully self-contained Windows desktop application. The compiled React SPA, the Express.js backend, and a bundled copy of Node.js are all packed into a single NSIS installer — no separate server, no IIS, no nginx. When a user double-clicks the installer, all three layers are installed together and the app launches directly from the Start Menu or desktop shortcut. The backend still requires a reachable SQL Server instance (local or network), but everything else ships inside the .exe.
If you need to deploy ContabilidadISV as a headless web service instead, see the Web Deployment guide.

Prerequisites

  • Windows 10 or Windows 11 build machine — the NSIS installer target (electron:build:win) only runs on Windows.
  • Node.js 16 or later — the root project, frontend/, and backend/ all require a modern Node.js runtime.
  • All npm dependencies installed — root, frontend, and backend packages must all be present before building:
npm install
npm run install-all
  • SQL Server (Express or full edition) accessible from the machine where the packaged app will run. See Database Configuration.

Development Mode with Electron

Running the app in development mode lets you iterate quickly — the React frontend has full hot-module replacement (HMR) and the Electron DevTools are always available.
1

Start the development environment

A single command starts all three services concurrently:
npm run electron:dev
Under the hood this runs:
concurrently
  "npm run dev:backend"          → Express on port 3002
  "npm run dev:frontend"         → Vite HMR on port 5174
  "node scripts/wait-for-services.js && electron ."
The wait-for-services.js script polls both URLs before launching the Electron window, so you never see a blank screen while services are still starting.
2

Open DevTools

Once the window is open press Ctrl + Shift + I (or F12) to open the Chromium DevTools panel. You can inspect React component state, monitor API network calls, and read backend stdout/stderr in the Console tab.
3

Edit and reload

Changes to frontend/src/ are reflected instantly via HMR. Changes to backend/ require restarting the backend process (Ctrl + C and re-run npm run electron:dev), or use npm run dev:backend separately if you have nodemon configured.

Building the Windows Installer

1

Install all dependencies

Make sure root, frontend, and backend node_modules are all present and up to date.
npm run install-all
2

Back up your development .env (recommended)

The build process copies backend/.env.production into the packaged app as .env. If you want to preserve your current development environment file, back it up first:
Copy-Item ".\backend\.env" ".\backend\.env.backup"
3

Run the Windows build command

npm run electron:build:win
This command chains four internal steps in sequence:
StepCommandWhat it does
1npm run build:frontendVite production build → frontend/dist/
2node scripts/copy-backend.jsCopies backend/ (minus node_modules, uploads, database, .env) to dist-electron/backend/, then runs npm install --production there
3node scripts/verify-build.jsAsserts that frontend/dist/index.html, backend/server.js, electron/main.js, and electron/preload.js all exist before invoking the packager
4electron-builder --winPackages everything into an NSIS installer
electron-builder needs permission to create symbolic links on Windows. Run your terminal as Administrator, or enable Developer Mode in Windows Settings → Privacy & Security → For Developers before executing this command. If you see Cannot create symbolic link: A required privilege is not held by the client, either option resolves it.
4

Locate the output files

After a successful build, dist-electron/ contains:
dist-electron/
├── Consolidación Contable Setup 1.0.0.exe   ← NSIS installer (~150-200 MB)
├── Consolidación Contable Setup 1.0.0.exe.blockmap
├── latest.yml
└── win-unpacked/
    ├── Consolidación Contable.exe            ← Portable executable (no install needed)
    └── resources/
        └── app.asar.unpacked/
            ├── backend/                      ← Express server (NODE_ENV=production)
            ├── frontend/dist/                ← Built React SPA
            └── electron/                     ← main.js + preload.js
Distribute Consolidación Contable Setup 1.0.0.exe to end users. The win-unpacked/ folder is a portable version useful for quick testing without running the installer.
5

Restore your development environment (if you backed it up)

Move-Item ".\backend\.env.backup" ".\backend\.env" -Force

electron-builder Configuration

The packager is configured via the "build" key in package.json. Key settings are shown below:
{
  "build": {
    "appId": "com.contabilidad.consolidacion",
    "productName": "Consolidación Contable",
    "copyright": "Copyright © 2025 Sistema Contable",
    "directories": {
      "output": "dist-electron",
      "buildResources": "build"
    },
    "files": [
      "electron/**/*",
      "frontend/dist/**/*",
      "!frontend/dist/**/*.map",
      "backend/**/*",
      "!backend/uploads/**/*",
      "!backend/database/**/*",
      "package.json"
    ],
    "asarUnpack": [
      "backend/**/*",
      "frontend/dist/**/*"
    ],
    "win": {
      "target": [{ "target": "nsis", "arch": ["x64"] }],
      "icon": "build/icon.png",
      "publisherName": "Sistema Contable"
    },
    "nsis": {
      "oneClick": false,
      "perMachine": false,
      "allowToChangeInstallationDirectory": true,
      "createDesktopShortcut": true,
      "createStartMenuShortcut": true,
      "shortcutName": "Consolidación Contable",
      "license": "LICENSE.txt"
    }
  }
}
Notable NSIS options:
OptionValueEffect
oneClickfalseDisplays the full installation wizard instead of silently installing
allowToChangeInstallationDirectorytrueLets the user choose the install path
perMachinefalseInstalls per-user (no Administrator rights needed by default)
createDesktopShortcuttrueAdds a shortcut to the user’s desktop automatically
createStartMenuShortcuttrueAdds an entry to the Start Menu
The asarUnpack option tells electron-builder to extract backend/ and frontend/dist/ outside the .asar archive. This is required because the Express server reads and writes files at runtime (uploads, logs) and cannot operate from within a read-only archive.

App Icon

The build system looks for the icon in the build/ directory at the project root. The Windows target uses build/icon.png (as declared in package.json). For best results, supply a multi-resolution .ico file and update the win.icon field accordingly.
1

Prepare the icon file

Create or obtain a square logo image at 1024 × 1024 px (PNG). Convert it to .ico format containing all required resolutions using a tool such as icoconvert.com or convertico.com. The .ico file should include layers at:16 × 16 · 32 × 32 · 48 × 48 · 64 × 64 · 128 × 128 · 256 × 256
2

Place the icon

Save the file as icon.ico inside the build/ directory:
ContabilidadISV/
└── build/
    └── icon.ico   ← place it here
Then update package.json to point to the .ico file:
"win": {
  "icon": "build/icon.ico"
}
3

Rebuild

Re-run npm run electron:build:win — the icon is embedded into the installer and the application .exe during packaging.

Security in Electron

ContabilidadISV follows the Electron security best practices:
FeatureSettingWhy it matters
contextIsolationenabledRenderer process JavaScript cannot access Node.js APIs directly
nodeIntegrationdisabledPrevents web content from calling require() or fs
Preload scriptelectron/preload.jsThe only bridge between the renderer and the main process
The preload script uses contextBridge.exposeInMainWorld to expose a minimal, curated API to the React frontend under window.electron:
// electron/preload.js (excerpt)
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electron', {
  getAppPath: () => ipcRenderer.sendSync('get-app-path'),
  versions: {
    node: process.versions.node,
    chrome: process.versions.chrome,
    electron: process.versions.electron
  },
  platform: process.platform,
  isElectron: true,
  env: {
    API_URL: 'http://localhost:3002',  // backend URL for the frontend
    NODE_ENV: process.env.NODE_ENV || 'production'
  }
});
The frontend reads window.electron.env.API_URL at startup to know which base URL to use when making API requests. In the packaged app this is always http://localhost:3002. See Environment Variables for how this is configured.
Never enable nodeIntegration: true in production builds. Doing so allows any JavaScript running in the renderer window (including injected third-party scripts) to execute arbitrary Node.js code with full filesystem and network access.

Estimated Installer Size

ArtifactApproximate Size
NSIS installer .exe150 – 200 MB
Installed application300 – 400 MB
The size is dominated by the Chromium rendering engine and the bundled Node.js runtime, both of which are included by Electron regardless of application size. The Express backend, React frontend, and their dependencies are comparatively small.

Troubleshooting

Root-level node_modules are missing. Run:
npm install
This installs electron, electron-builder, concurrently, and wait-on as listed in devDependencies.
Stale or mismatched node_modules across the three packages (root, frontend, backend) are the most common cause of cryptic build failures. Do a full clean-reinstall:
# Remove all node_modules directories
Remove-Item -Recurse -Force node_modules
Remove-Item -Recurse -Force frontend\node_modules
Remove-Item -Recurse -Force backend\node_modules

# Reinstall everything
npm install
npm run install-all
Then rebuild:
npm run electron:build:win
The Electron window loads before the Express backend has finished starting. In development mode this is handled by scripts/wait-for-services.js, but in the packaged app a different mechanism controls the timing.To diagnose:
  1. Open DevTools (Ctrl + Shift + I) — check the Console tab for network errors.
  2. Confirm the backend actually started by looking at %APPDATA%\Consolidación Contable\logs.
  3. Verify SQL Server is running and the connection string in backend/.env.production is correct.
Re-run the dev mode to reproduce the issue with live logs:
npm run electron:dev
The scripts/copy-backend.js step aborts if frontend/dist/ does not exist or backend/.env.production is missing.
# Build the frontend manually first
npm run build:frontend

# Verify .env.production exists
Get-ChildItem backend\.env*
backend/.env.production must exist and contain at least NODE_ENV=production and valid DB_* credentials before packaging. See Environment Variables.

Next Steps

Environment Variables

Configure backend/.env.production with the correct SQL Server credentials, JWT secret, and CORS origin before packaging.

Database Configuration

Set up SQL Server Express, create the ContabilidadISV database, and create the contabilidad_app user.

Security Configuration

Review JWT expiry, CORS policy, and Electron security flags before distributing to end users.

Web Deployment

Deploy the same stack as a headless Express + Vite web application instead.
Increment the "version" field in package.json before every distribution. electron-builder embeds the version number into the installer filename (Consolidación Contable Setup X.X.X.exe) and into latest.yml, which is used by the auto-updater to detect new releases.

Build docs developers (and LLMs) love