Skip to content
A reliable org-capture browser extension for Chrome/Firefox
JavaScript Python HTML Shell
Branch: master
Clone or download
Latest commit ecd1d2a Nov 16, 2019

Build status: CircleCI

Grasp is a browser extension Chrome and Firefox, which adds a button/keybinding to capture current page title and url, possibly selected text, additional comments or tags and adds it into your Org Mode file.

Screenshot, short demo.

Install from Chrome store:

Install from

Install from a zip: releases.


In the simplest setup, the server runs locally, and you can use 'localhost' version of the extension. If you have to work on a computer where you can't run python scripts, or your target capture file is just not there, you can selfhost the server part elsewhere and use the 'any host' version. Don't forget to set the endpoint in extension settings!

  1. Install server counterpart as systemd service (to autostart it): server/setup --path /path/to/your/ [--port <custom port>] [--template <custom org-capture template>].

    Or alternatively, just run it directly if you don't want to autostart it: server/ --path /path/to/your/ [--port <custom_port>] [--template <custom org-capture template>].

  2. Install chrome extension and configure hotkeys

That's it! If you're using custom port make sure it's same as in the extension settings (default is 12212).


Why use org-capture? Well, it's hard to explain, maybe some other time... However if you do know you want to use it instead/alongside your browser bookmarks, by default you don't have much choice and have to copy everything manually. For an experienced enough Org Mode user it's a torture.

For a while, I used the only Chrome extension for that (as for January 2019). However, it relies on setting up MIME handler which is quite flaky for many people (me included). What is more, capturing via org template requires always running emacs daemon, which might be too much for some people. But the worst thing is if capturing fails, you have to way of knowing about it. After losing few days of captured stuff due to MIME handler mysteriously not working, I got fed up and figured it's time to implement something more reliable.

My approach still requires a running server, but it's a simple python script which simply appends a text entry to a text file. The backend always responds back and in case anything fails, you get a notification. There is a collateral benefit though is that you can potentially use anything as a backend and storage file, e.g. you might be more of a Markdown or Todo.txt fan (let me know if you are interested in that!).

Main feature of this extension is that you can also add a comment and tags to the information you are capturing.

The only downside so far is that it's not as well integrated with emacs as its builtin capture templates. E.g. currently you can't point at a specific header in org file, it would just append at the end. However, if that's a stopper for you, please let me know, I could come up with something!


No third party dependencies! Just python3.

Potentional improvements

Permissions used

  • storage for settings
  • notifications for showing error notification
  • activeTab for requesting url, title and selected text
  • http://localhost/capture for talking with backend
  • content_security_policy needed for webpack

Building extension

The most up-to-date instructions should be in CI config.

You're gonna need npm for building extension.

npm install
npm run build

After that you can find the extension in build directory and 'Load unpacked** if necessary. There is also Flow and Eslint set up.

building any host version

If you do need unresticted url permissions, build the extensions like that: ANY_HOST=yes npm run build.

building for Firefox

Default target is Chrome. use TARGET=firefox npm run build to build for firefox. The code is actually same, the only differences are minor appearance adjustments in manifest.


Check CI config to figure out all the checks I'm doing.

The only test(s) that don't run on CI at the moment (e.g. due to lack of X server) are marked with @skip_if_ci. You can run them manually though.


You can’t perform that action at this time.