Things 3 Plugin - proof of concept and feedback

Inspired by obsidian-things-logbook/ at main · liamcain/obsidian-things-logbook · GitHub

I decided to try to port this to Logseq.

The first issue I ran into was despite being written in ClojureScript and one of the reasons I was drawn to logseq, the plugin libs are not ClojureScript friendly and could not be imported with shadow-cljs in the traditional manner requiring use of js interop. But there are some good cljs libraries for interop that it was easy enough to use interop syntax.

The next issue I ran into was that plugins are sandboxed and I could not directly query the Things 3 sqlite database as is done in the obsidian plugin. So to work around Things 3 not having an API I decided to spin up an HTTP server on my local machine to dump all the data. At first, this seemed a bit unnecessary work (and a potential security issue at the moment as anyone on the local network can potentially access my things db while the service is running), but this may prove to be useful when mobile comes out as I could potentially still have it connect to my computer. I’m not sure yet how to improve discoverability other than manually inputting the computer IP address and port if anyone has thoughts on that I’d be interested in how one might be able to discover if the service is running on the local network without the need for some internet service to serve as a registry (although I guess if needed I could create one).

The implementation as of yet is coming along okay. Few things in API not working quite as expected.

insertBlock on an empty page didn’t seem to work for me… I would expect that given a page block as srcBlock it would insert the block on the page, but it seemed to do nothing or create an orphan block. After asking in discord I discovered I needed to specify isPageBlock. I think this is potentially something the API could figure out if the given block is a page insert it on the page, but it works well enough if inserting relative to getCurrentBlock.

getCurrentPage sometimes returned nil even when getCurrentBlock worked and included page ref so I created helper function to use getPage(getCurrentBlock().page) if getCurentPage returned nil.

datascriptQuery expects a raw string and doesn’t take any parameters or rules, for now, I just build the values into the query, but not being able to specify rules may significantly limit potential queries particularly recursive queries which seem particularly useful in this context.

If you use Things 3 and are interested in the ability to sync with Logseq let me know.

Mostly I’m interested in syncing the logbook to reflect and organize the notes I take on tasks (mostly because it has a good mobile app so I take notes there and sync using obsidian). But logseq works way better for me Obsidian when it comes to mining my notes for relationships. I have some ideas on how to make the sync bidirectional using apple script (updating the sqlite database directly unfortunately does not push updates to mobile app), but it is a lot more work so I may not do it for myself.

You can find the first draft of the plugin here

In response to your question, I am definitely interested in the ability to sync Things 3 with Logseq.

To be upfront, I won’t be much help in a practical sense as I’m not a programmer. However, I can do my best to test, etc.

I currently use org-roam v2 in doom emacs and have been manually transferring and re-sorting Things 3 Logbook entries to the pertinent daily note at the end of the day.

I began experimenting with Logseq a few days ago and fwiw, I would find the functionality your roadmap suggests to be extremely useful.


Sounds good. I don’t currently need or want help with development just yet, but seeing if others are intrested will help me stay motivated to clean up the code, add tests and improve over all ux that I may not otherwise do if no one is interested.

The proxy is a complete hack at the moment. I dont recommend using it just yet, but now that I can implement a minimum viable plugin my next task is to add tests and start to refactor and clean up code.

I’ll ping you when the core code is bit more stable


Awesome. Likely you’re aware of this app that queries the things db and creates a kanban board, but in case not, here’s a link. It’s in python but maybe it proves useful or at least interesting.

Anyway, wishing you good progress.


Another approach might be to use the OSA scripting facility in Things3. I have no idea how hard/easy it is to do so within LogSeq.

Hi there @Kurt_Harriger ! Are you still working on this? I’d love to be able to integrate these two :slight_smile:

1 Like

Thank you for the initiative.

What’s your timeline for releasing the Things plugin?

My door’s always open for collaborating or testing.



1 Like

I have mostly stopped using things 3 and have lost interest in the project. I tried to use more native logseq functionality.

FYI if anyone has a similar workflow.

I’ve a personal plugin I use to send items to Things3 as I don’t use Logseq for tasks. This plugin allows you to right-click a block and send it’s contents and block URL to Things3.

Github: GitHub - hkgnp/logseq-sendtothings3-plugin: logseq-sendtothings3-plugin

Unfortunately, as tasks retrieval from Things3 requires quite a bit of work to parse through an sqlite3 database, I do not have plans for it.