Skip to content

JulyIghor/HTMLtoApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 

Repository files navigation

HTML to App Community Demos

This repository is a small set of standalone HTML demos built for HTML to App.

HTML to App lets you turn an HTML file or folder into a native macOS app bundle. You can use it to package offline tools, media viewers, internal utilities, dashboards, launchers, and file-driven apps without rewriting them in AppKit or SwiftUI.

What HTML to App Can Do

  • Convert a local HTML file or an entire site folder into a macOS app.
  • Bundle assets inside the app so the result works offline.
  • Launch apps with a native window, standard menu bar, copy/paste shortcuts, and normal text editing behavior inside web content.
  • Customize the generated app name, icon, and visual label treatment.
  • Register the generated app as a Finder handler for selected file extensions or folders.
  • Open compatible files and folders directly from Finder into the web app.
  • Pass opened items into JavaScript through the built-in bridge.
  • Expose scoped read and write APIs so editor-role apps can save back to opened files or folders.
  • Preselect app permissions such as camera, microphone, or location services from HTML metadata.
  • Send native macOS notifications from local HTML with the standard Notification API.
  • Control the Dock badge from JavaScript through window.HTMLtoApp.setBadge() and window.HTMLtoApp.clearBadge() after notification permission is granted.
  • Create a JavaScript-controlled menu bar icon, regenerate its menu on every popup, handle menu item clicks, show menu bar badges, and keep the app running in the background after the window closes.
  • Use drag and drop inside the example apps for local files and folders.
  • Support media-style apps such as image viewers, video players, audio players, and folder browsers.
  • Support canvas-style tools such as annotation or geometry drawing apps, plus document-style editors.
  • Export standalone app bundles that are easy to test, share, and submit.

Opened Files and Permissions

Generated apps can be configured with Open With settings so macOS sends matching files or folders into the app. In the page JavaScript, the launcher provides launch items through:

  • window.HTMLtoApp.launchItems
  • window event htmltoapp-open
  • window.HTMLtoApp.runtime
  • window event htmltoapp-runtime
  • window.HTMLtoApp.fs

For file-backed apps, this makes it possible to build viewers, players, and editors that react to real Finder-opened content instead of only loading bundled assets.

HTML to App can also auto-detect recommended Open With settings and app permissions from your main HTML file. Add this in the document <head>:

<meta name="htmltoapp:open-with" content="role=viewer; files=jpg,jpeg,png; folders=true; permissions=camera">

Supported keys:

  • role=viewer or role=editor
  • files=ext1,ext2,ext3
  • folders=true or folders=false
  • permissions=camera,microphone,location
  • camera=true, microphone=true, or location=true as explicit booleans
  • mic, audio, geolocation, and gps are accepted aliases

When someone browses that HTML source in HTML to App, the app can automatically enable Open With, prefill the role, file extensions, and files/folders options, and preselect requested app permissions in Advanced Settings.

Scoped File Bridge

window.HTMLtoApp.runtime reports whether the exported app is configured as a viewer or editor, and whether write-back is available:

  • enabled
  • role
  • allowFiles
  • allowFolders
  • canWriteBack

window.HTMLtoApp.fs accepts either a launch item object, a folder entry object, or an opened-item id string. Read methods work in both viewer and editor mode. Mutating methods only work when Open With is enabled and the role is editor.

<script>
  const launchItems = (window.HTMLtoApp && window.HTMLtoApp.launchItems) || [];
  const runtime = (window.HTMLtoApp && window.HTMLtoApp.runtime) || {};

  async function openFirstTextFile() {
    const fileItem = launchItems.find((item) => !item.isDirectory);
    if (!fileItem) return;

    const opened = await window.HTMLtoApp.fs.readText(fileItem.id);
    editor.value = opened.text;
  }

  async function saveBackToOpenedFile() {
    const fileItem = launchItems.find((item) => !item.isDirectory);
    if (!fileItem || !runtime.canWriteBack) return;

    await window.HTMLtoApp.fs.writeText(fileItem.id, editor.value);
  }

  async function createNoteInOpenedFolder() {
    const folderItem = launchItems.find((item) => item.isDirectory);
    if (!folderItem || !runtime.canWriteBack) return;

    await window.HTMLtoApp.fs.createDirectory(folderItem.id, "Drafts");
    await window.HTMLtoApp.fs.writeText(folderItem.id, "# New note\n", "Drafts/today.md");
  }
