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

desktop-window

v0.4.7

Published

A lightweight Web Components-based custom element that replicates the look and feel of native desktop application windows — resizable, movable, and styled like a traditional OS window.

Readme

desktop-window

A lightweight Web Components-based custom element that replicates the look and feel of native desktop application windows — resizable, movable, and styled like a traditional OS window. No frameworks required.

demo

NOT READY FOR PRODUCTION

This package is in active development, and not yet reached the point where I can recommend using in production environment:

  • Its tested to some degree, but not well tested or battle proven.
  • Documentation is still in the making (and will probably arrive in a month).
  • The API may still change. It's getting more stable, but changes are still possible.

Roadmap

  • comprehensive documentation
  • accessibility
  • test cases / unit tests?

Usage

import { register, DesktopWindow } from 'desktop-window';

register(); // this guards against multiple accidental registration

// OR you could just do this instead:
customElements.define('desktop-window', DesktopWindow);

Or without a build tool:

Manually copy the desktop-window.autoload.js to your site, then:

<script src="desktop-window.autoload.js"></script>

Use the <desktop-window> tag in HTML code.

<style>
  desktop-window[fullscreen] #enter-fullscreen { display: none; }
  desktop-window:not([fullscreen]) #exit-fullscreen { display: none; }
</style>
<div style="position: relative; width: 100vw; height: 100vh;">
  <desktop-window name="Hello world!" movable resizable minimizable maximizable closable centered>
    The contents of the window are placed here.
    <button id="enter-fullscreen">⛶ Enter fullscreen</button>
    <button id="exit-fullscreen">⛶ Exit fullscreen</button>
  </desktop-window>
</div>
<script>
document.getElementById('enter-fullscreen').addEventListener('click', function (event) {
    this.dispatchEvent(new Event('request-fullscreen', { bubbles: true }));
});
document.getElementById('exit-fullscreen').addEventListener('click', function (event) {
    this.dispatchEvent(new Event('exit-fullscreen', { bubbles: true }));
});
</script>

Examples

For examples see the Github project examples folder.

  1. Clone repository or download zip.
  2. Open examples/index.html in your browser.

Documentation

Contents

Attributes

All boolean attributes on <desktop-window> follow this rule:

  • If the attribute is present, its value is considered true, regardless of whether the value is empty, "true", or equals the attribute name.
  • If the attribute is not present, the value is false.

Truthy examples (evaluated as true):

<desktop-window centered>
<desktop-window centered="true">
<desktop-window centered="centered">
<desktop-window centered="1">
<desktop-window centered="">

Falsy example (evaluated as false):

<desktop-window>

There is no way to explicitly pass false via the attribute. Omitting the attribute entirely is the only way to make it false.

If dynamic control of booleans is needed, use JavaScript to set/remove attributes:

element.removeAttribute('centered'); // false
element.setAttribute('centered', ''); // true

name

Type: string
Specifies the title displayed in the window's title bar.
Example:

<desktop-window name="My Window">

movable

Type: boolean
If present, the window can be dragged. If omitted, the window is fixed in place.
Example:

<desktop-window movable>

x

Type: number
Initial horizontal coordinate of the window (in pixels, omit the px unit). Ignored if centered is set.
Example:

<desktop-window x="100">

y

Type: number
Initial vertical coordinate of the window (in pixels, omit px unit). Ignored if centered is set.
Example:

<desktop-window y="100">

centered

Type: boolean
If present, the window is centered. Overrides x and y.
Example:

<desktop-window centered>

resizable

Type: boolean
If present, the window can be resized. Omitting it disables resizing.
Example:

<desktop-window resizable>

width

Type: number
Default: 350.
Initial width in pixels.
Example:

<desktop-window width="800">

height

Type: number
Default: 350.
Initial height in pixels.
Example:

<desktop-window height="600">

minwidth

Type: number
Default: 150.
Minimum width allowed during resizing.
Example:

<desktop-window minwidth="200">

maxwidth

Type: number Maximum width allowed during resizing.
Example:

<desktop-window maxwidth="1000">

minheight

Type: number
Default: 150.
Minimum height allowed during resizing.
Example:

<desktop-window minheight="200">

maxheigh

Type: number
Maximum height allowed during resizing.
Example:

<desktop-window maxheigh="700">

minimizable

Type: boolean
If present, the window shows a minimize button and allows minimizing.
Example:

<desktop-window minimizable>

minimized

Type: boolean
If present, the window is minimized.
Example:

<desktop-window minimized>

maximizable

Type: boolean
If present, the window shows a maximize button and allows maximizing.
Example:

<desktop-window maximizable>

maximized

Type: boolean
If present, the window is maximized.
Example:

<desktop-window maximized>

closable

Type: boolean
If present, the window can be closed via an UI button. Omit to disable closing from the UI.
Closing via JS API is still possible when this is disabled.
Example:

<desktop-window closable>

fullscreen

Type: boolean
If present, the window is displayed in fullscreen mode.
In fullscreen mode there is no borders around the window, but the titlebar is still visible with the minimize, restore, close controls.
Example:

<desktop-window fullscreen>

hidden

Type: boolean
If present, the window is not visible. Remove this attribute to show the window.
Example:

<desktop-window hidden>

autofocus

Type: boolean
If present, the window receives focus on creation.
Example:

<desktop-window autofocus>

frameless

Type: boolean If present, the window is rendered without borders or title bar.
Example:

<desktop-window frameless>

modal

Type: boolean
If present, the window becomes modal (blocks interaction with other sibling windows or the background).
Example:

<desktop-window modal>

aspectratio

Type: number
Enforces a fixed aspect ratio (width / height) when resizing.
Example:

<desktop-window aspectratio="1.777">

