LukasHechenberger/open-webpage

Open a webpage in a custom window from nodejs

0Current release v0.2.0Rust
View on GitHub

@lhechenberger/open-webpage

NPM Version Homepage

Open a webpage in a custom window from nodejs

Note

This was basically a playground project for me to get to know napi-rs. I think it turned out pretty well :)

Installation

pnpm add @lhechenberger/open-webpage
# or bun add, yarn add, npm install ...

Usage

Basic example

import { openWebpage } from '@lhechenberger/open-webpage';

// Promise resolves once the window is closed
await openWebpage({ url: 'https://example.com' });
console.log('Window was closed');

...which results in a simple native window popping up, looking like this:

A simple example

You can also use an abort controller to close the page manually

import { openWebpage } from '@lhechenberger/open-webpage';

const controller = new AbortController();
const process = openWebpage({ url: 'https://example.com' }, { cancelSignal: controller.signal });

setTimeout(() => {
  console.log('Aborting process...');
  controller.abort();
}, [5000]);

try {
  await process;
} catch (error) {
  if (error.isCanceled) {
    console.log('Process was cancelled');
  } else {
    throw error;
  }
}

Available options

import { openWebpage } from '@lhechenberger/open-webpage';

openWebpage(
  {
    // Enables devtools
    devtools: true,
    // If the webpage should be opened fullscreen
    fullscreen: true,
    // The window's title
    title: 'some string',
    // **macOS only** If the window title should be hidden
    titleHidden: true,
    // **macOS only** If the titlebar should be hidden
    titlebarHidden: true,
    // The URL to open
    url: 'some string',
  },
  {
    // (optional) options for execa, see https://www.npmjs.com/package/execa
  },
);

There are additional options available to customize the window's appearance, use an IDE to get hints.

CLI

This package also ships with a small command line application

npx @lhechenberger/open-webpage --help # or bunx, pnpx, ...

# or, if you have it installed in your project:
npx open-webpage --help # or bunx open-webpage, pnpx open-webpage, ...
Usage: npx @lhechenberger/open-webpage [options] [url]

Arguments:
  url                The URL to open

Options:
  -V, --version      output the version number
  --devtools         Enables devtools
  --fullscreen       If the webpage should be opened fullscreen
  --title            The window's title
  --title-hidden     **macOS only** If the window title should be hidden
  --titlebar-hidden  **macOS only** If the titlebar should be hidden
  -h, --help         display help for command

How it works

The package is a native Node.js addon written in Rust, built with napi-rs. When called from JavaScript, it spins up a native OS window with an embedded webview — no Electron, no Chromium bundled.

The key crates involved:

Crate Role
napi / napi-derive Exposes the Rust functions to Node.js as a native addon via the Node-API (N-API)
tao Cross-platform windowing library — creates the native OS window and drives the event loop
wry Embeds the platform's system webview (WebKit on macOS/Linux, WebView2 on Windows) inside the tao window
tokio Async runtime used to integrate the blocking event loop with Node.js's async model
futures Async utilities for composing the async operations
schemars / serde Generate JSON Schema from the Rust options types, which is used to produce the TypeScript type definitions at build time

At a high level: tao creates a window and starts the event loop, wry attaches a webview to that window and loads the given URL, and napi-rs bridges the whole thing into a Promise that resolves when the window is closed.

Packages

This repository contains the following packages:

Name Description Links