= Up and Running
:experimental:

To use CIDER, you'll need to connect it to a running nREPL server that
is associated with your program. Most Clojure developers use standard
build tooling such as tools.deps, Leiningen, or Gradle, and CIDER can
automatically work with those tools to get you up and running
quickly. But those tools are not required; CIDER can connect to an
nREPL server that is already started and is managed separately.

NOTE: CIDER will automatically work with Leiningen 2.9.0+ or a recent
tools.deps. Older versions are not supported.

There are two ways to connect CIDER to an nREPL server:

. CIDER can launch an nREPL server for your project from Emacs.
. You can connect CIDER to an already-running nREPL server, managed separately.

The following sections describe each of these methods.

== Launch an nREPL Server From Emacs

If you have a Clojure project in your file system and want CIDER to
launch an nREPL session for it, simply visit a file that belongs to
the project, and type kbd:[M-x] `cider-jack-in`
kbd:[RET].footnote:[Yeah, that's a "Neuromancer" reference.]
CIDER will start an nREPL server and automatically connect to it.

TIP: In Clojure(Script) buffers the command `cider-jack-in` is bound to kbd:[C-c C-x (C-)j (C-)j].

The process of jacking-in is pretty simple:

* CIDER determines the build system for your project (e.g. Leiningen) and picks the necessary command to start an nREPL server.
* CIDER shells out and runs a command like `lein repl :headless` to start an nREPL server.
* CIDER waits for the nREPL server to start.
CIDER figures out this by parsing the output from the command and waiting for a line like
`nREPL server started on port 53005 on host localhost - nrepl://localhost:53005` to appear there.
* CIDER extracts the port of the nREPL from the preceding message.
* It connects to the running nREPL server.

TIP: You can see the exact command that `cider-jack-in` invoked in your minibuffer, while
waiting for nREPL to start. You can also find this command in Emacs's `+*Messages*+` buffer.

In some cases one project might have multiple project markers in it - e.g. `project.clj` and `deps.edn`.
When this happens CIDER will prompt you to select the build tool to use. You can override this behavior
by setting the variable `cider-preferred-build-tool`. While you can set it globally in your Emacs config,
most of the time you'd probably want to have a project-specific setting for it in your `.dir-locals.el`:

[source,emacs-lisp]
----
((clojure-mode
  (cider-preferred-build-tool . lein)))
----

NOTE: `cider-jack-in` is mainly designed for local development (with files on a
local machine and the nREPL process running on the same machine). It does support
various common remote/container scenarios, as documented later in this section. Due
to the large variation of remote scenarios it cannot support all of them, so in
some cases, a better option would be to start nREPL manually and connect to it with `cider-connect`.

=== Auto-Injecting Dependencies

While CIDER's core functionality requires nothing more than an nREPL server,
there are many advanced features that depend on the presence of additional nREPL
middleware. Fortunately, if you're using `cider-jack-in`, that's handled
auto-magically.

If your project uses `lein` or `tools.deps` (`deps.edn`), CIDER will
automatically inject all the necessary nREPL dependencies (e.g. `cider-nrepl` or
`piggieback`) when it starts the server.  The injection process is extremely
simple - CIDER passes the extra dependencies and nREPL configuration to
your build tool in the command it runs to start the nREPL server. Here's how
this looks for `tools.deps`:

  $ clojure -Sdeps '{:deps {nrepl {:mvn/version "1.5.2"} cider/cider-nrepl {:mvn/version "0.58.0"}}}' -m nrepl.cmdline --middleware '["cider.nrepl/cider-middleware"]'

TIP: If you don't want `cider-jack-in` to inject dependencies automatically, set
`cider-inject-dependencies-at-jack-in` to `nil`. Note that you'll have to setup
the dependencies yourself (see xref:basics/middleware_setup.adoc[nREPL Middleware Setup]).

Normally `cider-jack-in` would inject only `cider-nrepl` and `cider-jack-in-cljs` would
add `piggieback` as well. The injection mechanism is configurable and
you can easily add more libraries there. Some CIDER extensions would use
this mechanism to auto-inject their own dependencies.

Here's how you can modify the injected dependencies for `cider-jack-in-clj`:

[source,lisp]
----
;; auto-inject version 1.0 of the library foo/bar
(cider-add-to-alist 'cider-jack-in-dependencies
                    "foo/bar" "1.0")
;; if you want to have full control over the coordinate description set it as an alist
;; auto-inject {:git/sha "6ae2b6f71773de7549d7f22759e8b09fec27f0d9" for library org.clojure/tools.deps
;;              :git/url "https://github.com/clojure/tools.deps/"}
(cider-add-to-alist 'cider-jack-in-dependencies
                    "org.clojure/tools.deps"
                    '(("git/sha" . "6ae2b6f71773de7549d7f22759e8b09fec27f0d9")
                      ("git/url" . "https://github.com/clojure/tools.deps/")))
