Claude Code for Clojure re-frame Workflow Guide
Clojure developers working with re-frame have discovered a powerful ally in Claude Code. This guide demonstrates how to use Claude Code effectively for re-frame projects, from initial setup to advanced state management patterns.
Understanding re-frame Architecture
Before diving into workflow optimization, it’s essential to understand how re-frame organizes application state. re-frame follows a unidirectional data flow pattern with three key layers:
- Model: The state layer using Reagent ratoms
- View: Reactive UI components written in Reagent
- Event: The dispatch and handler system for state transitions
Claude Code excels at understanding this architecture because it maps well to prompt-based descriptions. When you explain your component hierarchy or state flow, Claude Code can generate idiomatic Clojure that follows re-frame conventions.
Setting Up Claude Code for Clojure Projects
Proper project configuration ensures Claude Code understands your re-frame codebase. Create a CLAUDE.md file in your project root:
# Project Context
This is a ClojureScript re-frame application using:
- shadow-cljs for compilation
- Reagent for reactive components
- re-frame for state management
## Key Conventions
- Events are namespaced: `:app/events` for core, `:module/events` for features
- Subscriptions follow pattern: `subscribe [::handlers/name args]`
- Components use Hiccup-style markup
This context helps Claude Code generate code that matches your project’s conventions.
Generating re-frame Components
One of Claude Code’s strongest use cases is generating component code. Provide clear specifications describing the component’s purpose, data requirements, and user interactions.
For example, when requesting a form component:
;; Request: Create a todo-item component that displays a task
;; with checkbox, title, and delete button
(defcomp todo-item
[{:keys [id title completed on-toggle on-delete]}]
(let [editing? (r/atom false)]
(fn []
[:li {:class (when completed "completed")}
[:input.toggle
{:type "checkbox"
:checked completed
:on-change #(on-toggle id)}]
[:span {:on-click #(reset! editing? true)}
title]
[:button.destroy
{:on-click #(on-delete id)}]
(when @editing?
[:input.edit
{:default-value title
:on-blur #(reset! editing? false)}])])))
Claude Code generates this pattern when you specify the component’s props and behavior. The output follows re-frame conventions with proper destructuring and Reagent component structure.
Handling Event Handlers
Event handlers are the backbone of re-frame applications. Claude Code helps generate both simple and complex handlers with proper effects.
For a registration handler with validation:
(reg-event-db
:register/submit
[validate-middleware]
(fn [db [_ credentials]]
(let [validation-errors (validate-user credentials)]
(if (seq validation-errors)
(assoc db :errors validation-errors)
(let [user-id (generate-user-id)]
(-> db
(assoc :current-user {:id user-id
:email (:email credentials)})
(update :users assoc user-id credentials)))))))
The key is describing the handler’s purpose clearly. Explain what inputs it receives, what validation it performs, and how the database state changes.
Debugging re-frame Applications
When debugging, provide Claude Code with specific error messages and relevant code sections. The workflow differs slightly from traditional debugging:
- Copy the error message from the browser console or shadow-cljs output
- Identify the failing component or handler
- Include both in your prompt
A productive debugging prompt includes the error, the relevant code, and what you’ve already tried:
The subscription returns undefined in my component but the database
contains the data. The handler dispatches correctly and I can see
the updated db in the re-frame trace. The subscription is:
(re-frame/reg-sub
:user/preferences
(fn [db _]
(get-in db [:user :preferences])))
What could cause this?
Claude Code typically identifies missing initialization or path issues quickly.
Working with Effects and Coeffects
re-frame’s effect system can be challenging. Claude Code helps generate proper effect handlers for side effects like HTTP calls:
(reg-fx
:http/fetch
(fn [{:keys [url on-success on-failure]}]
(go
(let [response (<! (http/get url))]
(if (= 200 (:status response))
(re-frame/dispatch [on-success (:body response)])
(re-frame/dispatch [on-failure (:status response)])))))
This pattern integrates cleanly with the event system. When requesting effect handlers, describe the external system you’re integrating and what data flows back into re-frame.
Optimizing Component Rendering
Performance matters in re-frame applications. Claude Code helps optimize components by suggesting proper memoization and subscription patterns.
For expensive computations in components:
;; Instead of computing in the render function:
(defn user-dashboard [user-id]
(let [user (re-frame/subscribe [::user/by-id user-id])
stats (re-frame/subscribe [::stats/for-user user-id])
recent-activity (re-frame/subscribe [::activity/recent user-id])]
(fn []
;; Computation moved to subscription layer
[:div.dashboard
[:h1 (:name @user)]
[:div.stats (render-stats @stats)]
[:ul.activity (map render-activity @recent-activity)]])))
Claude Code suggests this pattern when you describe performance issues. The key is identifying computations that run on every render and moving them to subscription level.
Building Complete Features
For feature development, provide a structured approach:
- Define the data model first
- List required events and handlers
- Specify subscriptions
- Describe the UI components needed
Create a pagination component for a data table with:
- Sortable columns (click to sort, arrow indicator)
- Items per page selector (10, 25, 50, 100)
- Previous/Next buttons
- "Showing X-Y of Z" text
- Uses :data/table-query subscription
- Dispatches :data/set-page and :data/set-sort events
Claude Code generates the full feature set following this specification.
Best Practices for Claude Code with re-frame
Provide Complete Context: Include your project structure and conventions in CLAUDE.md. The more Claude Code knows about your patterns, the better the output.
Be Specific About Data Flow: Describe where data comes from and where it goes. “When the user clicks save, dispatch :form/submit with the field values, which validates and calls the API” produces better results than “save the form.”
Iterate on Components: Generate initial versions, test them, then refine. Prompt-based generation works well with incremental improvement.
Test Generated Code: Always verify generated handlers and subscriptions work correctly. The logic may be syntactically correct but miss edge cases.
Summary
Claude Code transforms re-frame development by accelerating component creation, event handler implementation, and debugging workflows. The key lies in providing clear, structured prompts that describe data flow and user interactions. As you develop familiarity with this workflow, you’ll find Claude Code becomes an invaluable pair programmer for your ClojureScript projects.
The re-frame pattern of state, events, and views maps naturally to prompt-based description. use this alignment to generate idiomatic, maintainable code that fits smoothly into your application architecture.
Related Reading
- Claude Code for Beginners: Complete Getting Started Guide
- Best Claude Skills for Developers in 2026
- Claude Skills Guides Hub
Built by theluckystrike — More at zovo.one