How should next-generation plugins work?

93 views
Skip to first unread message

Simon Guest

unread,
Mar 2, 2026, 5:00:03 PM (4 days ago) Mar 2
to bean...@googlegroups.com
A limabean issue has raised a question about how plugins should work, and highlighted that my approach in limabean differs from the historical behaviour.

It comes down to, what are plugins for, actually?

The specific plugin which initiated the discussion was zerosum. Currently it is not possible to run such a plugin in limabean because limabean plugins run after the booking process has completed, and until such a plugin has run the beanfile is invalid.

My first instinct was, well, fix the beanfile!  That particular plugin seems to be a mitigation for an import process which doesn't pair transactions between accounts, in contrast to limabean-harvest for example, which handles transaction pairing across accounts on import.

My proposed mitigation for what I am calling such breakage (sorry) in beanfiles would be to run user-defined functions over the beanfile whose final output would be a fixed-up beanfile which passes validation.

I understand there is legacy behaviour here.  But the vNext document has some interesting plugin-related discussion, which says:

Furthermore, there may be two types of plugins: a plugin that runs on the uninterpolated, unbooked output of the parser, and a plugin that runs on the resolved and booked stream. This would allow more creative use of partial input that might be invalid under the limitations of interpolation and booking.
Updates:
- We could convert the plugin system to one that runs at booking/interpolation time.


I am interested to understand other scenarios which would illuminate design choices here.

Damien R.

unread,
Mar 3, 2026, 9:57:51 AM (4 days ago) Mar 3
to Beancount
To chime in on the topic, I don't know if you're aware of that list of plugins but that might give you a larger idea of how they operate on the ledger: https://github.com/beancount/beanlabs/tree/master/beanlabs/plugins

One of the plugin I rely on is ira_contribs.py (actually my own spin of it, adapted for Canadian tax-deferred and tax-free accounts). It adds postings to some transactions to help keep track of allowed contributions to those accounts. So for instance, if I transfer 1000 CAD from my checking account to a tax-deferred account, the plugin adds extra-postings to the transaction to decreased my "Assets:Allowance:TaxDeferred" account by the same amount. I don't know if such a plugin would work with limabean or not.

So maybe you've made transaction pairing first-class citizen in limabean-harvest, but current beancount plugins can get pretty creative and you're going definitely have breakage if you change when plugins run. My personal 2 cents: the community is small already, so I would be careful to not introduce new not-retrocompatible ways of doing things.

redst...@gmail.com

unread,
Mar 3, 2026, 2:42:47 PM (3 days ago) Mar 3
to Beancount
Le lundi 2 mars 2026 à 17:00:03 UTC-5, Simon Guest a écrit :
A limabean issue has raised a question about how plugins should work, and highlighted that my approach in limabean differs from the historical behaviour.

It comes down to, what are plugins for, actually?

The specific plugin which initiated the discussion was zerosum. Currently it is not possible to run such a plugin in limabean because limabean plugins run after the booking process has completed, and until such a plugin has run the beanfile is invalid.

My first instinct was, well, fix the beanfile!  That particular plugin seems to be a mitigation for an import process which doesn't pair transactions between accounts, in contrast to limabean-harvest for example, which handles transaction pairing across accounts on import.

FWIW, the issue that zerosum addresses isn’t about mitigating pairing deficiencies at import. Its purpose is to support asynchronous imports of the two sides of a transaction and to accurately represent transfers that are temporarily “in flight.”

Financial institutions differ in how up-to-date their transaction feeds are, and in practice users often import some accounts frequently while updating others only periodically. As a result, asynchronous imports are often unavoidable. In the U.S., transfers also do not settle instantly, which can complicate synchronization with an institution’s transaction sequence and balance assertions. One alternative is to reconcile and rewrite the existing ledger once the second side of a transfer arrives, but that approach carries its own trade-offs rather than being a clearly superior solution.

