Browse Clojure Foundations for Java Developers

Namespaces and Imports

How to declare a namespace, require Clojure libraries, and import Java classes in an idiomatic ns form.

Namespaces in Clojure are like Java packages, but they hold vars (functions and values), not classes. You usually configure a file’s namespace once at the top with ns.

The ns Form You’ll See Everywhere

1(ns myapp.core
2  (:require [clojure.string :as str]
3            [myapp.util :as util])
4  (:import [java.time Instant]))

What this means in practice:

  • :require loads other Clojure namespaces (your code or libraries).
  • :as gives you a short alias so calls are explicit: str/join, util/parse-int, etc.
  • :import brings Java classes into scope so you can write Instant/now instead of java.time.Instant/now.

You can always skip :import and use the fully-qualified class name:

1(java.time.Instant/now)

:refer (Use Sparingly)

1(:require [clojure.string :refer [join split]])

refer can be convenient for a small, stable set of names, but aliases are usually clearer. Avoid :refer :all in production code because it hides where names come from and makes conflicts harder to spot in review.

REPL Reload Tip

During development you’ll often reload a namespace after changes:

1(require 'myapp.core :reload)

Most editors also provide a “reload namespace” command.

File Path Rule of Thumb

Namespace names map to file paths:

  • myapp.coresrc/myapp/core.clj
  • hyphens in namespace segments become underscores in filenames:
    • my-app.coresrc/my_app/core.clj

Knowledge Check: Namespaces

### If you have `(:require [clojure.string :as str])`, how do you call `join`? - [x] `(str/join "," ["a" "b"])` - [ ] `(join "," ["a" "b"])` (without any require) - [ ] `(clojure.string/join "," ["a" "b"])` is the only valid way - [ ] `("a" "b").join(",")` > **Explanation:** The `:as` alias makes calls explicit and readable. Fully qualified calls also work, but aliases are the common style. ### Why is `:refer :all` usually discouraged? - [x] It pollutes the namespace and makes name origins/conflicts harder to see in code review. - [ ] It makes the code run slower by default. - [ ] It prevents Java interop. - [ ] It’s required for macros to work. > **Explanation:** `:refer :all` hides dependencies and increases the chance of collisions. Prefer `:as` or a tiny `:refer` list. ### What does `(:import [java.time Instant])` enable? - [x] Writing `(Instant/now)` instead of `(java.time.Instant/now)` - [ ] Importing another Clojure namespace - [ ] Loading Maven dependencies - [ ] Generating Java bytecode ahead of time > **Explanation:** `:import` is for Java classes. `:require` is for Clojure namespaces.
Revised on Friday, April 24, 2026