----

IMPORTANT: Always use the fully qualified `group/artifact` (e.g. `re-frame/re-frame`) in these dependencies, since only Leiningen supports the bare `re-frame` syntax.

CIDER will also inject the most recent version of nREPL that it supports. This is a simple
trick to override the version of nREPL bundled with your build tool (e.g. Leiningen), so you can gain
access to the newest nREPL features. Generally that's one aspect of CIDER's inner workings
that end-users will rarely have to think about.

You can override the injected versions of `cider-nrepl` and nREPL by customizing
`cider-injected-middleware-version` and `cider-injected-nrepl-version`.
Generally you should avoid doing this, but it may be useful if you want to try
a newer version or you encounter some regression that forces you to temporarily use
an older version.

CIDER can also inject a Clojure dependency into your project, which is useful,
for example, if your project defaults to an older version of Clojure than that
supported by the CIDER middleware. Set `cider-jack-in-auto-inject-clojure`
appropriately to enable this.

=== Enabling nREPL JVMTI agent

Since version 1.2.0, nREPL includes a native JVMTI agent which makes the eval
interrupts work properly on Java 21 and later. To enable the agent, the Java
process should be launched with `-Djdk.attach.allowAttachSelf`. CIDER will do it
automatically during jack-in if `cider-enable-nrepl-jvmti-agent` variable is set
to `t`.

[IMPORTANT]
====
`cider-enable-nrepl-jvmti-agent` has no effect if you start a REPL
process outside of Emacs and connect to it with `cider-connect`. In that
scenario, you have to add `-Djdk.attach.allowAttachSelf` Java property manually
through the means of the build tool. In Leiningen, add this to `project.clj`:

[source,lisp]
----
:jvm-opts ["-Djdk.attach.allowAttachSelf"]
----

In tools.deps, add this to one of the aliases that you enable with the REPL:

[source,lisp]
----
:aliases {:dev
          {:jvm-opts ["-Djdk.attach.allowAttachSelf"]
           ...}}
----
====

=== Jacking-in without a Project

If you try to run `cider-jack-in` outside a project
directory, CIDER will warn you and ask you to confirm whether you
really want to do this; more often than not, this is an accident.  If
you decide to proceed, CIDER will invoke the command configured in
`cider-jack-in-default` (defaults to `clj`, Clojure's basic startup command).

TIP: You can set `cider-allow-jack-in-without-project` to `t` if you'd like to
disable the warning displayed when jacking-in outside a project.

==== Universal jack-in

`cider-jack-in-universal` kbd:[C-c C-x j u] is another way to quickly
jack in without a project choosing from a list of pre-configured
Clojure build tools. When this command is called from outside of a
project, the user is given the option to select to jack in with one of
the pre-configured tools, as well as to confirm the root directory to
use as a base. If the command is called from within a project
directory, it behaves exactly the same as `cider-jack-in` does.

It utilizes Emacs's
https://www.gnu.org/software/emacs/manual/html_node/elisp/Prefix-Command-Arguments.html[numeric
prefix arguments] to quickly jack in with a specific build tool. Numeric prefix
arguments can be set with the `Meta` key followed by a number.

