BoxLang 🚀 A New JVM Dynamic Language Learn More...
Copyright Since 2005 ColdBox Platform by Luis Majano
and Ortus Solutions, Corp
www.coldbox.org | www.ortussolutions.com
Production-ready desktop application template built with ColdBox, BoxLang MiniServer, Electron, Vite, Alpine.js, and Bootstrap.
This template gives you a full desktop shell around a local BoxLang web application. Electron owns the native desktop lifecycle, while BoxLang MiniServer serves the app locally and the BrowserWindow loads it like a native desktop experience.
runtime/bin and runtime/lib
.boxlang-dev.json and .boxlang.json
app/
config/
electron/
handlers/
interceptors/
layouts/
models/ (includes ViteHelper.bx)
modules/
views/
public/
Application.bx
index.bxm
includes/
resources/
assets/
fonts/
js/
scss/
runtime/
Package.bx
VERSION
bin/
lib/
modules/
miniserver.json
forge.config.cjs
vite.config.mjs
app/electron/Main.js
Main.js wires the desktop modulesapp/electron/BoxLang.js starts BoxLang MiniServer using miniserver.json
public/
BrowserWindow
app/electron/Main.js: Electron bootstrap and module wiringapp/electron/BoxLang.js: MiniServer process management,
readiness checks, restart strategyapp/electron/AppMenu.js: app menuapp/electron/TrayMenu.js: tray integrationapp/electron/Shortcuts.js: global keyboard shortcutsapp/config/Coldbox.bx: ColdBox configurationapp/config/Router.bx: routespublic/Application.bx: web-facing bootstrappublic/index.bxm: default entry pointminiserver.json: MiniServer host, port, web root, and
dev runtime configruntime/Package.bx: MiniServer runtime packagervite.config.mjs: frontend asset build configforge.config.cjs: Electron Forge packaging configImportant: This template packages the BoxLang MiniServer runtime, but it does not package a JRE/JDK. Java 21+ must already be available on the host machine.
box install
npm install
npm run dev
This starts Vite and then launches Electron once the dev server is available.
Builds frontend assets and outputs them to public/includes/resources/:
npm run build
Runs the built application without development mode:
npm run prod
Generates platform-specific icon files from the PNG source iconset:
npm run generate:icons
This creates:
public/includes/icon.icns - macOSpublic/includes/icon.ico - Windowspublic/includes/icon.png - Generic fallbackPackages the application as a distributable for your platform:
# Current platform
npm run package
# Specific platform
npm run package:mac
npm run package:win
npm run package:linux
# Full packaging (downloads MiniServer runtime first)
npm run package:full
Downloads and extracts the BoxLang MiniServer runtime into
runtime/bin/ and runtime/lib/:
npm run package:miniserver
The version is controlled by .bvmrc.
This template uses Electron Forge for building and packaging desktop applications.
macOS (npm run package:mac)
dist/Electron/ directoryColdBox-BoxLang-Desktop-x.x.x-arm64.dmg, .zip
CSC_* or APPLE_*
environment variables
Windows (npm run package:win)
dist/Electron/ directory.exe, .msi,
.zip (Squirrel.Windows)public/includes/icon.ico (generated
by npm run generate:icons)
Linux (npm run package:linux)
dist/Electron/ directory.deb, .rpm,
.flatpak, .zip
public/includes/icon.png
forge.config.cjs controls all packaging behavior:
asar: Always false (MiniServer must be
spawned as a real filesystem executable)icon: Resolves to public/includes/icon
(Forge appends platform-specific extensions)makers: Array of active makers (dmg, zip for macOS;
squirrel, zip for Windows; deb, rpm, flatpak for Linux)postMake: Hook that copies unsigned-build helper
scripts into ZIP artifactsForge resolves icon filenames by appending platform-specific extensions:
| Platform | Icon File | Required | Generated by |
|---|---|---|---|
| macOS | public/includes/icon.icns | Yes | npm run generate:icons |
| Windows | public/includes/icon.ico | Yes | npm run generate:icons |
| Linux | public/includes/icon.png | No | Included in repo |
Missing icons will cause build failures on the target platform.
Icons are stored in public/includes/icon.iconset/:
public/includes/
└── icon.iconset/
├── icon_16x16.png
├── icon_32x32.png
├── icon_64x64.png
├── icon_128x128.png
├── icon_256x256.png
├── icon_512x512.png
└── icon_1024x1024.png
Run npm run generate:icons to create:
public/includes/icon.icns (macOS)public/includes/icon.ico (Windows)These generated files should be committed to your repository to ensure faster CI builds and consistent packaging.
miniserver.json
Controls the local development server:
{
"app": {
"name": "ColdBox BoxLang Desktop",
"logdir": "./logs"
},
"server": {
"port": 59700,
"host": "127.0.0.1",
"webroot": "./public"
},
"warmupUrl": "http://127.0.0.1:59700/",
"healthCheckUrl": "http://127.0.0.1:59700/health"
}
.boxlang-dev.json
Development-only overrides (loaded by miniserver.json):
{
"boxlang": {
"compiler": {
"nullChecking": true
},
"runtime": {
"allowImplicitStructKeyAccess": true
}
}
}
.boxlang.json
Production configuration (used in packaged builds):
{
"boxlang": {
"compiler": {
"nullChecking": false
}
}
}
The Vite pipeline compiles assets to public/includes/resources/:
resources/
└── assets/
├── fonts/ → public/includes/resources/fonts/
├── js/
│ └── app.js → public/includes/resources/app-[hash].js
└── scss/
└── app.scss → public/includes/resources/app-[hash].css
Use the ViteHelper to load assets automatically:
<!-- app/layouts/Main.bxm -->
<head>
#viteHelper.asset( "resources/assets/js/app.js" )#
#viteHelper.asset( "resources/assets/scss/app.scss" )#
</head>
The helper automatically:
public/includes/resources/
npm run dev # Start Vite dev server + Electron (development)
npm run build # Build Vite assets for production
npm run start # Start Electron only (assumes Vite already running)
npm run prod # Production build + production runtime config
npm run package # Package current platform (create installers/DMG)
npm run package:mac # Package macOS DMG + ZIP
npm run package:win # Package Windows installer + ZIP
npm run package:linux # Package Linux deb/rpm/flatpak + ZIP
npm run package:full # Download MiniServer runtime + package current platform
npm run generate:icons # Generate platform-specific icon files
# Terminal 1: Start development
npm run dev
# This starts:
# 1. Vite dev server at http://127.0.0.1:3000
# 2. BoxLang MiniServer at http://127.0.0.1:59700
# 3. Electron window loading http://127.0.0.1:59700
# Edit your .bxm templates or .bx handlers → immediate reload
# Edit your JS/SCSS in resources/assets/ → HMR updates in window
# Build Vite assets
npm run build
# Test production build locally
npm run prod
# Package for distribution
npm run package:full # If MiniServer runtime needs re-downloading
npm run package # If MiniServer runtime already packaged
Symptom: Electron window is blank or shows "Connection refused"
Likely Causes:
java --version
lsof -i :59700
npm run package:miniserver
Solutions:
# Verify Java is installed
java --version
# Kill process on port 59700
lsof -i :59700 | grep LISTEN | awk '{print $2}' | xargs kill -9
# Re-package MiniServer runtime
npm run package:miniserver
# Restart development
npm run dev
Symptom: runtime/bin/boxlang-miniserver:
Permission denied
Solution:
chmod +x runtime/bin/boxlang-miniserver
npm run dev
Symptom: "Fatal error: Unable to set icon"
during npm run package:win
Cause: public/includes/icon.ico missing
Solution:
npm run generate:icons
npm run package:win
Symptom: CSS/JS not loading in dev-mode window
Likely Causes:
Solutions:
# Ensure both servers are running
npm run dev
# In a separate terminal, verify Vite server
curl http://127.0.0.1:3000
# Check ViteHelper.bx is loaded in your layout
grep -r "include.*ViteHelper" app/
Symptom: Windows build fails with "fs.rmdir recursive not supported"
Cause: cross-zip (Forge dependency) requires Node.js 20 LTS; Node 22+ removed fs.rmdir
Solution:
# Use Node 20 LTS
nvm use 20
npm run package:win
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
robots.txt file due to web crawlers no longer needing complex ruleslib/modules folderlib folder to match the modern app template for consistencyserver.json to use /runtime/lib/coldbox/system/exceptions/ pathapp/config/Coldbox.bx
$
box install cbtemplate-boxlang-desktop