Set up environment
Before building the launcher, you need a working Node.js environment and an Electron project wired up with EML Lib.
Install Node.js
EML Lib requires Node.js v20 or later. Node.js v24 LTS is recommended.
- Go to the Node.js website and download the LTS installer.
- Run the installer and follow the instructions.
- Open a Command Prompt or PowerShell and verify:
node -v
# Should output v24.x.x or higherThe easiest way is to use Homebrew. If you do not have it:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" Then install Node.js:
brew install node@24
node -v
# Should output v24.x.x or higherUse fnm (Fast Node Manager):
curl -fsSL https://fnm.vercel.app/install | bash
source ~/.bashrc # or source ~/.zshrc
fnm install 24
fnm use 24
node -v
# Should output v24.x.x or higherInitialize the project
There are two ways to get started: using EML Template (recommended for beginners) or setting up the environment manually.
Option 1 — EML Template
EML Template is an Electron + Vite boilerplate pre-configured with TypeScript, SCSS, and electron-builder. IPC handlers, preload script, and EML Lib wiring are already in place. It is the fastest way to get a working launcher.
Go to the EML Template repository on GitHub.
Click “Use this template” > “Create a new repository”, or click “Fork”, to create your own copy.
Clone and install:
git clone https://github.com/YOUR_USERNAME/my-launcher.git cd my-launcher npm installOpen
electron/const.tsand set theADMINTOOL_URLconstant to your EML AdminTool URL (or your self-hosted manifest URL if you are not using AdminTool).Start the developer mode:
npm run dev
You can now move on to Frontend architecture.
Option 2 — Manual setup
npm create vite@latest my-launcher -- --template vanilla
cd my-launcher
npm install
npm install eml-lib
npm install electron electron-builder vite-plugin-electron --save-dev Create vite.config.js:
import { defineConfig } from 'vite'
import electron from 'vite-plugin-electron'
export default defineConfig({
plugins: [electron({ entry: 'electron/main.js' })]
}) Update package.json:
{
"name": "my-launcher",
"version": "1.0.0",
"main": "dist-electron/main.js",
"scripts": {
"dev": "vite",
"build": "vite build && electron-builder"
}
}npm create vite@latest my-launcher -- --template vanilla-ts
cd my-launcher
npm install
npm install eml-lib
npm install electron electron-builder vite-plugin-electron --save-dev Create vite.config.ts:
import { defineConfig } from 'vite'
import electron from 'vite-plugin-electron'
export default defineConfig({
plugins: [electron({ entry: 'electron/main.ts' })]
}) Update package.json:
{
"name": "my-launcher",
"version": "1.0.0",
"main": "dist-electron/main.js",
"scripts": {
"dev": "vite",
"build": "tsc && vite build && electron-builder"
}
} Note
Even in TypeScript, the main field must point to the compiled output (dist-electron/main.js), not the source .ts file.