npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tauri-plugin-frameless-window

v0.2.3

Published

Frameless webview windows for Tauri v2 — overlay title bar on macOS, decoration-less on Windows, with optional modal popup flow

Readme

tauri-plugin-frameless-window

Frameless window presets and route-based popup windows for Tauri v2.

This plugin provides the frameless window preset and the popup lifecycle. On Windows, it delegates the caption-button overlay to tauri-plugin-window-controls, which provides native-like minimize, maximize, and close controls and applies the required decoration-less window shape with shadow.

Features

  • Frameless window builder: WebviewWindowBuilder::frameless(...) creates a window with the platform-specific frameless preset.
  • Single window effect shortcut: .effect(Effect::Mica) and window.set_effect(Effect::Mica) wrap Tauri's EffectsBuilder ceremony for one effect.
  • Windows caption controls: Windows frameless windows use tauri-plugin-window-controls for native-like caption buttons and Windows 11 snap-layout support.
  • Route-based popups: openPopup('error/crash', { args: { message } }) opens /popup/error/crash?message=....
  • Blocking popup mode: blocking: true presents a native sheet on macOS and disables the parent window on Windows.
  • Promise resolution: closePopup(true | false) from inside the popup resolves the caller's openPopup(...) promise.

Install

From your Tauri app's src-tauri directory, install the Rust plugins:

cargo add tauri-plugin-frameless-window
cargo add tauri-plugin-window-controls

From your frontend package, install the JavaScript package if you use the popup helpers:

pnpm add tauri-plugin-frameless-window

tauri-plugin-window-controls must be a direct Rust dependency of the app because the app registers it explicitly. Add it unconditionally, not under a Windows-only target dependency; the plugin is a no-op on non-Windows targets.

Register tauri-plugin-window-controls before tauri-plugin-frameless-window:

tauri::Builder::default ()
.plugin(tauri_plugin_window_controls::init())
.plugin(tauri_plugin_frameless_window::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");

Add both default permissions to your capability file, for example src-tauri/capabilities/default.json:

{
  "permissions": [
    "window-controls:default",
    "frameless-window:default"
  ]
}

Frameless Windows

Use WebviewWindowBuilderExt when creating a Tauri webview window:

use tauri::{window::Effect, WebviewUrl, WebviewWindowBuilder};
use tauri_plugin_frameless_window::WebviewWindowBuilderExt;

let window = WebviewWindowBuilder::frameless(app, "main", WebviewUrl::App("/".into()))
.title("My App")
.inner_size(1280.0, 800.0)
.effect(Effect::Mica)
.build() ?;

For existing windows, use WebviewWindowExt when applying an effect after creation:

use tauri::window::Effect;
use tauri_plugin_frameless_window::WebviewWindowExt;

window.set_effect(Effect::Mica) ?;

If you need window size or position persistence, use Tauri's official tauri-plugin-window-state alongside this plugin.

frameless always starts the window hidden with visible(false). Call show() from the frontend after your UI has mounted to avoid a flash of unmounted content.

import {getCurrentWindow} from '@tauri-apps/api/window';

await getCurrentWindow().show();

Platform behavior:

| Platform | frameless preset | |----------|-------------------------------------------------------------------------------------------------------------------------------------------| | macOS | Uses an overlay title bar and hides the native title. | | Windows | Enables the tauri-plugin-window-controls title-bar overlay. The window-controls plugin applies decorations(false) and shadow(true). | | Linux | Keeps the default Tauri window shape and only applies visible(false). |

Popup Flow

From a parent window, open a route-based popup:

import {openPopup} from 'tauri-plugin-frameless-window';

const confirmed = await openPopup('error/crash', {
  args: {message: 'Something broke'},
  blocking: true,
});

This opens your app route at /popup/error/crash?message=Something%20broke. The route must be handled by your frontend router.

From inside the popup route, reveal the popup after mount and resolve the parent promise when the user completes the flow:

import {closePopup, showPopup} from 'tauri-plugin-frameless-window';

await showPopup();
await closePopup(true);

openPopup(...) resolves to the boolean passed to closePopup(...).

Popup options:

| Option | Type | Description | |------------|---------------------------------------------------------|-------------------------------------------------------------------------------------------| | args | Record<string, string \| number \| null \| undefined> | Query parameters appended to /popup/<route>. null and undefined values are omitted. | | blocking | boolean | Blocks the parent on supported platforms. | | detach | boolean | Opens the popup without assigning the current window as its parent. |

Popup platform behavior:

| Platform | blocking: true behavior | |----------|---------------------------------------------------------------------------------------| | macOS | Presents the popup as a native NSWindow sheet when showPopup() is called. | | Windows | Disables the parent window with EnableWindow(hwnd, FALSE) until the popup resolves. | | Linux | Opens a non-modal popup window. |

Rust Popup API

You can also open popups from Rust with PopupExt:

use tauri::Manager;
use tauri_plugin_frameless_window::PopupExt;

let parent = app.get_webview_window("main").expect("main window missing");

let confirmed = app
.popup("error/crash")
.args([("message", "Something broke")])
.parent(parent)
.blocking()
.open()
.await?;

Use open_detached() when you need a PopupHandle and want to wait manually:

let handle = app.popup("settings/about").open_detached() ?;
let resolved = handle.wait().await;

API

Rust exports:

  • init()
  • WebviewWindowBuilderExt
  • WebviewWindowExt
  • PopupExt
  • PopupBuilder
  • PopupHandle
  • is_popup_window_label(label)

JavaScript exports:

  • openPopup(route, options?)
  • closePopup(resolved?)
  • showPopup()
  • isPopupSheet()

License

MIT