# Quil: Processing-style sketches in Clojure and ClojureScript

> Quil wraps the Processing drawing API in Clojure and ClojureScript. It suits generative artists and Clojure developers who want immediate visual feedback from a REPL, and it assumes you already know your way around a JVM or a browser toolchain.

**quil/quil** — Main repo. Quil source code.

- Repository: https://github.com/quil/quil
- Stars: 3,052 · Forks: 171
- Language: Clojure
- License: EPL-1.0
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/quil-quil

## What Quil is for, and who it fits

Quil exists to put the Processing drawing vocabulary inside Clojure. Processing itself is a Java library with a long list of functions for shapes, colour, transforms and animation, and the README describes it as "a carefully crafted API for making drawing and animation extremely easy". Quil's job is to expose that API as Clojure functions you call with `q/` prefixes, so a sketch is ordinary Clojure code with ordinary namespaces.

The audience is narrow and specific. You need to be comfortable with Clojure or ClojureScript already: the README assumes you know what a namespace declaration is and shows `(:require [quil.core :as q])` without explaining it. If you come from Processing's Java or Python modes and have never written a Lisp, the parentheses are the first thing you will fight, not the drawing. Conversely, if you already write Clojure and want to draw something, this is a shorter path than wiring a Java graphics library by hand.

The README also points at generative art as the natural use case. It mentions that many bundled examples were translated from Matt Pearson's book "Generative Art", which tells you what the maintainers expect people to build: small sketches that mutate over time, not application UIs.

## setup, draw and defsketch: the whole model

A Quil sketch has three moving parts, and the README is explicit about them: the setup function, the draw function, and the sketch itself. Setup runs once. Draw runs immediately after setup finishes and then repeatedly until you stop it. The sketch is the container that binds the two functions together and starts the loop.

The README's own metaphor calls setup and draw "artistic gladiators" and the sketch the "arena" they work in, which is charming but also accurate: the sketch owns the window, the size, the title and the callbacks, while the two functions own the pixels.

The `defsketch` macro is a convenience wrapper around the underlying `sketch` function. It takes a name, a `:title`, a `:settings` function, `:setup`, `:draw` and `:size`. Because it is a macro, the sketch is defined at the top level of a namespace and starts running when the namespace loads. That is convenient in a REPL and slightly awkward if you want to construct sketches dynamically, in which case you would reach for `sketch` directly.

The `:settings` callback is separate from `:setup` for a reason visible in the README example: it is where anti-aliasing is configured with `(q/smooth 2)`. Settings run before the window is fully configured, so anything that depends on the surface being ready belongs in `setup`, not in `settings`.

## Installing Quil and running a first sketch

The README gives two paths. The fastest is a Leiningen template that scaffolds a working project, which the README calls a Quil Template and which lives in a separate repository. The command creates a directory named after your project, and inside it you edit and run `src/hello-quil/core.clj`.

```bash
lein new quil hello-quil
```

If you prefer the Clojure CLI, the README points at a `deps-new` template called the sketchbook template. Either way, the template exists so you do not have to assemble the dependency and the entry point by hand.

Adding Quil manually means one dependency line. For Leiningen, in `project.clj`:

```clojure
[quil "4.3.1563"]
```

For the Clojure CLI, in `deps.edn`:

```clojure
quil/quil {:mvn/version "4.3.1563"}
```

After that, the namespace declaration needs the core namespace aliased, conventionally to `q`:

```clojure
(:require [quil.core :as q])
```

The README's own minimal sketch is worth reading in full because it demonstrates the shape of everything else. It sets the frame rate to 1 FPS and the background to a grey, then draws a randomly sized, randomly coloured circle each frame:

```clojure
(defn setup []
  (q/frame-rate 1)
  (q/background 200))

(defn draw []
  (q/stroke (q/random 255))
  (q/stroke-weight (q/random 10))
  (q/fill (q/random 255))
  (let [diam (q/random 100)
        x    (q/random (q/width))
        y    (q/random (q/height))]
    (q/ellipse x y diam diam)))
```

What you should see when you run it is a window titled "Oh so many grey circles", 323 by 200 pixels, gaining one new grey circle per second. If the window appears but stays empty, the usual cause is that `draw` is not being called, which in turn usually means the sketch definition is wrong rather than the drawing code.

## Where Quil stops being the right tool

Quil's release history is the first thing to weigh. The two releases named in this repository are v4.3.1563 from 2024-01-22 and v4.3.1323 from 2023-11-08. The README states that the current released version `4.3.1560` is compatible with JDK 17 or newer and supports Linux amd64 and aarch64 plus macOS M1, M2 and x86_64. That version number is older than the newest release in the list, which is a small inconsistency in the README worth knowing about before you copy version strings out of it.

The last push to the repository was on 2026-04-24, so the project is not abandoned, but a gap of more than a year between the newest release and the newest commit is a real signal about how much of that activity reaches a published artifact. If your organisation requires recent releases, this is a friction point.

Platform support is the second boundary. The README names Linux amd64, Linux aarch64, macOS M1, macOS M2 and macOS x86_64. Windows is not mentioned. If you are on Windows, you are outside what the documentation claims to support, and you should confirm the situation yourself rather than assume it works.

Third, this is a drawing library, not an application framework. There is no input handling story in the README beyond the sketch lifecycle, no widget toolkit, no layout system. If you need a UI with buttons and text fields, a Clojure wrapper around a desktop toolkit is a better fit, and Quil will make you build input handling from scratch.

