Lemonade provides an Electron-compatible API layer for web-based applications, allowing Electron apps to run in a browser environment with minimal modifications.
Lemonade mimics Electron's API structure and provides browser-based implementations of common Electron modules. This allows developers to write code that works in both Electron and web environments.
app.getName()/app.setName()- Get/set application nameapp.getVersion()- Get application versionapp.getPath(name)- Get special directories (home, appData, userData, temp, downloads, documents, desktop)app.isReady()/app.whenReady()- Check application ready stateapp.quit()/app.exit()- Exit applicationapp.relaunch()- Reload the applicationapp.getLocale()- Get user locale
- Constructor with options (width, height, title, icon, resizable, etc.)
loadURL(url)- Load a URL (with proxy support)loadFile(path)- Load a local fileshow()/hide()- Show/hide windowminimize()/maximize()- Minimize/maximize windowclose()/destroy()- Close windowsetTitle(title)/getTitle()- Window titlesetSize(width, height)/getSize()- Window sizesetPosition(x, y)/getPosition()- Window positioncenter()- Center window on screensetFullScreen(flag)/isFullScreen()- Fullscreen mode- Event listeners:
on(),once(),removeListener() - Events:
close,closed,show,hide,focus,blur,maximize,minimize
showOpenDialog(options)- File/directory pickershowSaveDialog(options)- Save file dialogshowMessageBox(options)- Message box with buttonsshowErrorBox(title, content)- Error alert
openExternal(url)- Open URL in default browseropenPath(path)- Open file/directoryshowItemInFolder(path)- Show file in foldermoveItemToTrash(path)- Move to trashbeep()- Play system beep sound
readText()/writeText(text)- Text operationsreadHTML()/writeHTML(html)- HTML operationsreadImage()/writeImage(image)- Image operationsclear()- Clear clipboard- Supports async clipboard API
send(channel, ...args)- Send messageinvoke(channel, ...args)- Request/response patternon(channel, listener)- Listen for messagesonce(channel, listener)- Listen onceremoveListener(channel, listener)- Remove listener
request(url, options)- Make HTTP requestfetch(url, options)- Fetch API wrapperisOnline()- Check online status- Supports timeout and abort signals
getPrimaryDisplay()- Get primary display infogetAllDisplays()- Get all displaysgetDisplayNearestPoint(point)- Find display at point- Display info includes: bounds, workArea, size, scaleFactor, rotation
process.platform- OS platform (always "linux" in WebContainer)process.arch- Architecture (x64)process.versions- Version information (Node.js 18.x)process.env- Environment variablesprocess.argv- Command line argumentsprocess.cwd()- Current working directoryprocess.uptime()- Process uptimeprocess.memoryUsage()- Memory statisticsprocess.isNodeAvailable- Check if WebContainer Node.js is readyprocess.exec(command, args, options)- Execute Node.js command via WebContainerprocess.spawn(command, args, options)- Spawn Node.js process via WebContainerprocess.runScript(scriptPath, args)- Run a Node.js script fileprocess.evalNode(code)- Evaluate JavaScript in Node.js contextprocess.kill(pid)- Kill a process by PID
Note: This module integrates with Terbium's WebContainer (tb.node) to provide real Node.js execution instead of simulation.
- Constructor with options (title, subtitle, body, icon)
- Event handling with
on()/off() show()/close()- Display notification
import { BrowserWindow } from './sys/lemonade';
const win = new BrowserWindow({
width: 800,
height: 600,
title: 'My App',
resizable: true,
});
win.loadURL('https://example.com');
win.on('close', () => {
console.log('Window closing');
});import { dialog } from './sys/lemonade';
const result = await dialog.showOpenDialog({
title: 'Select File',
properties: ['openFile'],
});
console.log('Selected:', result);import { ipcRenderer } from './sys/lemonade';
// Send message
ipcRenderer.send('message-channel', 'Hello');
// Listen for response
ipcRenderer.on('response-channel', (event, data) => {
console.log('Received:', data);
});
// Request/response pattern
const result = await ipcRenderer.invoke('get-data', params);import { clipboard } from './sys/lemonade';
// Write text
await clipboard.writeText('Hello World');
// Read text
const text = await clipboard.readText();
// Write HTML
await clipboard.writeHTML('<b>Bold text</b>');import { app } from './sys/lemonade';
const homePath = app.getPath('home');
const appDataPath = app.getPath('appData');
const userDataPath = app.getPath('userData');import { process } from './sys/lemonade';
// Check if Node.js is available
if (process.isNodeAvailable) {
// Execute a Node.js command
const exitCode = await process.exec('node', ['--version']);
// Run a script file from Terbium's filesystem
await process.runScript('/home/user/script.js', ['arg1', 'arg2']);
// Evaluate Node.js code directly
const output = await process.evalNode('console.log(process.version)');
// Spawn a long-running process
const proc = await process.spawn('node', ['server.js']);
proc.output.pipeTo(new WritableStream({
write(chunk) {
console.log(chunk);
}
}));
// Install npm packages
await process.exec('npm', ['install', 'express']);
}import { shell } from './sys/lemonade';
// Open URL
await shell.openExternal('https://example.com');
// Show file
shell.showItemInFolder('/path/to/file.txt');
// Move to trash
await shell.moveItemToTrash('/path/to/file.txt');Lemonade wraps the underlying window.tb API (TerbiumOS API) and provides Electron-compatible interfaces. When an Electron method is called, Lemonade translates it to the appropriate window.tb call.
- Window Management: Maps to
window.tb.window.* - File System: Maps to
window.tb.fs.* - Dialogs: Maps to
window.tb.dialog.* - Notifications: Maps to
window.tb.notification.* - Network: Maps to
window.tb.libcurl.fetch - Proxy: Handles URL proxying via
window.tb.proxy.encode - Node.js: Uses
window.tb.node.webContainerfor real Node.js execution via WebContainer
Since Lemonade runs in a web environment, some Electron features have limitations:
Terbium's virtual file system
2. Native Menus: Not fully implemented
3. System Tray: Not available in web
4. Native Notifications: Uses Terbium's notification system
5. Process Control: Some methods are simulated (can't exit browser)
6. Multiple Windows: Limited support via Terbium's window manager
7. Synchronous APIs: Some sync methods are async
8. Node.js: Requires WebContainer to be initialized (tb.node.isReady === true)
7. Synchronous APIs: Some sync methods are async
Potential additions:
- Menu/MenuItem support
- Tray icons (where possible)
- PowerMonitor
- Protocol handling
- Content tracing
- Crash reporter
- Native image handling
- Web contents manipulation
- Session management
- Cookies API
- Download manager
Lemonade aims to maintain API compatibility with Electron 18+. Not all features are available due to browser limitations, but the API surface matches Electron where possible.
To extend Lemonade:
- Add new module in
src/sys/lemonade/modulename.ts - Export from
src/sys/lemonade/index.ts - Implement Electron-compatible API
- Map to
window.tbequivalents - Document usage and limitations