webview-bun

repository·main·Indexed 18 days ago

https://github.com/tr1ckydev/webview-bun

Bun bindings for webview, a tiny library for creating lightweight, cross-platform desktop GUIs using web technologies (HTML/CSS/JS) powered by the Bun runtime. Version 2.4.0 provides the Webview class to manage window lifecycle, bind Bun functions to the JavaScript context, and execute or inject JS code. Supports compiling to single-file executables via bun build --compile and provides access to native window handles for advanced integration.

Tokens
2.7K
Snippets
11
Records
15
Agent score
66%

What's inside webview-bun

  1. Use a custom webview library via WEBVIEW_PATH

    main
    If you have a custom-built webview shared library, you can instruct the application to use it by setting the WEBVIEW_PATH environment variable to the path of your .so, .dll, or .dylib file before running your application.
  2. Build the webview-bun library from source

    main

    If you need to build the library itself (e.g., for customization or development), follow these steps:

    1. Install Prerequisites

    • Windows: Install Visual Studio Build Tools 2022 with the Desktop development with C++ workload.
    • Linux (Debian): sudo apt install libgtk-4-dev libwebkitgtk-6.0-dev cmake ninja-build clang
    • Linux (Fedora): sudo dnf install gtk4-devel webkitgtk6.0-devel cmake ninja-build clang
    • Linux (Arch): sudo pacman -S cmake ninja clang
    • macOS: brew install cmake ninja clang

    2. Clone and Build

    # Clone with submodules
    git clone --recurse-submodules https://github.com/tr1ckydev/webview-bun
    cd webview-bun
    
    # Build the library
    bun run build

    The compiled library is located in the build folder.

    To clear the cache and rebuild:

    bun clean
    bun run build
    git clone --recurse-submodules https://github.com/tr1ckydev/webview-bun
    cd webview-bun
    bun run build
  3. Install webview-bun

    main

    Install the package using Bun:

    bun i webview-bun

    Platform Prerequisites

    Linux

    The compiled Linux library requires GTK 4 and WebkitGTK 6. Install the necessary system dependencies based on your distribution:

    • Debian-based: sudo apt install libgtk-4-1 libwebkitgtk-6.0-4
    • Arch-based: sudo pacman -S gtk4 webkitgtk-6.0
    • Fedora-based: sudo dnf install gtk4 webkitgtk6.0

    Windows

    The package uses the system-installed webview. For Windows versions prior to Windows 11, the Microsoft Edge WebView2 runtime must be installed.

  4. Compile a single-file executable

    main

    You can use bun build --compile to create a self-sufficient executable for your webview application.

    bun build --compile --minify --sourcemap ./path/to/app.ts --outfile myapp

    Hiding the terminal window

    By default, a terminal window may open in the background on Windows and macOS.

    • Windows: Use the hidecmd.bat script from this repository and provide the path to your .exe when prompted.
    • macOS: Append the .app extension to your --outfile name in the build command.

    Cross-platform compilation

    To compile for a different platform (e.g., Windows from macOS/Linux), use the --target flag:

    bun build --compile --target=bun-windows-x64 --minify --sourcemap ./path/to/app.ts --outfile myapp
    bun build --compile --minify --sourcemap ./examples/todoapp/app.ts --outfile todoapp
  5. Run a web server with Webview using Workers

    main

    Running a web server on the main thread will block the webview window. To prevent this, run the web server in a worker thread. When compiling, include both the entry point and the worker file:

    bun build --compile --minify --sourcemap ./index.ts ./worker.ts --outfile webserver
  6. Customize Webview versions (Linux and Windows)

    main

    When building the library from source, you can customize the webview engine version via CMake options in _build.ts:

    • Linux: Change the WEBVIEW_WEBKITGTK_API option to use a different WebkitGTK version (ensure the corresponding libraries are installed on your system).
    • Windows: Change the WEBVIEW_MSWEBVIEW2_VERSION option to a specific NuGet version string to bundle a specific version instead of using the system one.
  7. Basic usage of Webview

    main

    To create a web-based GUI, import the Webview class, instantiate it, set the HTML content, and call .run() to start the event loop.

    import { Webview } from "webview-bun";
    
    const html = `
    <html
        <body>
            <h1>Hello from bun v${Bun.version} !</h1>
        </body>
    </html>
    `;
    
    const webview = new Webview();
    
    webview.setHTML(html);
    webview.run();
    import { Webview } from "webview-bun";
    
    const html = `
    <html
        <body
            <h1>Hello from bun v${Bun.version} !</h1>
        </body>
    </html
    `;
    
    const webview = new Webview();
    
    webview.setHTML(html);
    webview.run();
  8. Initialize a Webview instance

    main

    Use the Webview constructor to create a new window. You can enable developer tools, set an initial size, or embed the webview into an existing native window handle.

    Parameters:

    • debug (boolean): If true, developer tools are enabled on supported platforms.
    • size (Size): An object specifying width, height, and hint. If undefined, the window may be invisible on macOS until resized.
    • window (Pointer | null): UNSAFE. A pointer to a platform-specific native window handle (GtkWindow, NSWindow, or HWND). If provided, the webview is embedded as a child. If null or undefined, a new window is created.

    Note: You can also initialize a Webview instance by passing an existing Pointer handle to the constructor.

    import { Webview, SizeHint } from "webview-bun";
    
    // Create a new webview with developer tools enabled and a fixed size
    const webview = new Webview(true, {
      width: 200,
      height: 200,
      hint: SizeHint.FIXED
    });
    
    webview.navigate("https://bun.sh/");
    webview.run();
  9. Access unsafe native handles

    main

    The Webview class provides access to the underlying native pointers. Warning: These are highly unsafe and can cause crashes if misused.

    • unsafeHandle: Returns the raw pointer to the webview instance.
    • unsafeWindowHandle: Returns the platform-specific native window handle:
      • GTK: GtkWindow pointer
      • Cocoa: NSWindow pointer
      • Win32: HWND pointer
  10. Configure Webview window size and title

    main

    You can control the window's appearance using the size and title properties.

    Setting Size

    Assign a Size object to the size property. The Size object requires:

    • width: number
    • height: number
    • hint: A SizeHint value.

    SizeHint values:

    • SizeHint.NONE: Default size.
    • SizeHint.MIN: Minimum bounds.
    • SizeHint.MAX: Maximum bounds.
    • SizeHint.FIXED: User cannot resize the window.

    Setting Title

    Assign a string to the title property to change the native window title.

    import { Webview, SizeHint } from "webview-bun";
    
    const webview = new Webview();
    
    // Set window title
    webview.title = "Hello world!";
    
    // Set window size to a small fixed window
    webview.size = {
      width: 200,
      height: 200,
      hint: SizeHint.FIXED
    };
    
    webview.run();
  11. Bind Bun functions to the Webview JavaScript context

    main

    The bind method allows you to expose Bun (server-side) functions to the webview's JavaScript environment as global asynchronous functions.

    Features:

    • Automatic JSON conversion: Arguments passed from JavaScript are automatically parsed from JSON. The return value from your Bun callback is automatically stringified and sent back to the webview.
    • Async support: If your callback returns a Promise, the result is sent back to the webview once the promise resolves.
    • Error handling: If the callback throws an error, the error is passed back to the webview.

    To remove a binding, use unbind(name).

    import { Webview } from "webview-bun";
    
    const html = `
      <button onclick="press('I was pressed!', 123).then(log);">
        Press me!
      </button>
    `;
    
    const webview = new Webview();
    webview.navigate(`data:text/html,${encodeURIComponent(html)}`);
    
    // Bind 'press' to a Bun function
    webview.bind("press", (msg, num) => {
      console.log(msg, num);
      return { status: "ok" };
    });
    
    // Bind 'log' to pipe webview logs to Bun console
    webview.bind("log", (...args) => console.log(...args));
    
    webview.run();