Browse Learn Clojure Foundations as a Java Developer

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.
  • 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.
Revised on Saturday, May 23, 2026