Carlo

0.9.46 · abandoned · verified Sun Apr 19

Carlo is a Node.js framework designed to create hybrid desktop applications by rendering Node.js data structures and UIs using a locally installed Google Chrome browser instance. It establishes communication between Node.js and the browser via the Puppeteer project, offering a remote call infrastructure for seamless interoperability. Unlike Electron or NW.js, Carlo does not bundle Chromium, relying instead on the user's existing Chrome installation. This approach can lead to smaller application sizes and leverage an up-to-date browser. The project, currently at version 0.9.46, was last updated in June 2019, and its GitHub repository under `GoogleChromeLabs` shows no recent activity, indicating it is no longer actively maintained. Key differentiators included the ability to bundle the application into a single executable using `pkg`, exposing Node.js capabilities to a web frontend, and leveraging the web stack for dynamic visualization of Node.js app states.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates launching a Carlo application, serving static HTML content, and exposing a Node.js function (`getSystemInfo`) to the browser environment. The browser-side JavaScript then calls this exposed function to retrieve and display system information from the Node.js process.

const carlo = require('carlo');
const path = require('path');

(async () => {
  // Launch the browser. Carlo requires a locally installed Chrome/Chromium.
  const app = await carlo.launch({
    args: ['--disable-extensions', '--start-maximized'],
    width: 800,
    height: 600
  });

  // Terminate Node.js process on app window closing.
  app.on('exit', () => process.exit());
  app.on('unhandledRejection', (reason, promise) => {
    console.error('Unhandled Rejection at:', promise, 'reason:', reason);
  });

  // Serve static web files from the 'app' directory.
  // Make sure to create a simple `index.html` in a folder named `app`
  // or serve from `__dirname` if your html is alongside your JS file.
  app.serveFolder(path.join(__dirname, 'app'));

  // Expose a Node.js function 'getSystemInfo' to the web environment.
  // This function will be callable from the browser-side JavaScript.
  await app.exposeFunction('getSystemInfo', async () => {
    return {
      nodeVersion: process.version,
      platform: process.platform,
      arch: process.arch,
      envVars: Object.keys(process.env).sort()
    };
  });

  // Navigate to the main page of your app.
  await app.load('index.html');

  console.log('Carlo app launched. Check the new Chrome window.');
})();

// A minimal app/index.html to be served by Carlo
// (Save this in a subfolder named 'app' next to your main JS file)
/*
<!DOCTYPE html>
<html>
<head>
  <title>Carlo System Info</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    pre { background-color: #f4f4f4; padding: 10px; border-radius: 4px; }
  </style>
</head>
<body>
  <h1>System Information</h1>
  <pre id="info-display"></pre>
  <script>
    async function displaySystemInfo() {
      const info = await getSystemInfo(); // Call Node.js function
      document.getElementById('info-display').textContent = JSON.stringify(info, null, 2);
    }
    window.onload = displaySystemInfo;
  </script>
</body>
</html>
*/

view raw JSON →