aspectratioextrawidth

Type: number
Extra width in pixels added to the actual content width when maintaining the aspect ratio.
Example:

<desktop-window aspectratioextrawidth="50">

aspectratioextraheight

Type: number
Extra height in pixels added to the content height for aspect ratio calculation.
Example:

<desktop-window aspectratioextraheight="50">

Events emitted

  • 'closing'
  • 'closed'
  • 'minimizing'
  • 'minimized'
  • 'maximizing'
  • 'maximized'
  • 'restoring'
  • 'restored'
  • 'requesting-fullscreen'
  • 'exiting-fullscreen'

Events listening for

  • 'close'
  • 'minimize'
  • 'maximize'
  • 'restore'
  • 'request-fullscreen'
  • 'exit-fullscreen'
  • 'move'
  • 'resize-n'
  • 'resize-e'
  • 'resize-s'
  • 'resize-w'
  • 'resize-ne'
  • 'resize-nw'
  • 'resize-se'
  • 'resize-sw'

Properties

  • name
  • movable
  • x
  • y
  • centered
  • width
  • height
  • minWidth
  • minHeight
  • maxWidth
  • maxHeight
  • resizable
  • minimizable
  • minimized
  • maximizable
  • maximized
  • closable
  • fullscreen
  • hidden
  • autofocus
  • frameless
  • modal
  • aspectRatio
  • aspectRatioExtraWidth
  • aspectRatioExtraHeight

Methods

  • flash()
  • isFocused()
  • focus()
  • blur()
  • close()
  • destroy()
  • getPosition()
  • setPosition(x, y)
  • getSize()
  • setSize(width, height)
  • getNormalBounds()
  • getBounds()
  • setBounds({ x, y, width, height })
  • getContentSize()
  • setContentSize(width, height)
  • getContentBounds()
  • setContentBounds({ x, y, width, height })
  • setAspectRatio(ratio, { width, height })

Slots

  • titlebar-start
  • titlebar-center
  • titlebar-end

Parts

  • window
  • titlebar
  • titlebar-start
  • titlebar-center
  • titlebar-end
  • titlebar-text
  • minimize-button
  • restore-button
  • maximize-button
  • close-button
  • client-area

CSS Variables

  • --desktop-window-background-color
  • --desktop-window-border-width
  • --desktop-window-border-color
  • --desktop-window-minimize-duration
  • --desktop-window-maximize-duration
  • --desktop-window-titlebar-height
  • --desktop-window-titlebar-text-color
  • --desktop-window-titlebar-background-color
  • --desktop-window-titlebar-font-family
  • --desktop-window-titlebar-font-size
  • --desktop-window-minimize-button-mask-image
  • --desktop-window-maximize-button-mask-image
  • --desktop-window-restore-button-mask-image
  • --desktop-window-close-button-mask-image
  • --desktop-window-buttons-width
  • --desktop-window-buttons-height
  • --desktop-window-buttons-margin
  • --desktop-window-buttons-text-color
  • --desktop-window-buttons-background-color
  • --desktop-window-buttons-hover-text-color
  • --desktop-window-buttons-hover-background-color
  • --desktop-window-minimize-text-color
  • --desktop-window-minimize-background-color
  • --desktop-window-minimize-hover-text-color
  • --desktop-window-minimize-hover-background-color
  • --desktop-window-maximize-text-color
  • --desktop-window-maximize-background-color
  • --desktop-window-maximize-hover-text-color
  • --desktop-window-maximize-hover-background-color
  • --desktop-window-restore-text-color
  • --desktop-window-restore-background-color
  • --desktop-window-restore-hover-text-color
  • --desktop-window-restore-hover-background-color
  • --desktop-window-close-text-color
  • --desktop-window-close-background-color
  • --desktop-window-close-hover-text-color
  • --desktop-window-close-hover-background-color
  • --desktop-window-focused-background-color
  • --desktop-window-focused-border-color
  • --desktop-window-focused-titlebar-text-color
  • --desktop-window-focused-titlebar-background-color
  • --desktop-window-focused-buttons-text-color
  • --desktop-window-focused-buttons-background-color
  • --desktop-window-focused-buttons-hover-text-color
  • --desktop-window-focused-buttons-hover-background-color
  • --desktop-window-focused-minimize-text-color
  • --desktop-window-focused-minimize-background-color
  • --desktop-window-focused-minimize-hover-text-color
  • --desktop-window-focused-minimize-hover-background-color
  • --desktop-window-focused-maximize-text-color
  • --desktop-window-focused-maximize-background-color
  • --desktop-window-focused-maximize-hover-text-color
  • --desktop-window-focused-maximize-hover-background-color
  • --desktop-window-focused-restore-text-color
  • --desktop-window-focused-restore-background-color
  • --desktop-window-focused-restore-hover-text-color
  • --desktop-window-focused-restore-hover-background-color
  • --desktop-window-focused-close-text-color
  • --desktop-window-focused-close-background-color
  • --desktop-window-focused-close-hover-text-color
  • --desktop-window-focused-close-hover-background-color

Notes

  • Always set position: relative or position: absolute on the immediate parent container, or the window may behave unexpectedly. Only exception is when the parent is document.body.

  • Setting overflow: hidden on the container element is recommended to hide windows moved partially outside of the area and prevent an appearing scrollbar.

  • The window works only when there is a valid parentElement, so appending eg. to a shadow root directly will not work.

  • Appending to the document.body works, but don't forget to set the body height or have content that stretches the area!

  • When the script is asynchronously loaded and the HTML has windows, I recommend you this CSS to prevent jumping content:

    desktop-window:not(:defined) {
      display: none;
    }

Missing a feature?

Create an issue describing your needs! If it fits the scope of the project I will implement it.