TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Hledger: Robust Plain Text Accounting

236 pointsby lwhsiaoalmost 6 years ago

19 comments

simonmicalmost 6 years ago
I&#x27;m hledger&#x27;s lead developer, thanks for the mention. If you have any questions or hit any snags trying it out, I&#x27;m ready to help. Critique of product, docs etc. is welcome. Last time (2017) we got 2 out of 41 comments about hledger, so I&#x27;m hoping for a few more. :) <a href="https:&#x2F;&#x2F;hledger.org&#x2F;release-notes" rel="nofollow">https:&#x2F;&#x2F;hledger.org&#x2F;release-notes</a> has the (software) changes since then. Our chat is #hledger on Freenode: <a href="http:&#x2F;&#x2F;webchat.freenode.net&#x2F;?channels=hledger" rel="nofollow">http:&#x2F;&#x2F;webchat.freenode.net&#x2F;?channels=hledger</a>
评论 #20021861 未加载
评论 #20020196 未加载
评论 #20019508 未加载
评论 #20019682 未加载
评论 #20020204 未加载
评论 #20019740 未加载
stevesimmonsalmost 6 years ago
These ledger formats have what feels to me an overly verbose multi-line structure for each transaction.<p>For 20 years, I have been using a format that combines a diary and ledger. The &#x27;to&#x27; and &#x27;from&#x27; accounts are either bank&#x2F;asset accounts (sav, cc, hl for home loan, ...) or spend categories (snack, shopping, clothes, ... ). Each year I finish 31 December with a `# Closing balances` section for each bank&#x2F;investment&#x2F;pension account, then start a new text file `2019.txt` with an `# Opening balances` section before 1 January&#x27;s entry.<p>Here is a typical day&#x27;s format:<p><pre><code> # 2019-05-27 Mon 2.50 sav&gt;lunch Cafe Nero - Coffee 100.00 sav&gt;cc Transfer - Credit card repayment amt from&gt;to forex: shop - desc [txn #] # Diary * &lt;topic&gt; - &lt;what&gt; * Times - Sleep 01:00-06:00 5h. Run 45m. Work 08:00-18:00 10h. * Work - Meeting with xxx on xxx. We agreed to xxx. * Friends - Lunch with xxx * Note - Running shoes are Asics GT-2000, size 48, model T500N. # Links * Hledger: Robust plain text accounting - https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=20012499 </code></pre> For the first 5 years, I was single and reconciled everything down to the cent, using an AWK script to generate totals to match against my bank statements.<p>When I got married, all our accounts switched to joint ones. I didn&#x27;t want to track my my partner&#x27;s side of our spending. So these logs became more a personal diary than a fully reconciled ledger. Anything I want to remember long-term goes either there or secured in a password safe.
评论 #20021333 未加载
评论 #20022672 未加载
评论 #20022892 未加载
merurualmost 6 years ago
See also <a href="https:&#x2F;&#x2F;plaintextaccounting.org" rel="nofollow">https:&#x2F;&#x2F;plaintextaccounting.org</a> for more on the broader ledger ecosystem.
评论 #20020750 未加载
AdamGibbinsalmost 6 years ago
Personally I prefer beancount, incredibly pluggable in python (imo a friendlier language to haskell), additionally much stricter in multiple aspects. Been maintaining my ledger with ledger-cli and then beacount for 10 years now.
评论 #20018607 未加载
edwintorokalmost 6 years ago
I&#x27;ve recently come across two systems that use hledger for processing bank statements: <a href="https:&#x2F;&#x2F;pauley.org.za&#x2F;hledger-flow&#x2F;" rel="nofollow">https:&#x2F;&#x2F;pauley.org.za&#x2F;hledger-flow&#x2F;</a> <a href="https:&#x2F;&#x2F;github.com&#x2F;adept&#x2F;full-fledged-hledger&#x2F;wiki" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;adept&#x2F;full-fledged-hledger&#x2F;wiki</a><p>They treat the statements as the single source of truth, with preprocessing and rules that can be used to turn them into hledger journals.
评论 #20024633 未加载
enriqutoalmost 6 years ago
I would appreciate a small section on the README file that explains how to compile the program, what are the requirements (e.g., what debian packages to install), and a minimal cli use case.<p>Also, running &quot;make&quot; prints a daunting 96 lines of text of which the last 50 (the ones that you get to see) are mostly useless. If I run &quot;make build&quot; it starts to download stuff from the internet, which I find extremely impolite, as I already downloaded the source code. What is the point of not including all the neeedded source code in the source distribution?
评论 #20022602 未加载
评论 #20019713 未加载
sctbalmost 6 years ago
Discussion from 2017: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=15818682" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=15818682</a>.
tanguealmost 6 years ago
If you&#x27;re using Emacs and are not familiar with double-entry accounting this video is a good introduction : <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=cjoCNRpLanY" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=cjoCNRpLanY</a> (it&#x27;s based on ledger not hledger)
Neradaalmost 6 years ago
Does Hledger support encrypting the ledger file? I don&#x27;t mean placing the ledger in an encrypted container and mounting&#x2F;unmounting as necessary, but I guess &#x27;natively&#x27; as part of the file (think an encrypted Excel document).<p>I&#x27;m a GnuCash user, but my biggest gripe is not being able to encrypt my accounting file. I&#x27;d love to have it sync across my devices via x cloud platform, but I&#x27;m always paranoid about uploading anything that isn&#x27;t password protected. If I was able to do that it&#x27;d be the push that gets me to switch from the GnuCash GUI to a plaintext account.<p>Maybe there&#x27;s some other way I haven&#x27;t thought of without a high barrier to entry like constantly mounting and unmounting an encrypted container to make changes.
评论 #20017928 未加载
评论 #20018163 未加载
评论 #20018219 未加载
评论 #20017911 未加载
评论 #20019548 未加载
HorizonXPalmost 6 years ago
I just spent the last week reconciling my books, using my scores of Excel files as a source, moving them to ledger.<p>I learned rudimentary double-entry accounting in high school, and I love that ledger enforces it so that I can be strict about my tracking. I still have to figure out how to produce balance sheets and income statements so that I can confirm that my accounts are balanced correctly. Honestly wish I had done this sooner.<p>Edit: Looking at beancount again, I should just use that instead of ledger. Ledger&#x27;s simple, elegant, and nice, but I&#x27;m a Python guy, and I should just use what I know.
accrualalmost 6 years ago
I&#x27;ve used the original ledger [0] for a few years to track my day-to-day cash flow and appreciate the simplicity. I create a new file every year and manage it with standard Unix tools, plus a few shell and Python wrappers to make entries and reports a little easier.<p>The hardest part is just getting started and getting into the habit of maintaining the ledger. Once you start tracking it&#x27;s difficult to stop! Seeing all of your accounts line up is a reward in itself.<p>[0] <a href="https:&#x2F;&#x2F;www.ledger-cli.org" rel="nofollow">https:&#x2F;&#x2F;www.ledger-cli.org</a>
fiatjafalmost 6 years ago
See also <a href="http:&#x2F;&#x2F;hledger.alhur.es&#x2F;" rel="nofollow">http:&#x2F;&#x2F;hledger.alhur.es&#x2F;</a>, hledger compiled for the web in a playground (you can also save your stuff to remoteStorage).<p>Source: <a href="https:&#x2F;&#x2F;github.com&#x2F;fiatjaf&#x2F;hledger-web" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;fiatjaf&#x2F;hledger-web</a>
techntokealmost 6 years ago
hledger looks pretty amazing, but there are so many dependencies and updates with Haskell programs. Almost every other day I&#x27;m updating like 20 Haskell packages for hledger or pandoc when I run a system update. It isn&#x27;t inherently bad, but never had this issue with a C or Go program.
评论 #20018587 未加载
评论 #20021755 未加载
评论 #20019023 未加载
评论 #20018853 未加载
ryanobjcalmost 6 years ago
Hledger is pretty good for basic accounting. I recently had to do some tracking of stocks and lots and forex and the developers decided not to implement lot-based tracking. Which made it impossible to accurately track money.<p>So back to plain ledger. If I was starting over I&#x27;d probably consider beancount. But there&#x27;s only so much I can do a day.
评论 #20019319 未加载
z3t4almost 6 years ago
A ledger should be a database with only select and insert privileges. eg. No update or delete queries should be allowed.
评论 #20019170 未加载
评论 #20019560 未加载
评论 #20022339 未加载
评论 #20020211 未加载
noufalibrahimalmost 6 years ago
I used to be a heavy ledger-cli user and wrote about my setup here <a href="http:&#x2F;&#x2F;nibrahim.net.in&#x2F;2015&#x2F;11&#x2F;07&#x2F;ledger_and_personal_finance.html" rel="nofollow">http:&#x2F;&#x2F;nibrahim.net.in&#x2F;2015&#x2F;11&#x2F;07&#x2F;ledger_and_personal_financ...</a>
评论 #20021213 未加载
mongolalmost 6 years ago
I looked into plain text accounting but Swedish bookkeeping&#x2F;accounting practises forbid practises where past records can be modified. It needs to be append-only. I started developing a command line accounting tool using SQLite and Go but it is only half-finished.
评论 #20023318 未加载
评论 #20021239 未加载
billfruitalmost 6 years ago
Does it do &#x27;envelope&#x27; style budgets like YNAB?
评论 #20022986 未加载
kazinatoralmost 6 years ago
This is exactly how I do my accounting: record transactions in a plain text file, which is processed by the system, resulting in various ledger and account type objects being in a certain state, which can then be subject to queries and reports.<p>Mine is written in TXR Lisp. It is not released to the public.<p>All input is recorded via function call expressions, which are of course S-exps. There is only one single macro in the whole thing: <i>def-date-var</i> defines a variable that exhibits different values depending on a effective date context (established by a dynamically scoped date variable). With this we can do things like different tax rates for different periods, without having to introduce such things as parameters appearing in every input item.<p>&gt; <i>The amounts within a transaction must always sum up to zero. As a convenience, one amount may be left blank; it will be inferred so as to balance the transaction.</i><p>I also have transactions that sum to zero. There can be three or more account deltas in a transaction, not only two.<p>This is not how accounting is taught in North America, though; I came up with it myself.<p>Inferring one amount is a bad idea. My system throws an exception if the transaction amounts do not add to zero.<p>However, the entry of items is done via various convenience functions, most of which generate the necessary transactions against all the right accounts. For instance, recording a new asset:<p><pre><code> (record-asset 1 &quot;Discombobulator&quot; :cca-50 ;; ID, description, capital-cost-allowance class (date 2017 1 23) ($ 79.99) ($ 4.00) ($ 5.60)) ;; base price, GST, PST taxes. </code></pre> From the looks of the journal format of hledger, it&#x27;s too generic. I wouldn&#x27;t want to use anything of the sort.<p>Different items need their own syntax. I don&#x27;t want to record a simple purchase of a recurring expense in the same way that I record an invoice.<p>I bind a new variable when recording an invoice:<p><pre><code> (defparml %inv-0042% (new invoice number 42 provider %my-addr% client %foo-client-addr% remit-to &quot;Kazinator&quot; remit-days 25 date (date 2017 6 30) items (list (new time-unit start (date 2017 6 1) end (date 2017 6 2) hours 16 rate %rate-foo-client-2017%) (new time-unit start (date 2017 6 5) end (date 2017 6 9) hours 40 rate %rate-foo-client-2017%) (new time-unit start (date 2017 6 12) end (date 2017 6 16) hours 40 rate %rate-foo-client-2017%) (new time-unit start (date 2017 6 19) end (date 2017 6 23) hours 40 rate %rate-foo-client-2017%) (new time-unit start (date 2017 6 26) end (date 2017 6 30) hours 40 rate %rate-foo-client-2017%)))) </code></pre> There is no custom DSL here at all; just the <i>new</i> macro of the object system.<p>This is then recorded using a plain function call to the convenience function <i>record-invoice</i>:<p><pre><code> (record-invoice %inv-0042% &quot;Invoice 0042 issued to Foo, Inc.&quot;) </code></pre> This function will digest the invoice and post the right amounts into various accounts. The GST tax has to be charged, and such,<p>When the invoice is paid:<p><pre><code> (record-paid-invoice %inv-0042% &quot;Invoice 0042 paid by Foo, Inc.&quot; (date 2017 7 31)) </code></pre> this function will also update multiple accounts, including the automatic withholding of income tax, based on the withholding rate configured for the date into which the invoice lands.<p>To generate a nice HTML invoice, at the REPL, I just call the .(html ...) method of the invoice object, which takes a stream argument.<p><pre><code> 1&gt; (with-stream (s (open-file &quot;invoice.html&quot; &quot;w&quot;)) %inv-0042%.(html s))</code></pre>