Where Incanter still fits in Clojure, how to use its stats and chart modules, and how it compares with the newer Scicloj-centered data stack.
Incanter is an important part of Clojure’s data-science history, but it is no longer the default center of gravity for modern Clojure analytics work. That distinction is the main thing older tutorials miss. Incanter is still useful, still readable, and still perfectly capable for some local statistical tasks. But contemporary Clojure data work more often gathers around the broader Scicloj ecosystem and tech.ml.dataset-oriented tooling.
So the right way to teach Incanter in 2026 is neither “ignore it” nor “pretend it is the only serious option.” The better approach is to explain where it still shines, where it shows its age, and how to make a practical choice.
The Incanter project describes itself as a Clojure-based, R-like statistical computing and graphics environment for the JVM. That framing still captures its appeal:
For a developer who wants to stay inside one Clojure process and perform quick statistical work, that can still be attractive.
Incanter is strongest when:
It is weaker when:
That is why the modern conversation usually includes Scicloj, Noj, scicloj.ml, and tech.ml.dataset-centric tools rather than treating Incanter as the default first stop.
Older Incanter tutorials are often project.clj-first. A cleaner default now is deps.edn, and it is usually clearer to depend on the modules you actually need:
1{:paths ["src"]
2 :deps {org.clojure/clojure {:mvn/version "1.12.0"}
3 incanter/incanter-core {:mvn/version "1.9.3"}
4 incanter/incanter-stats {:mvn/version "1.9.3"}
5 incanter/incanter-charts {:mvn/version "1.9.3"}}}
That keeps the example aligned with the modern Clojure toolchain even if the library itself comes from an earlier era of the ecosystem.
Here is the kind of job Incanter still handles well: summarize a small numeric sample and render a quick chart.
1(ns myapp.stats
2 (:require [incanter.stats :as stats]
3 [incanter.charts :as charts]))
4
5(def latency-ms [82 79 90 88 77 84 95 91 80 86 83])
6
7(def summary
8 {:mean (stats/mean latency-ms)
9 :median (stats/median latency-ms)
10 :sd (stats/sd latency-ms)})
11
12(def histogram
13 (charts/histogram latency-ms
14 :nbins 6
15 :title "Latency Distribution"
16 :x-label "Milliseconds"
17 :y-label "Frequency"))
That example is good Incanter territory:
If your question is this small and this local, Incanter can still feel pleasantly direct.
Incanter’s age becomes visible in three places.
Modern Clojure data workflows more often revolve around richer, more interoperable tabular data tooling. In practice, many teams now want dataset abstractions that fit smoothly into a larger pipeline of cleaning, feature engineering, notebook exploration, and model training.
Many older Incanter examples assume local windowed chart display as a normal default. That was more natural in an earlier JVM-centric analytics workflow. Today, browser-first and notebook-first flows are more common.
The Scicloj ecosystem now offers a more integrated story for:
That does not make Incanter “wrong.” It just changes the default recommendation.
flowchart LR
A["Small Local Statistical Task"] --> B["Incanter Can Still Fit Well"]
A --> C["Larger Modern Data Workflow"]
C --> D["Scicloj / tech.ml.dataset / Noj Style Stack"]
The thing to notice is that the decision is driven by workflow shape, not by ideology.
Choose Incanter when:
Choose a more modern Scicloj-oriented path when:
There is also a softer reason to keep Incanter in a guide like this: it helps explain how Clojure developers approached statistical computing before the newer Scicloj ecosystem matured. That historical bridge is useful. It shows how Clojure’s data story evolved rather than pretending the current stack appeared fully formed.
So this page should leave the reader with a balanced view:
deps.edn is the better default for new examples, even when discussing older libraries.tech.ml.dataset-oriented tools.