</script>

Available methods:

  • stat(itemOrId, relativePath?)
  • list(itemOrId, relativePath?)
  • readText(itemOrId, relativePath?)
  • readData(itemOrId, relativePath?)
  • writeText(itemOrId, text, relativePath?, options?)
  • writeData(itemOrId, base64Data, relativePath?, options?)
  • createDirectory(itemOrId, relativePath, options?)
  • remove(itemOrId, relativePath?, options?)
  • move(itemOrId, fromRelativePath, toRelativePath, options?)

Notes:

  • A file item can be read or overwritten directly with no relative path.
  • A folder item uses relative paths inside that opened folder tree only.
  • writeText supports encoding, atomic, and createIntermediates.
  • writeData supports atomic and createIntermediates.
  • createDirectory supports createIntermediates.
  • remove supports recursive for non-empty folders.
  • move supports createIntermediates and overwrite.
  • The bridge does not grant arbitrary filesystem access outside the exact opened file or folder scope.

Notifications and Dock Badge

Generated apps can pass notification requests from local HTML to native macOS notifications. This is local notification passthrough from the exported app, not APNs or server-delivered remote push. Use the standard browser-style Notification API:

<script>
  async function sendNotification() {
    if (!("Notification" in window)) return;

    const permission = await Notification.requestPermission();
    if (permission !== "granted") return;

    new Notification("HTML to App", {
      body: "This notification was sent from local HTML.",
      tag: "html-to-app-demo"
    });
  }
</script>

Generated apps can also control their Dock badge from JavaScript. On macOS, Dock badge visibility is tied to notification authorization for the generated app, so request notification permission before enabling badge controls in your UI:

<script>
  const appBridge = window.HTMLtoApp;

  async function updateDockBadge(value) {
    const permission = "Notification" in window
      ? await Notification.requestPermission()
      : "denied";
    if (permission !== "granted") return;

    if (appBridge && typeof appBridge.setBadge === "function") {
      appBridge.setBadge(value);
    }
  }

  function clearDockBadge() {
    if (appBridge && typeof appBridge.clearBadge === "function") {
      appBridge.clearBadge();
    }
  }

  updateDockBadge("3");
</script>

Badge values are strings, so you can use numbers, short labels, or clear the badge when there is no active state to show. If permission is denied, keep both notification and Dock badge controls disabled or show the user where to re-enable notifications in System Settings. The bridge namespace is exactly window.HTMLtoApp.

Menu Bar and Window Controls

Generated apps can create a menu bar icon from JavaScript. The native launcher asks JavaScript for the menu each time the icon is clicked, so the page can rebuild the menu from current state before the popup appears. Menu items support separators, checked state, toggle callbacks, and recursive submenus.

<script>
  const appBridge = window.HTMLtoApp;
  let paused = false;

  appBridge?.menuBar?.setIcon({
    title: "TA",
    tooltip: "Task Agent",
    imagePosition: "left",
    closeToMenuBarOnWindowClose: true
  });

  appBridge?.menuBar?.setBadge("4");

  appBridge?.menuBar?.setMenu(() => [
    { id: "open", title: "Open Window" },
    { type: "separator" },
    { id: "paused", title: "Paused", checked: paused, toggle: true },
    {
      title: "Queues",
      submenu: [
        { id: "inbox", title: "Inbox" },
        { id: "done", title: "Done" }
      ]
    },
    { type: "separator" },
    { id: "quit", title: "Quit" }
  ]);

  appBridge?.menuBar?.onItemClick((event) => {
    if (event.id === "open") appBridge.showWindow();
    if (event.id === "paused") paused = event.checked;
    if (event.id === "quit") appBridge.quit();
  });