Anyway, I digress. Other plugins like opengroup, and possibly rename_accounts and effective_date need to run early in the proccess. Not to mention homecooked plugins.

 On Tuesday, March 3, 2026 at 6:57:51 AM UTC-8 Damien R. wrote:
One of the plugin I rely on is ira_contribs.py (actually my own spin of it, adapted for Canadian tax-deferred and tax-free accounts).. [...]
So maybe you've made transaction pairing first-class citizen in limabean-harvest, but current beancount plugins can get pretty creative and you're going definitely have breakage if you change when plugins run. My personal 2 cents: the community is small already, so I would be careful to not introduce new not-retrocompatible ways of doing things.

Emphasis mine, +1.

Simon Guest

unread,
Mar 3, 2026, 3:52:34 PM (3 days ago) Mar 3
to bean...@googlegroups.com
I am coming to terms with the fact that I will have to embrace the need for early-run plugins in limabean!  Which means I will likely have to redo my Rust implementation of the Beancount booking algorithm in Clojure.  Ah well, such is life. 😅

I envisage having two places where plugins can run, one on the raw just-parsed directives where nothing has yet been validated or balanced, and the other after booking and balancing.  A plugin will be clearly defined to be for one or other of these (but not both).

Thanks to you both for the feedback, really appreciated.  Brief conversations like this are immensely helpful for steering things along in the right direction!  And I surely agree with the goal of not fragmenting the community.

--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/beancount/ba1553b5-0e2a-4c20-80be-d64d14c83c58n%40googlegroups.com.

Vasily M

unread,
Mar 3, 2026, 5:21:38 PM (3 days ago) Mar 3
to Beancount
Just to add to the already present comments.
I personally was attracted by flexibility and simplicity of Beancount plugin system and have invested time and effort into extensions via plugins while working on https://github.com/Evernight/lazy-beancount/. Most of them can be found here: https://github.com/Evernight/beancount-lazy-plugins (and Fava-related are in their own repos). Not sure how many other users there actually are of each particular one or of the setup as a whole, besides me though – since there's no telemetry (and won't be). The main project also links to more established plugins and collections that I found useful (and you can find more at awesome-beancount).

Because of some behaviour I wanted to achieve I have to enable 

  option "plugin_processing_mode" "raw"

in the configs which allows to control ops.pad and ops.balance plugins manually. Overall plugin order matters and that makes config editing somewhat error-prone.

It would be really cool to be able to migrate to a faster, more efficient backend like limabean at some point. Although since Fava is not supported not sure how possible it would be for Lazy Beancount for the time being at least. For now I'd tolerate longer loading time or even consider pruning ledger or other techniques as a tradeoff.

In any case it might give additional data points as you were looking for the plugin examples. I got maybe a bit further into plugin addiction than an average Beancount user but it just was interesting to experiment with solving different use-cases and trying out ideas in that system.

Martin Blais

unread,
Mar 4, 2026, 8:12:04 AM (3 days ago) Mar 4
to bean...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.

Tim Tickner

unread,
Mar 4, 2026, 9:28:03 AM (3 days ago) Mar 4
to Beancount
Ditto - adding to the already present comments.

I use a handful of the builtin plugins that you've already talked about being covered (check_commodity, coherent_cost, implicit_prices), some fava ones (tag_discovered_documents, link_documents), autobean (stock_split, narration), redstreet (zerosum, effective_date), and then a few home-baked plugins that just work well for my workflow (controlling tags and metadata from a master list, promoting a posting level metadata "tag" to a transaction level proper tag, and adding descriptions to matched zerosum transactions so I know which account the transfer is with).

I think I could do without my home-baked ones, but they are fun to just mess with. They open a whole world of possibility with beancount, and I imagine have helped spur adoption of the tool.

To call out zerosum specifically, I use it with my institution imports where the debit and credit fall on different days. I'd be pretty sad to lose that one in particular.

Excited to see limabean with such active development and will be sure to try it soon!

Justus Pendleton

unread,
Mar 4, 2026, 5:54:01 PM (2 days ago) Mar 4
to Beancount
On Wednesday, March 4, 2026 at 6:12:47 AM UTC+10:30 redst...@gmail.com wrote:

