Integrate your Raindrop bookmarks into Org-mode.
This package provides:
- A dynamic block
#+BEGIN: raindrop ... #+END:that renders a list of links. - A helper command to use current heading tags to insert/update a links list.
- An Org-babel language
raindropthat returns Org-formatted lists. - An interactive search interface with as-you-type completion and animated spinner.
This is an AI-assisted Emacs package, created in collaboration with a large language model (OpenAI). Requirements and vision were provided by the author.
Search interface
Dynamic block

This package requires Emacs 27.1+ and Org 9.4+.
(use-package raindrop
:defer t
:ensure (raindrop :host github :repo "artawower/raindrop.el"))Org integration
(use-package raindrop-org
:after raindrop
:ensure nil
:defer t)Raindrop search
(use-package raindrop-search
:ensure nil
:after raindrop
:bind (("C-c r s" . raindrop-search))
:defer t)Ob raindrop (dynamic block)
(use-package ob-raindrop
:after (org raindrop)
:commands (org-babel-execute:raindrop)
:ensure nil
:init
(with-eval-after-load 'org
(add-to-list 'org-babel-load-languages '(raindrop . t))
(when (boundp 'org-babel-load-languages)
(org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages))))(package-vc-install '(raindrop :url "https://github.com/artawower/raindrop.el"))
(use-package raindrop)
(use-package raindrop-org :after org)
(use-package raindrop-search)
(use-package ob-raindrop :after org)For security, prefer auth-source:
- Create an entry:
machine raindrop.io login token secret <YOUR_TOKEN>. - Alternatively export env var
RAINDROP_TOKEN. You can also setraindrop-custom-token, but this is less secure.
Example auth-source entry for .authinfo.gpg:
machine raindrop.io login token password 0123456789abcdef
Load packages (autoloads are simple; explicit require is fine):
(require 'raindrop)
(require 'raindrop-org)
(require 'raindrop-search)
(require 'ob-raindrop)Use M-x raindrop-search for an interactive search with as-you-type completion:
- Search by tags:
#emacs #lisp some text - Tags with spaces:
#\"disk usage\" #\"file manager\" backup tools - Exclude tags:
#emacs -#outdated(include emacs, exclude outdated) - Exclude spaced tags:
#cli -#\"old tool\" modern tools - Mixed search:
#programming -#legacy [Work] project - Search by folders:
[Work] project notes - Combined search:
#important [Archive] meeting notes - Animated ASCII spinner during loading
- Smart collection/tag parsing
- Support for all major completion frameworks (Vertico, Ivy, etc.)
Features:
- Press
RETto open the selected bookmark in your browser - Use
M-x raindrop-search-toggle-enter-actionto toggle between opening the original link and the Raindrop app URL - Embark integration for additional actions (edit, delete, open in different ways)
Embark Actions (when using Embark):
o: Open original linkO: Open in Raindrop appe: Edit bookmark in dedicated bufferD: Delete bookmark (with confirmation)c: Create new bookmark (from clipboard/browser)C: Create bookmark from URL in kill ring
Customization:
raindrop-search-idle-delay: delay before API request (default 0.25s)raindrop-search-page-size: number of results per page (default 50)raindrop-search-spinner-frames: spinner animation framesraindrop-search-spinner-delay: spinner animation speedraindrop-search-title-max/raindrop-search-excerpt-max: truncation limits
Create new bookmarks directly from Emacs using these functions:
M-x raindrop-search-create-bookmark: Create bookmark from any URLM-x raindrop-search-create-from-browser: Create from clipboard (browser URL)M-x raindrop-search-create-from-kill-ring: Create from URL in kill ring
All creation functions open an edit buffer where you can:
- Set the title and description
- Add tags (comma-separated:
emacs, productivity, tools) - Customize before saving with
C-c C-c - Cancel with
C-c C-k
The edit buffer automatically detects URLs at point or in clipboard for quick bookmarking.
Add tags to a heading, e.g.:
* Books :book:fiction:
Then run:
M-x raindrop-insert-or-update-links-under-heading
This inserts (or updates) a dynamic block directly in the body of that node, rendering an Org bullet list in the form:
- [[https://example.com][Title]] — optional excerpt
Tip: Use C-u M-x raindrop-insert-or-update-links-under-heading to switch to
OR semantics for tags just for this run; default is AND.
You can insert a block yourself and refresh with C-c C-c:
#+BEGIN: raindrop :tags "emacs, -outdated, programming" :match all :limit 50 #+END:
Parameters:
:tagsstring with comma-separated or space-separated tags. Supports exclusion with-tagsyntax (e.g.,"emacs, -outdated, programming"). Both formats work:"cli -openai macos"or"cli, -openai, macos". Tags with spaces work naturally:"cli, -openai, -tui with space".:foldersstring with comma-separated folder names (e.g.,"work, personal").:folderalias for:foldersthat accepts a single folder name.:searchstring for text search query (e.g.,"machine learning").:exclude-groupsstring with comma-separated tags to exclude from smart grouping (e.g.,"cli, terminal").:matchall(AND, default) orany(OR).:collectionnumeric collection id (optional,0means all). If both:foldersand:collectionare provided, the folder names are resolved to IDs and take precedence.:limitmax items to fetch (default 100).:smartenable smart auto-grouping by tags (tornil, defaultnil).
Examples:
- By folder only:
#+BEGIN: raindrop :folders "Terminal" :match all :limit 20 #+END: - Tags within a folder:
#+BEGIN: raindrop :folders "Work" :tags "cli, -legacy" :match any :limit 30 #+END: - With tag exclusion and smart grouping:
#+BEGIN: raindrop :tags "emacs, -outdated, programming" :match all :limit 25 :smart t #+END: - Tags with spaces and exclusions:
#+BEGIN: raindrop :tags "cli, -openai, -tui with space" :match all :output org-list :smart t #+END: - Text search with tags:
#+BEGIN: raindrop :search "machine learning" :tags "python, ai" :match any :limit 20 #+END: - Text search only:
#+BEGIN: raindrop :search "productivity tools" :limit 15 :smart t #+END: - Smart grouping with excluded groups:
#+BEGIN: raindrop :tags "emacs" :exclude-groups "cli, terminal" :smart t :limit 20 #+END:
Returns Org-formatted output; use :results raw replace:
Also works with folders:
With tag exclusion and tags with spaces:
Space-separated format also supported:
With text search:
Text search only:
You can also enable via babel languages API:
(with-eval-after-load 'org
(require 'ob-raindrop))raindrop-request-timeout: request timeout (seconds).raindrop-default-limit: default fetch limit.raindrop-auth-source-host: host to look up in auth-source.raindrop-token-source: order of token sources (auth-source/env/custom).raindrop-links-empty-text: text when no results.raindrop-heading-tags-match: default AND/OR for heading tags.
- Backend uses
request.elfor HTTP requests andjson-parse-bufferfor JSON parsing. - Content is inserted idempotently inside a dynamic block.
- Title/excerpt are sanitized for single-line list items.
- Interactive search supports vector-to-list conversion for Raindrop API responses.
Any contribution is welcome! Please consider reading the style guide and, if you like this project, supporting via Patreon. Typical contributions:
- Bug reports, feature requests
- Documentation improvements
- Code patches
This project is licensed under GPLv3 or later. Make sure your contributions are compatible with this license.
This project uses ERT tests located under test/.
- Install Eldev by following the instructions at https://github.com/emacs-eldev/eldev.
- From the project root, run:
eldev test
Useful variants:
- Verbose with backtraces:
eldev -dtT test - Select specific tests:
eldev test :selector '"raindrop-parse-tags"'
From the project root:
emacs -Q --batch -L . \
-l raindrop.el -l raindrop-org.el \
-l test/raindrop-core-tests.el \
-f ert-run-tests-batch-and-exitNotes:
- Tests are self-contained and do not require a Raindrop token; they do not hit the network.
- Tests automatically handle the
request.eldependency via Eldev configuration.