</script>

The generated app icon is shown by default. If title is also set, the status item shows icon and title together; use imagePosition: "left" or imagePosition: "right" to choose the side. Set imageVisible: false for a text-only menu bar item. Menu bar badges draw on the image icon and are not appended to text-only titles.

Use window.HTMLtoApp.setWindowTitle(title) to control the native window title. window.HTMLtoApp.showWindow(), window.HTMLtoApp.hideWindow(), and window.HTMLtoApp.quit() are useful from menu item callbacks. Only expose window hide/show controls when a menu bar item exists, so the user has a visible way to restore the app. Use window.HTMLtoApp.menuBar.hideIcon() or menuBar.configure({ visible: false }) to remove the menu bar item and let the user start the menu bar flow again. When closeToMenuBarOnWindowClose is enabled and the menu bar icon is visible, closing the generated app window hides the window and Dock icon while the WebView keeps running; the app shows a one-time native message explaining that it is still running in the menu bar.

Examples

Each example below is a single HTML file you can package with HTML to App.

Local gallery viewer for images opened from Finder or from a folder.

Recommended Open With setup:

  • Role: Viewer
  • Accept: files and folders
  • Extensions: jpg, jpeg, png, gif, webp, bmp, tif, tiff
  • Permissions: none

Canvas app for drawing rectangles, circles, arrows, lines, and labels. It can also use an opened image as the background.

Recommended Open With setup:

  • Role: Editor
  • Accept: files
  • Extensions: jpg, jpeg, png, webp
  • Permissions: none

Text editor that opens Finder-selected files as text, saves directly back to the opened file, and can create or remove files and folders when launched on a folder.

Recommended Open With setup:

  • Role: Editor
  • Accept: files and folders
  • Extensions: txt, md, html, htm, css, js, json, xml, csv, log
  • Permissions: none

Local video player with playlist-style navigation for one file or a whole folder.

Recommended Open With setup:

  • Role: Viewer
  • Accept: files and folders
  • Extensions: mp4, mov, m4v
  • Permissions: none

Simple local audio player with queue support for tracks or album folders.

Recommended Open With setup:

  • Role: Viewer
  • Accept: files and folders
  • Extensions: mp3, m4a, aac, wav, aif, aiff
  • Permissions: none

Live camera viewer with device switching, mirroring, framing guides, still capture, and offline snapshots.

Recommended Open With setup:

  • None needed
  • Permissions: Camera Access

Demonstrates native notification passthrough from local HTML and Dock badge control from JavaScript after notification permission is granted.

Recommended Open With setup:

  • None needed
  • Permissions: none

Demonstrates JavaScript-controlled menu bar icons, image-plus-title placement, per-popup dynamic menu regeneration, status item and menu item callbacks, toggled items, recursive submenus, menu bar badges, hiding/removing the menu bar item, background menu bar behavior, and native window title control.

Recommended Open With setup:

  • None needed
  • Permissions: none

Mixed-media folder browser for quickly previewing assets such as images, video, audio, and text files.

Recommended Open With setup:

  • Role: Viewer
  • Accept: folders
  • Extensions: none
  • Permissions: none

Typical Uses

  • Text editor
  • Markdown notes app
  • Image viewer
  • Photo browser
  • Video player
  • Audio player
  • Camera preview tool
  • Asset browser
  • Internal dashboard
  • Presentation app
  • Documentation shell
  • Kiosk-style launcher
  • Drawing or annotation utility

Website

Made for HTML to App.

About

Standalone HTML demos for HTML to App, showing how local HTML files can become offline macOS apps with Finder file handling, permissions, and JavaScript launch-item support.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors