Clojure Development Environment
Build a practical Clojure environment for Java engineers: a stable JDK, Clojure CLI or Leiningen, editor-connected REPL, project layout, build integration, Git hygiene, and troubleshooting habits.
For Java developers, the biggest “tooling shock” with Clojure is that the REPL is not optional. This chapter gets you to a tight feedback loop: an editor connected to a running JVM process where you can evaluate code as you work.
You will set up Clojure, choose a build/dependency workflow, and learn the minimum project structure you need to navigate real codebases. The goal is not to memorize tools, but to be able to start a REPL, load code, run tests, and iterate confidently.
| Setup concern |
Java instinct |
Clojure habit to build |
| Runtime |
Install a JDK and let the IDE hide most details |
Verify the same JDK from the terminal, editor, build, and REPL |
| Build/deps |
Pick Maven or Gradle first |
Learn the project’s actual workflow: Clojure CLI, Leiningen, Maven, Gradle, or a mix |
| Feedback loop |
Compile, run, debug, repeat |
Keep a REPL connected and evaluate small forms as you work |
| Project layout |
Package/class navigation |
Namespace/file navigation plus classpath awareness |
| Team workflow |
Commit source and generated build metadata carefully |
Keep REPL artifacts, caches, and formatter churn out of commits |
Treat this chapter as infrastructure: once the workflow feels natural, every later chapter becomes faster to learn and easier to verify.
In this section
-
Java Setup for Clojure
Make the JVM foundation boring and reliable by choosing a supported JDK, aligning terminal and editor settings, and verifying the same Java runtime across Clojure tools and Java builds.
-
Check Your Java Installation
Confirm that your terminal can find a real JDK before installing Clojure, and learn what java, javac, PATH, and JAVA_HOME tell you about the JVM your tools will use.
-
Install a JDK for Clojure
Choose and install a supported JDK for Clojure development without getting distracted by vendor debates, then verify that your shell, editor, and build tools use the same runtime.
-
Java Environment Variables
Use PATH, JAVA_HOME, and optional Java selection variables deliberately so Clojure, Maven, Gradle, editors, and CI agree on the same JDK.
-
Verify Java for Clojure
Run a compact Java verification checklist before installing or debugging Clojure so runtime, compiler, PATH, JAVA_HOME, classpath behavior, and editor configuration are aligned.
-
Fix Java Setup Issues
Diagnose Java setup failures that block Clojure: wrong JDK selection, missing javac, stale PATH entries, bad JAVA_HOME, editor mismatch, dependency download problems, and permission errors.
-
Installing Clojure
Install a Clojure toolchain that lets you start a REPL, resolve dependencies, inspect the JVM classpath, and run small experiments without fighting your environment.
-
How Clojure Installation Works
Understand what the Clojure CLI installs, how clj and clojure relate to the JVM classpath, and why the CLI version is separate from the Clojure language version.
-
Install Clojure on Windows
Choose between WSL and the Windows Clojure installer, verify Java first, and set up a Windows workflow that matches the Clojure tutorials and tools you plan to use.
-
Install Clojure on macOS
Install the Clojure CLI on macOS with Homebrew, verify Java and brew first, and confirm that clj, clojure, and your editor use the same JVM setup.
-
Install Clojure on Linux
Install the Clojure CLI on Linux with the current official installer script, verify Java, bash, curl, and rlwrap prerequisites, and confirm REPL and classpath behavior.
-
Clojure CLI vs Leiningen
Compare the Clojure CLI with deps.edn and Leiningen with project.clj so Java engineers can run existing projects, choose new-project defaults, and avoid tool migration churn.
-
Install Leiningen
Install Leiningen only when a project or learning path needs it, then verify lein, project.clj, REPL, test, and package commands without confusing it with the Clojure CLI.
-
Verify Your Clojure Installation
Check Java, the Clojure CLI, REPL startup, language version, classpath construction, and optional Leiningen commands before debugging project-specific setup problems.
-
Choosing an Editor or IDE
Choose a Clojure editor setup by prioritizing REPL connection quality, evaluation commands, namespace navigation, stack-trace clarity, formatting support, and daily comfort over brand loyalty.
-
Clojure Development: Overview of Popular Editors and IDEs
Explore the best editors and IDEs for Clojure development, including IntelliJ IDEA with Cursive, Emacs with CIDER, Visual Studio Code with Calva, Atom with Chlorine, and Vim with Fireplace.
-
Installing and Configuring IntelliJ IDEA with Cursive for Clojure Development
Learn how to set up IntelliJ IDEA with the Cursive plugin for Clojure development, including installation, configuration, and exploring key features like syntax highlighting, code completion, REPL integration, and debugging.
-
Setting Up Visual Studio Code with Calva for Clojure Development
Learn how to set up Visual Studio Code with the Calva extension for an optimal Clojure development experience, including installation, configuration, and usage of REPL and debugging tools.
-
Configuring Emacs with CIDER for Clojure Development
Learn how to set up Emacs with CIDER for a seamless Clojure development experience, tailored for Java developers transitioning to functional programming.
-
Choosing the Right Editor for Clojure Development
Explore the best editors and IDEs for Clojure development, focusing on features, plugins, community support, and compatibility with team workflows.
-
Setting Up the REPL
Build the core Clojure inner loop: start the right project REPL, connect your editor, evaluate forms safely, reload namespaces, inspect values, and keep the running JVM aligned with source.
-
Understand the Clojure REPL
Understand the Clojure REPL as a running JVM process where Java engineers can evaluate forms, inspect values, reload namespaces, and shorten the edit-run-debug loop.
-
Start the Right Clojure REPL
Start standalone, project-connected, Leiningen, Clojure CLI, and editor-connected REPL sessions, and choose the mode that matches the code and classpath you need.
-
Evaluate Forms in the REPL
Use the Clojure REPL to evaluate complete forms, inspect return values, require helper namespaces, work with recent results, and avoid confusing scratch state with saved source.
-
Manage Namespaces and Reloads in the REPL
Work with namespaces, require and reload source files, inspect errors, interrupt bad evaluations, and understand when a running REPL needs a restart instead of another reload.
-
Use the REPL in Daily Clojure Workflow
Turn the REPL into a daily engineering workflow: connect the editor, evaluate source-backed forms, capture decisions in tests, and avoid hidden state that teammates cannot reproduce.
-
Clojure Build Tools
Compare Leiningen and tools.deps from a Java engineer's point of view so you can recognize project files, start the right REPL, run tests, package code, and avoid premature tool migrations.
-
Understand Leiningen Projects
Learn how Leiningen uses project.clj, named tasks, profiles, plugins, the project REPL, and uberjar packaging so you can work confidently in existing Clojure repositories.
-
Create a Leiningen Project
Generate a Leiningen application, read its project.clj and namespace layout, run the app, run tests, and start the project REPL without confusing the scaffold with architecture.
-
Understand deps.edn and the Clojure CLI
Understand how deps.edn, clj, clojure, aliases, classpath roots, main invocations, exec functions, and tools aliases fit together in modern Clojure CLI projects.
-
Create a deps.edn Project
Create a small Clojure CLI project by hand, wire source and test paths, add run and test aliases, and verify the project from the shell before adding more tooling.
-
Choose Between Leiningen and deps.edn
Compare Leiningen and deps.edn by repository signals, team workflow, REPL expectations, testing, packaging, and migration cost so Java engineers choose tools pragmatically.
-
Your First Clojure Project
Create a small Clojure project that has a runnable entry point, test namespace, REPL-friendly functions, and a simple structure Java engineers can recognize and extend.
-
Build Your First Clojure Project
Create a small Clojure project with a namespace, pure greeting function, runnable entry point, and repeatable command while mapping each piece to familiar Java concepts.
-
Understand Clojure Project Structure
Map Clojure source paths, namespaces, tests, resources, and build files to the Java project concepts you already know so a small project stays easy to navigate.
-
Run and Test a Clojure App
Run a small Clojure app from the command line, add focused clojure.test coverage, and create repeatable commands that feel predictable to Java engineers.
-
Package a Clojure App as an Uberjar
Package a small Clojure application as an executable uberjar, understand when :gen-class and AOT compilation matter, and verify the artifact with java -jar.
-
Understanding Project Structure
Understand how Clojure namespaces map to files, how src, test, and resources fit on the JVM classpath, and how to navigate a repository without looking for one class per file.
-
Map Clojure Namespaces to Files
Map Clojure namespaces to source files, require aliases, and Java package instincts so namespace loading errors become easy to diagnose.
-
Organize Source and Test Directories
Organize `src`, `test`, and `resources` directories around classpath roots, mirrored test namespaces, and the differences from Maven or Gradle source sets.
-
Read Clojure Project Config Files
Read `deps.edn`, `project.clj`, aliases, and profiles through a Java build-tool lens so you know which file controls dependencies, classpaths, tasks, and local workflow.
-
Integrating with Maven and Gradle
Fit Clojure into existing Java Maven or Gradle builds by keeping dependency resolution, packaging, source ownership, and runtime boundaries explicit.
-
Add Clojure to Maven Builds
Use Maven as the owning build for mixed Java and Clojure modules by declaring the Clojure runtime, source roots, plugin responsibilities, and compile/test boundaries explicitly.
-
Add Clojure to Gradle Builds
Integrate Clojure into Gradle with explicit plugin choice, source-set ownership, dependency scopes, test wiring, and runtime boundaries for mixed JVM projects.
-
Choose Maven or Gradle for Clojure
Decide whether Maven, Gradle, a separate Clojure build, or a separate service is the right integration boundary for Java teams adopting Clojure on the JVM.
-
Using Git with Clojure
Keep Clojure repositories reviewable by ignoring build and REPL artifacts, standardizing formatting, committing source truth rather than live REPL state, and documenting runnable commands.
-
Initialize a Clojure Git Repository
Start a Clojure repository with a clean first commit, a Clojure-aware `.gitignore`, reproducible commands, and clear source-of-truth boundaries for REPL-driven work.
-
Use Git Commands in Clojure Projects
Apply everyday Git commands to Clojure work by staging source changes deliberately, reviewing namespace diffs, keeping generated artifacts out, and syncing branches safely.
-
Review Clojure Changes with Git
Use pull requests, small commits, CI commands, and Clojure-aware review checklists to keep team changes understandable when Java developers adopt Clojure.
-
Troubleshooting Common Setup Issues
Diagnose common Clojure setup failures by reducing problems to terminal commands, checking JDK consistency, classpath construction, dependency resolution, editor REPL connection, and resource loading.
-
Diagnose Java Version Conflicts
Diagnose Clojure setup failures caused by mismatched JDKs, `JAVA_HOME`, IDE runtimes, Maven or Gradle toolchains, and class files compiled for newer Java versions.
-
Fix Clojure Environment Variables
Fix Clojure setup problems caused by shell startup files, `PATH`, `JAVA_HOME`, editor-launched REPLs, proxy variables, and project commands running in different environments.
-
Debug Clojure Dependency Problems
Debug missing libraries, version conflicts, classpath surprises, cached dependency failures, and Maven/Clojars access problems in Clojure CLI and Leiningen projects.