The following Clojure build tools are supported so far

- kbd:[M-1 C-c C-x j u] jack-in using clojure-cli.
- kbd:[M-2 C-c C-x j u] jack-in using leiningen.
- kbd:[M-3 C-c C-x j u] jack-in using babashka.
- kbd:[M-4 C-c C-x j u] jack-in using nbb.
- kbd:[M-5 C-c C-x j u] jack-in using basilisp.

Here is an example of how to bind kbd:[F12] for quickly bringing up a
babashka REPL:

[source,lisp]
----
(global-set-key (kbd "<f12>") (lambda ()
                                (interactive)
                                (cider-jack-in-universal 3)))
----

The list of available build tools to consider is configured in
`cider-jack-in-universal-options`. Each element of the list consists
of the tool name and its setup options. Taking `nbb` as an example
from the list:

[source,lisp]
----
(nbb         (:prefix-arg 4 :cmd (:jack-in-type cljs :project-type nbb :cljs-repl-type nbb :edit-project-dir t)))
----

with

. `:prefix-arg` assigns the `nbb` tool name a numerical argument prefix of 4.
. `:cmd` how to invoke the command.
.. `:jack-in-type` use a `cljs` repl.
.. `:project-type` use `nbb` (see `jack-in-command`) to bring up the nREPL server.
.. `:cljs-repl-type` client uses the `nbb` cljs repl type (see `cider-cljs-repl-types`) to initialize server.
.. `:edit-project-dir` ask the user to confirm root directory to use as base.

=== Customizing the Jack-in Command Behavior

You can use kbd:[C-u M-x] `cider-jack-in` kbd:[RET] to specify the exact command
that `cider-jack-in` would run. This option is very useful if you want to e.g.
specify extra Leiningen profiles or `deps.edn` aliases.

Alternatively you can kbd:[C-u C-u M-x] `cider-jack-in` kbd:[RET], which is a
variation of the previous command. This command will first prompt you for the
project you want to launch `cider-jack-in` in, which is pretty handy if you're
in some other directory currently. This option is also useful if your project
contains some combination of `project.clj` and `deps.edn` and you want to launch
a REPL for one or the other.

NOTE: The examples use only `cider-jack-in`, but this behavior is consistent
for all `cider-jack-in-\*` commands.

You can further customize the command line CIDER uses for `cider-jack-in` by
modifying some options. Those differ a bit between the various tools,
so we'll examine them tool by tool.

==== Leiningen Options

* `cider-lein-command` - the name of the Leiningen executable (`lein` by default)
* `cider-lein-parameters` - the command-line params to start a REPL (e.g. `repl :headless` or -o to enable offline mode)

==== Clojure CLI Options

