Until October, the Wagoe homepage said this:
Each library is a standard
deps.edndependency. Already have Integrant, Reitit and next.jdbc in place? They stay. Addwagoe-userfor auth this week and nothing else — that’s a valid way in.
Next to it sat a stat: Zero lock-in. What I meant was that every Wagoe library is a plain Maven artifact, so you can take one without taking the framework. Then I asked the tool that decides what "one" means.
What -Stree said
An empty directory, one dependency, and a count of what lands on the classpath:
stree() {
clojure -Sdeps "{:deps {com.wagoe/wagoe-$1 {:mvn/version \"$2\"}}}" -Stree \
| awk '!/ X /{for(i=1;i<=NF;i++) if($i~/\//){print $i;break}}' | sort -u \
| awk '/^com\.wagoe\//{w++;next} {e++} /jetty|reitit|muuntaja/{h++} END{print w, e, h+0}'
}
stree user 1.1.1
# 12 146 28
The three numbers are: Wagoe artifacts, the library itself included; every other artifact, Clojure included; and how many of those are Jetty, Reitit or Muuntaja. Lines -Stree marks X (superseded, older version) are not on the classpath and are not counted.
So adding wagoe-user 1.1.1 brings 11 more Wagoe libraries and 146 other artifacts, 28 of them a web server and a router. If you already had Integrant, Reitit and next.jdbc, they stayed, and got a second web stack next to them.
The 1.1 libraries fell into three rings:
-
On their own: cache, config, i18n and ui-style. Realtime needs only i18n.
-
Only
wagoe-core: audience, geo, observability, payments, reports and scaffolder. Ai addswagoe-config. -
Through
wagoe-platform, with Jetty, Reitit, Muuntaja and HikariCP: everything else, including every library the homepage used as an example.
Why the data libraries pulled in a web server
wagoe-platform was one artifact: the HTTP server, the router, the middleware, the system wiring and the database layer. The data libraries only wanted the last part. In 1.1.1, this is everything jobs, events, storage, search, push and webhooks required from it: database, lease, transit, the privacy port, and a few pure HTTP helpers for access checks and error bodies. wagoe-webhooks required exactly one namespace, wagoe.platform.database, and got 28 Jetty, Reitit and Muuntaja jars for it.
Search also declared wagoe-admin, which no file in search required. Nothing checked that a declared dependency was used.
What 1.2 changes
-
wagoe-platform-sqlis a new artifact with platform’s database, migration, seed, lease and transit namespaces, under the same names.wagoe-platformdepends on it, so an app that uses platform changes nothing, and norequirechanges anywhere. Jobs, events, storage, search, push and webhooks now depend on platform-sql instead. -
Unused dependencies are gone: search no longer declares admin, user no longer declares external.
-
Pure helpers moved to
wagoe-core: the privacy port under its old name, and newwagoe.core.http.errorsandwagoe.core.http.accessfor storage and search. The platform namespaces keep every var. -
Jobs no longer depends on tenant. When tenancy is on, tenant hands the job workers a runner.
-
Search’s admin pages load
wagoe-shared-uionly when it is on the classpath. The search API is unchanged.
Run the same function against both versions:
for l in jobs events storage search push webhooks user; do
echo "$l $(stree $l 1.1.1) -> $(stree $l 1.2.0)"
done
| Library | Wagoe artifacts | Other artifacts | Jetty, Reitit, Muuntaja |
|---|---|---|---|
jobs |
7 → 5 |
130 → 69 |
28 → 0 |
events |
6 → 5 |
130 → 69 |
28 → 0 |
storage |
6 → 5 |
249 → 189 |
28 → 0 |
search |
15 → 6 |
146 → 64 |
28 → 0 |
push |
8 → 6 |
147 → 88 |
28 → 0 |
webhooks |
9 → 7 |
130 → 76 |
28 → 0 |
user |
12 → 13 |
146 → 146 |
28 → 28 |
What jobs brings now is next.jdbc, HoneySQL, HikariCP and Migratus: a job queue needs a database. Storage stays the largest because the AWS SDK for S3 is 31 artifacts on its own.
Ring is still in every one of these trees. ring-core arrives through sentry-clj, which wagoe-observability uses for error reporting. So: no web server and no router, but Ring is still there.
The build refuses it now
Cleaning up a dependency tree once is easy. It grows back the next time someone adds a :local/root line because it was quicker than checking. So 1.2 adds two rules to checks that already run in CI.
bb check:deps: a library’s declared Wagoe dependencies must equal the ones its src/ requires, in both directions. Add wagoe/platform to geo’s deps.edn without using it, and:
Dependency direction violations found: VIOLATION: geo declares platform but nothing in its src/ uses it — remove it from geo/deps.edn :deps, or name the resource under :wagoe/resource-deps 1 violation(s) found.
bb check:fcis: core/ and ports know no SQL. They may not require honey.sql, next.jdbc or wagoe.platform.database, and a port signature may not name a SQL type. This is what keeps a library’s logic from quietly needing platform-sql again. Require honey.sql in wagoe.geo.core.address, and the pre-commit hook says:
FC/IS violations found:
VIOLATION: …/libs/geo/src/wagoe/geo/core/address.clj
namespace wagoe.geo.core.address requires honey.sql — core/ and ports know no SQL
1 violation(s) found. Core namespaces must not import shell, I/O, logging, or DB code, throw, or hold mutable state; core and ports know no SQL.
Both messages come from a scratch copy of the repository with those two edits; neither edit exists in Wagoe.
What is still not true
User, tenant, admin, workflow, calendar, email and external still run on wagoe-platform. User and tenant register with platform’s system wiring and interceptors and use its authorization and page helpers. Admin is CRUD screens over your tables and the authorization and navigation around them. Workflow builds on admin and user. Calendar renders with wagoe-shared-ui, which needs platform’s CSRF, page and navigation helpers. Email sends through external, which uses platform’s RPC client and its retry and circuit breaker. The table above says it for wagoe-user: in 1.2 it brings 12 other Wagoe libraries and the same 28 Jetty, Reitit and Muuntaja artifacts. If you already have Integrant, Reitit and next.jdbc wiring, adding wagoe-user means replacing that wiring, not running beside it.
What the homepage says now
The sentence about wagoe-user is gone. The homepage now says:
Audience, geo, observability, payments, reports and scaffolder only need
wagoe-core(Clojure and Malli), and ai also needswagoe-config. Cache, config, i18n and ui-style need nothing, and realtime only needs i18n. These drop into any project.Jobs, search, events, storage, push and webhooks bring next.jdbc, HoneySQL, HikariCP and Migratus through
wagoe-platform-sql, but no web server or router. Runclojure -Streeand you won’t find Jetty, Reitit or Muuntaja.User, tenant, admin, workflow and the rest run on
wagoe-platform, which has its own Integrant, Reitit and next.jdbc wiring. If your app already has that wiring, addingwagoe-usermeans replacing yours.
Every number in this post comes from the stree function above. Paste it into a shell and run it. If you get a different number, open an issue: either the post is wrong or the build let something through, and I want to know which.