Wekan
Open source kanban board application built with Meteor
Alternative to: trello
v10.76
2026-08-09Binaries in these bundles
Each bundle carries a Node.js, a FerretDB and the MongoDB Database Tools. Which source has a given CPU varies from release to release - nodejs.org builds some architectures, unofficial-builds others, and the wekan/node fork the ones neither of them does - and not every source publishes a checksum. This is what went into this release, and which downloads were checked against a published SHA256.
| Bundle | Binary | From | Version | Checked | SHA256 |
|---|---|---|---|---|---|
| arm64 | FerretDB | wekan/FerretDB | latest | verified | 436db5da28b794ab… |
| arm64 | FerretDB | wekan/FerretDB | latest | verified | 436db5da28b794ab… |
| arm64 | Node.js | nodejs.org | v24.19.0 | verified | 01443c1e1a29e531… |
| arm64 | Node.js | nodejs.org | v24.19.0 | verified | 01443c1e1a29e531… |
| armhf | FerretDB | wekan/FerretDB | v1.48.0 | verified | 2232872afa468a83… |
| armhf | FerretDB | wekan/FerretDB | v1.48.0 | verified | 2232872afa468a83… |
| armhf | Node.js | wekan/node-patches | v24.19.0 | verified | b55350f3071b765a… |
| armhf | Node.js | wekan/node-patches | v24.19.0 | verified | b55350f3071b765a… |
| armv7 | FerretDB | wekan/FerretDB | v1.48.0 | verified | 2232872afa468a83… |
| armv7 | FerretDB | wekan/FerretDB | v1.48.0 | verified | 2232872afa468a83… |
| armv7 | Node.js | wekan/node-patches | v24.19.0 | verified | 8dbe0a9aa8550ad5… |
| armv7 | Node.js | wekan/node-patches | v24.19.0 | verified | 8dbe0a9aa8550ad5… |
| i386 | FerretDB | wekan/FerretDB | v1.48.0 | verified | 63d7a9e5e2754cbf… |
| i386 | FerretDB | wekan/FerretDB | v1.48.0 | verified | 63d7a9e5e2754cbf… |
| i386 | Node.js | wekan/node-patches | v24.19.0 | verified | 3b0b3bbfe27daf58… |
| i386 | Node.js | wekan/node-patches | v24.19.0 | verified | 3b0b3bbfe27daf58… |
| mac-arm64 | FerretDB | wekan/FerretDB | latest | verified | d4786d3c1c32ac6b… |
| mac-arm64 | FerretDB | wekan/FerretDB | latest | verified | d4786d3c1c32ac6b… |
| mac-arm64 | Node.js | nodejs.org | v24.19.0 | verified | 3f1cf157479c1480… |
| mac-arm64 | Node.js | nodejs.org | v24.19.0 | verified | 3f1cf157479c1480… |
| ppc64le | FerretDB | wekan/FerretDB | v1.48.0 | verified | 0400cd6dfc3d10d9… |
| ppc64le | FerretDB | wekan/FerretDB | v1.48.0 | verified | 0400cd6dfc3d10d9… |
| ppc64le | Node.js | nodejs.org | v24.19.0 | verified | c510c6ce12f07010… |
| ppc64le | Node.js | nodejs.org | v24.19.0 | verified | c510c6ce12f07010… |
| riscv64 | FerretDB | wekan/FerretDB | v1.48.0 | verified | d37c35af988670b9… |
| riscv64 | FerretDB | wekan/FerretDB | v1.48.0 | verified | d37c35af988670b9… |
| riscv64 | Node.js | unofficial-builds.nodejs.org | v24.19.0 | verified | cd1f14af28121480… |
| riscv64 | Node.js | unofficial-builds.nodejs.org | v24.19.0 | verified | cd1f14af28121480… |
| s390x | FerretDB | wekan/FerretDB | v1.48.0 | verified | 6c7d61fbb8c79b2e… |
| s390x | FerretDB | wekan/FerretDB | v1.48.0 | verified | 6c7d61fbb8c79b2e… |
| s390x | Node.js | nodejs.org | v24.19.0 | verified | a4792e65962ffa0a… |
| s390x | Node.js | nodejs.org | v24.19.0 | verified | a4792e65962ffa0a… |
| win64 | FerretDB | wekan/FerretDB | latest | verified | 25bc69dfb495e2cd… |
| win64 | FerretDB | wekan/FerretDB | latest | verified | 25bc69dfb495e2cd… |
| win64 | Node.js | nodejs.org | v24.19.0 | verified | 57f71ab3652e797d… |
| win64 | Node.js | nodejs.org | v24.19.0 | verified | 57f71ab3652e797d… |
A row saying no checksum published is not a failed check - it is a source that publishes nothing to check against. Those are the ones worth fixing at the source.
v10.76 2026-08-09 WeKan ® release
In short: three round-trip counts that were linear in the input, and are not
any more. The bulk label endpoint asked the database twice per card - a
thousand sequential round-trips at its 500-card cap - global search resolved
each named user with its own lookup before the search could start, and
FerretDB skipped every top-level $or when building a WHERE clause, so the
board-list query narrowed nothing in SQL and filtered every row in Go. None of
them was a wrong answer; each was the right question asked one document at a
time. The binaries below are v10.75’s: nothing here rebuilds them.
| Platform | Binary | From | Version | SHA256 |
|---|---|---|---|---|
| amd64 | Node.js | nodejs.org | v24.19.0 | 14b342e71204f811bde6153be8e04b62aef63c236fef92b55f9c83154b409647 |
| amd64 | FerretDB | wekan/FerretDB | v1.45.0 | 94713f605167abb45a3717482d35de4824cb4a8f199c1400e826a8a2b04f3893 |
| arm64 | Node.js | nodejs.org | v24.19.0 | 01443c1e1a29e531ccad5a46fefa6df490d2189c49f7955904aecdbb0fe86fdc |
| arm64 | FerretDB | wekan/FerretDB | v1.45.0 | 275ae50ac97e6a70eee72e6de37766c458775c5997c896352db5189c6cf1f04b |
| loong64 | Node.js | unofficial-builds.nodejs.org | v24.19.0 | c24f224726f2d785bd18a1fd09f5e6d1fecf0269928451a60c5da9eac8e92e68 |
| loong64 | FerretDB | wekan/FerretDB | v1.45.0 | 28bf67981168dfc4bd67698b41dd62628aafe347a77f2b1e6ffcadf009d575e0 |
| mac-arm64 | Node.js | nodejs.org | v24.19.0 | 3f1cf157479c1480352083105e13faf9d008ede98e7e157746b6df940d197b94 |
| mac-arm64 | FerretDB | wekan/FerretDB | v1.45.0 | 639ed58b84820b3d588f4161c64d0ab940d0cc6e7d022088d60c2b0b97f99f8e |
| mac-x64 | Node.js | nodejs.org | v24.19.0 | d35e95230f46f6f0751df497c56622c6735e05d5e1fb1630996a005b9d328fe4 |
| mac-x64 | FerretDB | wekan/FerretDB | v1.45.0 | fd519903f5630e881e38e7c5814f00c0e89ad26f6785f1ddcbab4058356fc9f3 |
| ppc64le | Node.js | nodejs.org | v24.19.0 | c510c6ce12f07010f771e6edb22a3fe23f4f2e6f40b1ffd4941aed0646a0d8b3 |
| ppc64le | FerretDB | wekan/FerretDB | v1.45.0 | de4518c7774d302533369c477759ddd866785d6741d98d399388eb8de3df175a |
| riscv64 | Node.js | unofficial-builds.nodejs.org | v24.19.0 | cd1f14af2812148002f58b58a5f9af512a50e3b8e8c148e0db44019dcb68edfd |
| riscv64 | FerretDB | wekan/FerretDB | v1.45.0 | 7dc2952f554e8800c4029577901999e06e10272da686f7e402177080067028f9 |
| s390x | Node.js | nodejs.org | v24.19.0 | a4792e65962ffa0af42627aacf1122a60c3c88dbf4e4184f06820d66f9da8ba4 |
| s390x | FerretDB | wekan/FerretDB | v1.45.0 | 0ae2e2f2cffdc5dd2ea4f125281a5e12eea216fbe49b5561d9c001700c3fc0c1 |
| win64 | Node.js | nodejs.org | v24.19.0 | 57f71ab3652e797d84acddc79c81cc9ff1c6ddb2a1974cdb83f00fee9bff4c73 |
| win64 | FerretDB | wekan/FerretDB | v1.45.0 | f6337994368a52d011d438c82b914b0cedb3178fd030acac8db3dab8017cee85 |
This release makes the following faster:
The REST API - how many times one request talks to the database.
Bulk label changes read every card in one query, and write them together. Thanks to xet7.
PUT .../cards/labels awaited a getCard per id and then an update per id. At
the BULK_CARDS_MAX of 500 that is one thousand sequential round-trips for
a single request, each starting only once the last one finished.
The reads are all the same question, so they are one $in query indexed into a
Map. The writes genuinely differ - each card merges its own labelIds - so they
stay individual updates, but they are issued together and awaited once instead
of each waiting for the last.
Two details had to survive. The loop still iterates the caller’s cardIds
rather than the query result, because a batch read comes back in the database’s
order and without the ids that matched nothing: iterating it would silently
reorder updated and lose notFound. And every write is awaited before the 200
is sent, so the response still means what it says.
The bulk DELETE beside it is deliberately left alone. Its per-card work is real
cardRemoverruns the sub-item hooks and each card gets its own activity - so batching the reads would save one query inside a loop that does far more than query.
Global search - what happens before the search itself starts.
Every username a query names is resolved in one lookup. Thanks to xet7.
Each user:, member:, assignee: and creator: predicate resolved its name
with its own awaited findOne, so member:ann member:bob member:carol was
three serial round-trips before the search could begin.
They are all the same question - which of these names is an account - so it is
asked once, with $in, and answered from a map. A name typed under two
operators is one lookup now rather than two.
An unknown name is still reported against the operator it was typed under: “ann is not a user” is not useful without saying where ann was typed.
The database - what SQLite is asked, and what is filtered afterwards.
FerretDB pushes a top-level $or down to SQL when every branch can be. Thanks to xet7.
FerretDB skipped every top-level $-key when building its WHERE clause, so a
selector whose only SELECTIVE terms sit inside an $or produced a clause that
narrowed nothing: SQLite returned the rows, and every one was decoded and
filtered in Go to return a handful.
That is the shape of WeKan’s “which boards may this user see” query, and the
worst possible one for it - archived = false and type = 'board' push down
and match nearly everything, while the membership clauses that actually select
stayed in Go. On an instance with ten thousand boards where a user belongs to
five, that decoded ten thousand documents to return five, on every All Boards
load.
It is all or nothing, and that is the whole subtlety. Every other pushdown
NARROWS: a condition that cannot be expressed is dropped, the WHERE returns a
superset, and the Go filter removes the rest. An OR that drops a branch REMOVES
rows that match it, and the Go filter never sees them. So one unpushable branch
refuses the whole $or, as does a nested-operator branch and an empty one.
See the FerretDB CHANGELOG for the database side.
Thanks to above GitHub users for their contributions and translators for their translations.