in practice users often import some accounts frequently while updating others only periodically

This is the main use case for me personally. For most accounts, I only update them when I'm send a statement. That means I'll update one bank on the 1st (they have fast computers?), another bank on the 5th, my credit card statement always comes on the 25th, etc. I've also done international wire transfers between my accounts which can (depending on the countries and correspondent banks involved) can take anywhere from 6 hours to 6 days.

I'm fine with that "eventual consistency" approach and I think most users probably are. If I do an international wire transfer for a house deposit, it is in some sense accurate to treat that as my net worth dropping by several hundred thousand dollars until it eventually arrives in another account. After all, I have seen wire transfers go astray (wrong instructions, bank mistakes, etc) so it isn't really "mine" until it reappears. But it also feels like making things far too complicated in the name of chasing perfect fidelity.

That said, I'm definitely sympathetic to the thought that this is such a common use case it (along with the similar but slightly different effective_date plugin) is functionality that probably ought to be a core part of an accounting system, instead of the current (nearly universal, not just in beancount) fiction that transactions are instantaneous and nothing is ever pending.

redst...@gmail.com

unread,
Mar 4, 2026, 6:24:55 PM (2 days ago) Mar 4
to Beancount

in practice users often import some accounts frequently while updating others only periodically

This is the main use case for me personally. For most accounts, I only update them when I'm send a statement. That means I'll update one bank on the 1st (they have fast computers?), another bank on the 5th, my credit card statement always comes on the 25th, etc. I've also done international wire transfers between my accounts which can (depending on the countries and correspondent banks involved) can take anywhere from 6 hours to 6 days.

I'm fine with that "eventual consistency" approach and I think most users probably are. If I do an international wire transfer for a house deposit, it is in some sense accurate to treat that as my net worth dropping by several hundred thousand dollars until it eventually arrives in another account. After all, I have seen wire transfers go astray (wrong instructions, bank mistakes, etc) so it isn't really "mine" until it reappears. But it also feels like making things far too complicated in the name of chasing perfect fidelity.

Agree. For me it’s less about fidelity and more about practicality. If I force a transaction to appear earlier or later than when the bank records it, the running balances no longer line up with the bank’s statements, and balance assertions start failing, and troubleshooting becomes messy.

 
That said, I'm definitely sympathetic to the thought that this is such a common use case it (along with the similar but slightly different effective_date plugin) is functionality that probably ought to be a core part of an accounting system, instead of the current (nearly universal, not just in beancount) fiction that transactions are instantaneous and nothing is ever pending.

Agree. The Vnext doc already mentions these ideas, and they’re quite close to the ones you listed above, but in my view they could still benefit from another round of design iteration.

redst...@gmail.com

unread,
Mar 4, 2026, 6:28:09 PM (2 days ago) Mar 4
to Beancount
a few home-baked plugins that just work well for my workflow (controlling tags and metadata from a master list, promoting a posting level metadata "tag" to a transaction level proper tag, and adding descriptions to matched zerosum transactions so I know which account the transfer is with).

Zerosum can add links for you, if that helps.

Simon Guest

unread,
Mar 4, 2026, 7:25:52 PM (2 days ago) Mar 4
to bean...@googlegroups.com
Thanks! 

Putting that together with what others are saying suggests that I'm finally on the right track, with two types of plugin. The original type (which I had hoped would be all that was needed) operating on fully booked transactions and other directives. But the other type we do in fact seem to need, operating on raw directives before validation. 

In limabean these use different data structures, and up until now the raw transactions from the parser haven't been available to user-defined code. I'm going to allow that soon, but it's quite a bit change alas.

Tim Tickner

unread,
Mar 4, 2026, 10:29:50 PM (2 days ago) Mar 4
to Beancount
@redstreet - I opened this issue to describe what my zerosum plugin-on-a-plugin does. I'm curious to get your thoughts, could we have this conversation there? 
Reply all
Reply to author
Forward
0 new messages