I have leaned on Soulver for years. It is the app that worked out the notepad calculator idea: you type in plain language on the left, answers appear on the right, and it updates as you go. No cells, no formula bar, no mode switching. If you use a Mac, I highly recommend you purchase it. that being said, the catch is that Soulver lives on one Mac.
My sheets were on the laptop, which meant they were not on my Windows desktop, and they were certainly not on the machine out in the shop. A notepad calculator that only exists on one device is a document. What I wanted was a service.
So I built Sumline.

What It Looks Like
A sheet is just lines. Some of them do math, some of them are notes, and the engine does not care which is which.
groceries $86.40 #home $86.40
train fare $12.80 #travel $12.80
electricity $94.10 #home $94.10
sum $193.30
sum #home $180.50
Nothing there is a special mode. A line it does not recognize is left alone as plain text with no answer, so headings and notes and running sums all live in the same sheet without fighting each other.
Beyond that it handles what you would expect from this kind of tool. 20% of 250, 10 km in miles, 100 USD in EUR, 5 hours 30 minutes in minutes, next friday, 3 workdays from today. You can set variables like day rate = 550, reference earlier lines with prev or line 3, tag lines with #home and subtotal across the sheet, and write formatting into the line itself with something like 1/3 to 2 dp.
Press ? in the app for the full reference. Every example in that reference is also a passing test, which means the docs cannot claim behavior the engine does not have.
Why a Server Changes Things
That one decision, service instead of document, is where almost every difference from Soulver comes from.
Because there is one instance on the network, there is nothing to sync. Every browser in the house reaches the same sheets. That opened the door to a few things a single-user app has no reason to want: spaces, so I can have separate sets of sheets and variables, or so I can keep work and personal apart. Live updates over an event stream. An editing lock with a conflict panel that shows which lines actually differ instead of silently picking a winner. Share links where every slug a sheet has ever had keeps working. An HTTP API and a CLI, so a launcher and a sheet agree on what day rate * 3 means.
Everything in a sheet is text you typed, formatting included. That is the constraint the rest of the design answers to. Hidden per-line state would not survive a copy, an export, a search, or a line getting moved. Plain text is also what makes diffing two versions possible, which is the only reason the conflict panel can exist.
What It Does Not Do
No conditionals or branching. No live weather or stock prices. Nothing that needs an API key. Nothing native, so no Alfred, no Services, no iOS app.
Exchange rates and public holidays are the only two network calls, both chosen because they need no key, and both fall back to bundled data. The container works with no internet at all.
The engine accepts the phrasings Soulver documents and not much more. That was a decision rather than an oversight. Every phrasing you invent is a rule you maintain, and rules collide.
Running It
git clone https://github.com/philoking/Sumline.git sumline
cd sumline
docker compose up -d --build
Open port 8422 and that is the install. Sheets live in the sumline-data volume and survive restarts and rebuilds. Date math resolves in your browser’s timezone, so today is your today no matter where the container is running.
There is no authentication by default, which is the right call for a trusted LAN and is staying the default. Set SUMLINE_PASSWORD and you get one shared password for the whole instance. It is a door, not a login. There are still no accounts. On plain HTTP that password crosses the network in the clear, so if you are exposing it anywhere, put it behind a proxy that terminates TLS. Mine runs on [server] behind [NPM / Twingate], reachable at [hostname].
Under the hood it is three workspaces. The engine is pure TypeScript with no DOM or Node APIs, pinned by a golden table of input to answer cases. The web side is React and CodeMirror 6, and evaluation happens in the browser so answers never wait on the network. The server is Fastify with SQLite through Node’s built-in node:sqlite.
Credit Where It Belongs
The idea is Soulver’s. Unit assimilation, last currency wins, sum closing a section, prev and line N, per-line formatting written into the line, most of the natural phrasing the engine accepts. All of that was worked out there first, and Soulver’s documentation was the spec I built against. Sumline is an independent implementation, not a port. No Soulver code was used and it is not affiliated with them in any way. If you want the polished native original, go buy it. It is a good app.
Sumline is MIT licensed and up at github.com/philoking/Sumline