This library was born out of a desire to have a basic understanding of my web projects’ visitors and a lack of desire to set up anything.
clj-simple-stats, as the name suggests, is trivial to set up:
io.github.tonsky/clj-simple-stats {:mvn/version "1.1.0"} to deps.edn.clj-simple-stats.core/wrap-stats anywhere in your middleware stack.That’s it! There’s no step 3.
clj_simple_stats.duckdb in the current dir./stats that looks like this:
Couple of highlights:
text/html, application/atom+xml or application/rss+xml are countedThese default values are used; feel free to override:
(wrap-stats handler
{:db-path "clj_simple_stats.duckdb"
:uri "/stats"
:dash-perms-fn (fn [req] true)
:cookie-name "stats_id"
:cookie-opts {:max-age 2147483647
:path "/"
:http-only true}})
wrap-stats is a composition of wrap-collect-stats and wrap-render-stats, which you can use separately as well.
Finally, wrap-render-stats middleware checks if (= (:uri opts) (:uri req)) and then calls render-stats handler. If you prefer to use your own router, feel free to use render-stats handler directly.
Q: Will this work with static websites? E.g. served fully by Nginx? A: Unfortunately, no. This is designed to sit in your Ring middleware stack.
Q: How can I select time intervals? A: Select whole years at the top of the page. Select whole months by clicking their labels in the graph. Everything else only by modifying URL params. Might change later.
You can see live deployments at
Copyright © 2025 Nikita Prokopov
Licensed under MIT.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |