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

electron-bookmarks

v0.2.4

Published

Access to macOS Security-Scoped bookmarks in an electron application

Downloads

151

Readme

Electron Bookmarks!

This module enables you to use sandboxed Security-Scoped Bookmarks inside of an electron application.

NEED TO KNOW

  • This module only supports app-scoped bookmarks at this time. (document-scoped bookmarks are planned, but their implementation may be more difficult).
  • I'm not sure if this will be approved by the Mac App Store review process - since it uses nodobjc for native Objective-C runtime bindings. I'm in the process of releasing an app on the App Store that uses this module and will update this as soon as I know.

IMPORTANT:

Please note this is experimental software, and is not currently ready for the production environment. It is currently under active development and its API may change from version to version without notice, until this reaches version 1.0.0

LASTLY:

Due to the way Objective-C is bridged to the Node process, you MUST use this module in electron's main process. It will not work in the renderer process.

Installation

Super easy.

npm install --save electron-bookmarks

Introduction

This module was created to be a drop-in-replacement for electron's dialog module. In order to create a security-scoped bookmark you have to use Use Apple's Powerbox API, which is used transparently in the background by NSOpenPanel (and NSSavePanel). Thus, the need to re-create electron's dialog module in order to have access to the NSURL class returned by it.

You must have the correct entitlements (either com.apple.security.files.bookmarks.document-scope or com.apple.security.files.bookmarks.app-scope in conjunction with com.apple.security.files.user-selected.read-write) in your signed electron app (see here for more information), it must have been already packaged for the mas platform, and of course, this only runs on macOS.

tl;dr

Change this:

let win = new BrowserWindow();
dialog.showOpenDialog(win, { /* ... */ }, (filenames) => {
  console.log(filenames); // [ '/path/to/file/' ]
});

To this:

const bookmarks = require('electron-bookmarks');
bookmarks.showOpenDialog(win, { bookmarkType: 'app', /* ... */ }, (filenames, bookmarks) => {
  console.log(filenames); // [ '/path/to/file/' ]
  console.log(bookmarks); // { keys: [ 'bookmark::file:///path/to/file/' ], ... }
});

And this:

fs.writeFile('/path/to/file', 'foo', 'utf8', function (err) {
  if (err) throw err; // Error: EPERM: operation not permitted, access '/path/to/file'
  else {
    // ...
  }
});

To this:

const bookmarks = require('electron-bookmarks');
bookmarks.open(myBookmark, function (allowedPath, close) {
  fs.writeFile('/path/to/file', 'foo', 'utf8', function (err) {
    if (err) throw err; // null
    else {
      // Yay! We have access outside the sandbox!
      // We can read/write to this file.
      
      // ...
      
      // Once finished, the bookmark *MUST* be closed!
      close(); 
    }
  });
});

Usage

Note that initialisation of this module may take some time, since it has to bridge Node to Objective-C and setup all the runtime calls. For this reason bookmarks.init() has been provided, so you can initialise it in your app at a convenient time. If you don't call this, bookmarks will be initialised the first time you use any of its methods.

bookmarks.showOpenDialog(window, options[, callback])

In order to use this you must do two things:

  1. Pass bookmarkType: 'app'. Default is "app" (the value "document" will - hopefully - be supported in the future).
  2. Use showOpenDialog's asynchronous API. There is currently no support for the synchronous API (nor will there be).

Usually electron's dialog.showOpenDialog will return an array of filenames. electron-bookmarks returns the same array but with an additional argument bookmarks.

bookmarks.keys tells you which bookmarks have just been saved to NSUserDefaults as NSData objects. These bookmarks are accessible across app restarts and allow your app to access files outside its sandbox provided you use the APIs correctly. Use these keys in bookmarks.open(key, ...).

bookmarks.showSaveDialog()

Important!
bookmarks.showSaveDialog() will create the file at the path you select in the dialog, since a bookmark cannot be created without a file. Therefore, remember that after using bookmarks.showSaveDialog() you will be reading or writing to an already existing file.

Otherwise the same as showOpenDialog, you must:

  1. Pass bookmarkType: 'app'. Default is "app" (the value "document" will - hopefully - be supported in the future).
  2. Use showOpenDialog's asynchronous API. There is currently no support for the synchronous API (nor will there be).

Usually electron's dialog.showSaveDialog will return a path. electron-bookmarks returns the same path but with an additional argument bookmark.

bookmark.key is the key that has just been saved to NSUserDefaults as an NSData object. This bookmark is accessible across app restarts and allow your app to access the file outside its sandbox provided you use the APIs correctly. Use this key in bookmarks.open(key, ...).

bookmarks.open(key, callback)

  • key is a key returned from bookmarks.showOpenDialog or from bookmarks.list.
  • callback(allowedPath, close)
    • allowedPath is the path you must use in order to access your file.
    • close IMPORTANT: this function MUST be called once you have finished using the file! If you do not remember to close this, kernel resources will be leaked and your app will lose its ability to reach outside the sandbox completely, until your app is restarted.

bookmarks.list()

This will return an array of all the keys that you've saved with electron-bookmarks. These can be used in order to gain access outside your sandbox.

bookmarks.deleteOne(key)

Simply delete a bookmark by its key.
Returns undefined;

bookmarks.deleteAll()

Removes all bookmarks associated with your app. Returns undefined;

bookmarks.init()

Links the runtime Objective-C to Node. May take up to a second to complete.

Things to do

  • [ ] Add support for document-scoped bookmarks (seems tricky)
    • Note that "document-scoped" bookmarks are scoped to each document, so we'll have to attach the bookmarks to the each document's NSURL entry. I'm not currently sure of a good way to get an NSURL entry nicely.
  • [ ] Attempt to support app groups and shared bookmarks ?

To be documented:

  • bookmarks don't need to be used until next start of app

License

MIT