# REPL Workflow

Most Clojure devs work with the REPL through a reloadable lifecycle system. If you don't know what a REPL workflow is I **mandate** that you read through [REPL Driven Development](https://practical.li/clojure/introduction/repl-workflow/) and watch all the associated videos.

This document goes into more details about personalizing the REPL workflow to your needs using [launchpad](https://github.com/lambdaisland/launchpad).

## Prerequisites

If you haven't already, please follow the steps from [getting started](/shipclojure-docs/getting-started.md) documentation to have everything running.

## Understanding Launchpad

ShipClojure uses [lambdaisland/launchpad](https://github.com/lambdaisland/launchpad) to manage the development environment. When you run `bb dev`, launchpad:

1. Installs development tools via mise
2. Installs npm dependencies
3. Sets up secrets file if missing
4. Starts Docker services (PostgreSQL)
5. Starts CSS watch process
6. Starts the Clojure REPL on port `7888`
7. Automatically calls `(user/go)` to boot the system

The beauty of launchpad is that it handles all this automatically, but also allows you to personalize your setup without affecting other team members.

## Personalizing Your Setup

Launchpad supports a `deps.local.edn` file for individual configuration. This file is gitignored, so your preferences stay local to your machine.

Create a `deps.local.edn` file in the project root:

```clojure
{;; CLI flags for your preferences
 :launchpad/main-opts ["--emacs"]  ; or other flags

 ;; Additional aliases to always include
 :launchpad/aliases [:your-alias]

 ;; Options merged into launchpad context
 :launchpad/options {:portal true
                     :nrepl-port 7888}

 ;; Shadow-cljs builds to start
 :launchpad/shadow-build-ids [:app :portfolio]

 ;; Shadow builds to auto-connect REPL to (with --emacs)
 :launchpad/shadow-connect-ids [:app]}
```

### Editor-Specific Setup

#### Emacs / CIDER

For the smoothest Emacs experience, add this to your `deps.local.edn`:

```clojure
{:launchpad/main-opts ["--emacs"]}
```

The `--emacs` flag is shorthand for `--cider-nrepl --refactor-nrepl --cider-connect`, which:

* Injects CIDER nREPL middleware
* Injects refactor-nrepl middleware
* Automatically instructs Emacs to connect to the REPL

With this setup, just run `bb dev` and Emacs will automatically connect.

#### VS Code / Calva

For VS Code/Calva users, add this to your `deps.local.edn`:

```clojure
{:launchpad/main-opts ["--vs-code"]}
```

The `--vs-code` flag includes the CIDER nREPL middleware that Calva needs.

Then run `bb dev` and connect in VS Code:

1. Open the Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`)
2. Run `Calva: Connect to a Running REPL Server in the Project`
3. Select `deps.edn`
4. Enter `localhost:7888` when prompted

#### IntelliJ / Cursive

Run `bb dev` to start the REPL, then in IntelliJ:

1. Go to `Run > Edit Configurations`
2. Add a new `Clojure REPL > Remote`
3. Set host to `localhost` and port to `7888`
4. Run the configuration

#### Vim / Neovim

Run `bb dev` to start the REPL, then connect using your preferred plugin (vim-fireplace, conjure, etc.) to `localhost:7888`.

## Working with the REPL

Once connected, the system should already be running (launchpad calls `(user/go)` automatically). You can interact with it using these functions from the `user` namespace:

```clojure
(reset)      ; Reload changed namespaces and restart the system
(halt)       ; Stop the system
(reset-all)  ; Reload all namespaces and restart (use when reset fails)
(go)         ; Start the system (if halted)
```

**Pro tip**: Bind `(user/reset)` to a keybind so you can call it often. See [this tweet](https://x.com/ovstoica/status/1851655570303942782) for community explanations of binding a key to a clojure fn call - people in the replies contributed with the way to do it for most editors.

## ClojureScript REPL

> NOTE: You don't *need* a CLJS REPL to work on ShipClojure. Live reload of changes in `.cljs` or `.cljc` files are automatically compiled and reflected in the browser. The CLJS REPL is a nice-to-have for those who prefer it.

The shadow-cljs nREPL server runs on port **7002**. You can change this in [shadow-cljs.edn](https://github.com/shipclojure/shipclojure/blob/main/shadow-cljs.edn) under `[:nrepl :port]`.

### Connecting to ClojureScript REPL

Alternatively, connect directly to the shadow-cljs nREPL:

* **Emacs**: `M-x cider-connect-clj` and enter `localhost:7002`
* **VS Code**: `Calva: Connect to Running REPL`, select `Generic`, enter `localhost:7002`
* **IntelliJ**: Create a Remote REPL configuration for `localhost:7002`

Then call `(user/cljs-repl)` to switch to the ClojureScript REPL.

## Customizing What Launchpad Starts

### Shadow-CLJS Builds

By default, launchpad starts shadow-cljs builds configured via the `:launchpad/shadow-build-ids` key in the `:dev` alias. If you want to customize which builds start, add to your `deps.local.edn`:

```clojure
{:launchpad/shadow-build-ids [:app :portfolio]}
```

### Disabling Automatic System Start

If you prefer to manually call `(go)` instead of having it run automatically, you would need to modify `bin/launchpad` and set `:go false`. However, this affects everyone, so it's recommended to keep `:go true` and use `(halt)` if you need to stop the system.

### Hot Reloading deps.edn

One of launchpad's killer features is hot-reloading of `deps.edn` and `deps.local.edn`. You can:

* Add new dependencies
* Switch to a newer version of a dependency
* Switch from a Maven jar to a local checkout (`:local/root`)
* Activate additional aliases

All without restarting your REPL! Just save your `deps.edn` or `deps.local.edn` and launchpad will pick up the changes.

## Troubleshooting

### System didn't start automatically

If the system didn't start, you can manually start it:

```clojure
(user/go)
```

### Need to fully reset

If things get into a weird state:

```clojure
(user/reset-all)  ; Reloads all namespaces
```

### Port already in use

If port 7888 is already in use, either stop the existing process or configure a different port in `deps.local.edn`:

```clojure
{:launchpad/options {:nrepl-port 7889}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shipclojure.gitbook.io/shipclojure-docs/development/repl-workflow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