* `cider-clojure-cli-command` - the name of the `clojure` executable (`clojure` by default)
* `cider-clojure-cli-parameters` - the command-line parameters to start a REPL
* `cider-clojure-cli-aliases` - a list of project-specific aliases to be used at jack-in time (it's meant to be set via `.dir-locals.el`)
* `cider-clojure-cli-global-aliases` - a list of global aliases that are appended to project-specific `cider-clojure-cli-aliases`

On MS-Windows, CIDER will employ `PowerShell` to execute Clojure if no
`clojure` executable is found in the PATH (e.g. like the one supplied
by https://github.com/borkdude/deps.clj[deps.clj]). The default
executable used is `powershell` which is available on all Windows
platforms. Using `PowerShell` will Base64 encode the clojure launch
command before passing it to PowerShell and avoids shell-escaping
issues.

The functionality of `cider-clojure-cli-command` has been verified
with the following alternatives

* `pwsh`: This option proves beneficial when the user has installed the https://github.com/clojure/tools.deps.alpha/wiki/clj-on-Windows[ClojureTools] module on pwsh in a directory not accessible by the system's PowerShell installation.
* `deps.exe`: This executable is part of the tools provided by
  https://github.com/borkdude/deps.clj[deps.clj] as an alternative name for `clojure.exe`.

NOTE: Alternatively you can use WSL (e.g. to run nREPL and Emacs there), which
will likely result in a better overall development experience.

==== Gradle Options

* `cider-gradle-command` - the name of the Gradle executable (`./gradlew` by default)
* `cider-gradle-parameters` - the Gradle arguments to invoke the repl task (e.g. `--no-daemon` or `--configuration-cache`) (`clojureRepl` by default)

==== shadow-cljs

* `cider-shadow-cljs-command` - the command to run `shadow-cljs` (`npx shadow-cljs` by default). By default we favor the project-specific shadow-cljs over the system-wide.
* `cider-shadow-cljs-parameters` - the task to start a REPL server (`server` by default)

=== Override the Jack-In Command

Which Jack-In Command is used is based on the project type. You can override the Jack-In Command either project-wide or as an argument in Lisp.
This allows for fine-grained control over how cider starts the nrepl-server.

The precedence order for determining the Jack-In Command is:
1. `:jack-in-cmd` if provided as a parameter,
2. `cider-jack-in-command` if set as a directory local variable, and
3. Inferred from the project type (the default).

==== Setting a project-wide command

You can set a local variable `cider-jack-in-command` to override the jack-in command.

[source,emacs-lisp]
----
((nil
  (cider-jack-in-cmd . "nbb nrepl-server")))
----

==== Passing the Command Programmatically as a Parameter

You can provide an override Jack-In command as an argument to `cider-jack-in`.
Here is an example Nbb Jack-In command, providing a custom `:jack-in-cmd`.

[source,emacs-lisp]
----
(defun cider-jack-in-nbb-2 ()
  "Start a Cider nREPL server with the 'nbb nrepl-server' command."
  (interactive)
  (cider-jack-in-clj '(:jack-in-cmd "nbb nrepl-server")))
----

==== Starting nREPL server without trying to connect to it ====

In some situations, it might be useful to only start a nREPL server process, without
connecting to it. This can support complex setups
for which CIDER cannot reliably detect to which server/port to connect, and
would therefore fail.
This assumes that the user will execute a `cider-connect` command manually afterwards,
specifying host/port.

For this scenario, the `cider-start-nrepl-server` (kbd:[C-c C-x (C-)j (C-)n])  command is provided, which
takes the same parameters as `cider-jack-in`.

== Connect to a Running nREPL Server

If you have an nREPL server already running, CIDER can connect to
it. For instance, if you have a Leiningen-based project, go to your
project's directory in a terminal session and type:

[source,sh]
----
$ lein repl :headless
----

This will start the project's nREPL server.

It is also possible for plain `clj`, although the command is somewhat longer:

[source,sh]
----
$ clj -Sdeps '{:deps {cider/cider-nrepl {:mvn/version "0.58.0"}}}' -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]"
----

Alternatively, you can start nREPL either manually or using the facilities
provided by your project's build tool (Gradle, Maven, etc).

After you get your nREPL server running, go back to Emacs and connect
to it: kbd:[M-x] `cider-connect` kbd:[RET]. CIDER will
prompt you for the host and port information, which should have been
printed when the previous commands started the nREPL server in your
project.

TIP: In Clojure(Script) buffers the command `cider-connect` is bound to kbd:[C-c C-x c s].

If you frequently connect to the same hosts and ports, you can tell
CIDER about them and it will use the information to do completing
reads for the host and port prompts when you invoke
`cider-connect`. You can identify each host with an optional label.

[source,lisp]
----
(setq cider-known-endpoints
  '(("host-a" "10.10.10.1" "7888")
    ("host-b" "7888")))
----

If you wish to bypass the prompts entirely, you can configure the variables
`cider-connect-default-params` and `cider-connect-default-cljs-params`
on a per-project basis using https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html[.dir-locals.el].

The following configuration allows you to type kbd:[M-x] `cider-connect-clj&cljs` kbd:[RET] and instantly connect to both JVM and shadow-cljs REPLs without answering any prompts – useful when the project always uses the same fixed endpoints for its nREPL servers.

[source,lisp]
---
((clojure-mode
  . ((cider-connect-default-params . (:host "localhost" :port 1234))
     (cider-connect-default-cljs-params . (:host "localhost" :port 5678))
     (cider-default-cljs-repl . shadow))))
---

Note that the universal argument kbd:[C-u] can be used before a command to override these settings and force the prompts to be displayed.

== Working with Remote Hosts

While most of the time you'd be connecting to a locally running nREPL
server, that was started manually or via `cider-jack-in-\*`, there's
also the option to connect to remote nREPL hosts. For the sake of security
CIDER has the ability to tunnel a connection over SSH in such cases.
This behavior is controlled by
`nrepl-use-ssh-fallback-for-remote-hosts`: when true, CIDER will attempt to
connect via ssh to remote hosts when unable to connect directly. It's
`nil` by default.

There's also `nrepl-force-ssh-for-remote-hosts` which will force the use
of ssh for remote connection unconditionally.

WARNING: As nREPL connections are insecure by default, you're encouraged to use only SSH
tunneling when connecting to servers running outside of your network.

There's another case in which CIDER may optionally leverage the `ssh` command - when
trying to figure out potential target hosts and ports when you're doing `cider-connect-\*`.
If `cider-infer-remote-nrepl-ports` is true, CIDER will use ssh to try to infer
nREPL ports on remote hosts (for a direct connection). That option is also set to `nil`
by default.

NOTE: Enabling either of these causes CIDER to use
https://www.gnu.org/software/tramp/[TRAMP] for some SSH operations, which parses
config files such as `~/.ssh/config` and `~/.ssh/known_hosts`. This is known to
cause problems with complex or nonstandard ssh configs.

You can run `cider-jack-in-\*` while working with remote files over TRAMP. CIDER
will reuse existing SSH connection's parameters (like port and username) for establishing a SSH tunnel.
The same will happen if you try to `cider-connect-\*` to a host that matches the one you're currently
connected to.

NOTE: For Docker containers, running `cider-jack-in-\*` over TRAMP may technically work but it may give mixed results.
Please check out the following section for the recommended approaches.

== Working with Containers (Docker or others)

By 'containers' we mean Docker containers, or similar technologies, for running the JVM that will host our nREPL server.
The files which we edit may / may not be edited using TRAMP. They could as well be mounted inside the container, so they appear as local.

Because CIDER can't always detect if it's dealing with remote files, it's advisable to not rely on `cider-jack-in`
and its remote support described above, but to
start the nREPL server via command line from inside the container, and `cider-connect` to it.

This requires to first get a shell inside the running container and then start a nREPL server manually,
or configure the container to start an nREPL automatically when the container starts.

In order to connect Emacs to nREPL, we need to make sure that the port of nREPL is reachable to our local Emacs,
so that we can `cider-connect` to it.
There are several solutions for this depending on the concrete scenario.

=== Working with Containers running on localhost

The nREPL port should be set to a fixed value as we need to give this during the `docker start` command in order to forward the port from
container to host. This requires as well that nREPL server listens to "0.0.0.0" and not only to "localhost".

=== Working with Containers running on remote hosts

In case we have the container running on a remote machine, we need to do the same setup as above and additionally use `ssh`
to forward the already-forwarded port again to our local machine.

This can be done using a command such as "ssh -L 12345:localhost:12345 remote-server",
assuming that 12345 was the nREPL port exposed by the container.

=== Working with devcontainers locally or remotely

https://containers.dev[Development Containers] is a standard to describe container-based development environments. It includes a CLI.
It uses Docker/Podman behind the scenes. So the principles of making sure that the nREPL port becomes available stay the same,
but there are slightly different ways to configure this (given by the devcontainer standard).

There are several CLI tools to manage devcontainers, as there are several container technologies. The following example uses
link:https://github.com/devcontainers/cli[the devcontainers cli], but there are others (devpod, gitpod...).

==== Example: Working with containers (using `devcontainer`) on a remote server

In this scenario and assuming a folder `/home/me/my-clj-code` containing the relevant `devcontainer` related config files
(devcontainer.json) we can first start remotely a devcontainer via:

[source,sh]
----
# executed on MY_REMOTE_SERVER
devcontainer up --workspace-folder /home/me/my-clj-code
----

Then we can start a nREPL server inside the container on the remote host as shown below (executed from your local machine).
The command tunnels as well the remote port 12345 to local machine on port 12345:

[source,sh]
----
ssh -t -L 12345:localhost:12345 MY_REMOTE_SERVER \
    devcontainer exec  --workspace-folder /home/me/my-clj-code \
    "clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version \"1.5.2\"} cider/cider-nrepl {:mvn/version \"0.58.0\"}}}' -m nrepl.cmdline -p 12345 -b 0.0.0.0 --middleware '[\"cider.nrepl/cider-middleware\"]' "
----

For this to work, we need as well to configure `devcontainer.json` with a snippet that exposes port `12345` from the container to the (remote) host:

[source,json]
----
"appPort": [
  // will make container port 12345 available as 12345 on remote host
  // (which will be further tunneled to 12345 on local machine)
  "12345:12345"
	],
----

This results then in having port 12345 available locally and we can `cider-connect` to it, using `localhost:12345`.
Editing of the files can then happen via TRAMP. As the files are "on the remote machine"
and also mounted inside the container on the remote machine, we have two possible TRAMP file syntaxes to edit them - either of:

* `/ssh:MY_REMOTE_SERVER:/home/me/my-clj-code/...`
* `/ssh:MY_REMOTE_SERVER|docker:DOCKER_CONTAINER_ID:/workspaces/my-clj-code/...`

== Connecting via unix domain file socket

NOTE: Unix socket support was introduced in nREPL 0.9. Currently
CIDER's support for Unix sockets is considered experimental and its
interface might change in future CIDER releases.

When locally running nREPL servers, there is the option to listen on a
socket file instead of opening a network port.  As long as access to
the parent directory of the socket is sufficiently protected, this is
much more secure than the network port, since any local user can
access the port-provided REPL.  It can also be helpful in other
cases, e.g. when working with virtual networks (containers) where
sharing a file socket can be vastly simpler than managing bridge
networks and firewall setups.

After having started an nREPL server on a file socket, e.g. with the
`clj` command (see https://nrepl.org/nrepl/usage/server.html for other
examples),

[source,sh]
----
$ clj -R:nREPL -m nrepl.cmdline --socket nrepl.sock
----

you can then connect CIDER by using the `local-unix-domain-socket`
special hostname with `cider-connect`: kbd:[M-x] `cider-connect` kbd:[RET] `local-unix-domain-socket` kbd:[RET] `nrepl.sock` kbd:[RET].

At the moment only with `leiningen`, commands like `cider-jack-in`
will detect and use the unix domain socket if one is requested via the
`:socket` argument.  This can be arranged by specifying a prefix
argument to `cider-jack-in`, e.g. kbd:[C-u] kbd:[M-x] `cider-jack-in`,
or by adjusting `cider-lein-parameters`.

== What's Next?

So, what to do next now that CIDER's ready for action? Here are a few ideas:

* Get familiar with xref:usage/interactive_programming.adoc[interactive programming] and xref:usage/cider_mode.adoc[cider-mode]
* xref:config/basic_config.adoc[Configure] CIDER to your liking
* Explore the xref:additional_packages.adoc[additional packages] that can make you more productive