Finally, the documentation is split across the README, the quil.info API page, the wiki and a cheatsheet PDF. The README itself warns that the cheatsheet "may be a little bit out-dated". Expect to consult more than one source, and expect some of them to lag the code.

## ClojureScript support and how it differs from the JVM path

Quil runs in ClojureScript as well as on the JVM, and the README points to a wiki article for the details rather than explaining them inline. That is a meaningful gap: the repository contains `dev.cljs.edn`, `test.cljs.edn`, `snippets.cljs.edn` and `figwheel-main.edn` at the top level, which tells you the project's own ClojureScript development uses Figwheel and a set of separate build configurations. If you go the browser route, you are adopting that toolchain shape, not just a library.

The practical difference is that on the JVM your sketch opens a desktop window, while in ClojureScript it renders into a canvas in a page. The drawing API surface is shared, which is the point of the project, but the surrounding concerns are not: asset loading, page lifecycle and the build pipeline all become yours.

Because the README does not walk through the ClojureScript setup, treat the wiki article as required reading before you commit to that path. The README's own requirements line lists ClojureScript 1.10.x alongside Clojure 1.10, so the two are supported in parallel rather than one being a preview of the other.

## Comparing Quil with plain Processing

The obvious alternative is Processing itself, in Java or in its Python mode. The difference is not the drawing API, which Quil borrows wholesale, but the language and the workflow around it.

Processing ships its own editor and its own build system. You press run and a sketch window appears. There is no dependency resolution step, no namespace declaration, no choice between Leiningen and the Clojure CLI. For someone whose goal is to draw a shape in the next ten minutes, that is a shorter path than `lein new quil hello-quil` followed by opening an editor.

Quil's advantage is the Clojure side. A sketch is a normal Clojure namespace, so you can pull in any library from Clojars, use the language's data structures for generative parameters, and connect to a running REPL to redefine `draw` while the window is open. That last point is the real differentiator: Processing's editor does offer live changes, but the Clojure REPL gives you a general-purpose interactive environment rather than one scoped to the sketch. If your work involves computing something before you draw it, the Clojure side earns its keep. If it does not, Processing's editor is less machinery for the same output.

## Licence, maintenance and what upgrading costs

Quil is released under EPL-1.0, the Eclipse Public License 1.0. That is a file-level copyleft licence, which in practice means you can use Quil in your own project, including a commercial one, but modifications you make to Quil's own source files carry obligations. This is a description of the licence identifier in the repository, not legal advice; if the distinction matters to your organisation, have someone qualified read the licence text, which is in the `LICENSE` file at the repository root.

On maintenance, the honest summary is that the repository received a push on 2026-04-24 while the newest release listed here is v4.3.1563 from 2024-01-22. The project is not archived. It is also not shipping releases at a pace that matches its commit activity, and the README's own version references lag the release list.

Upgrade cost is hard to estimate from the README alone, because the README does not document a migration path between 4.x versions. The repository does contain a `RELEASE-NOTES.md` at the top level, so that file is where you should look for breaking changes before bumping the version string in `project.clj` or `deps.edn`. The JDK requirement is the other upgrade constraint: the README states JDK 17 or newer, so a project still on JDK 8 or 11 needs a JDK move before it can move Quil.

## Conclusion

Adopt Quil if you already write Clojure or ClojureScript and want a drawing API that behaves like Processing, with setup, draw and defsketch as the whole mental model. Do not adopt it if you need a large maintained community, an actively developed release cadence, or a graphics stack you can debug without reading JVM or ClojureScript build output, because the last push to the repository was on 2026-04-24 and the newest release noted here is v4.3.1563 from 2024-01-22. Before committing, verify that your JDK is 17 or newer, that the Clojars artifact resolves at the version you pin, and that the examples repository still builds against it.

## FAQ

### How do I install Quil in a new Clojure project?

The README's recommended path is the Leiningen template: run `lein new quil hello-quil`, then open `src/hello-quil/core.clj` and run it. For manual setup, add the dependency to `project.clj` or `deps.edn` and require `[quil.core :as q]` in your namespace.

### Does Quil work with ClojureScript?

Yes. The README states that Quil supports ClojureScript and points to a wiki article for the details, and the requirements section lists ClojureScript 1.10.x alongside Clojure 1.10. The repository also contains Figwheel configuration files for its own ClojureScript development.

### What JDK version does Quil need?

The README states that the released version `4.3.1560` is compatible with JDK 17 or newer, and that it supports Linux amd64 and aarch64 plus macOS M1, M2 and x86_64 architectures. Windows is not named in that list.

### What is the difference between setup and draw in Quil?

The README says `setup` is called only once at the start, while `draw` is called immediately after `setup` completes and then repeatedly until you stop it. A third callback, `:settings`, runs before the surface is ready and is where the README enables anti-aliasing with `(q/smooth 2)`.

### What does quil mean?

The README does not give a definition of the word; it uses the name and tells a short story about a character called Quil. The project is named after that character, and the README does not document any other meaning.

## Sources

- [Issues](https://github.com/quil/quil/issues)
- [License: EPL-1.0](https://github.com/quil/quil/blob/master/LICENSE)
- [quil/quil on GitHub](https://github.com/quil/quil)
- [README](https://github.com/quil/quil/blob/master/README.md)
- [Releases](https://github.com/quil/quil/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/quil-quil
