Inspired by React and Reagent. Previously Respo/respo.cljs.
- Version: 0.16.65
- Init Function:
respo.main/main! - Reload Function:
respo.main/reload! - Core Namespaces: 33 namespaces providing virtual DOM, rendering, components, and utilities
- Testing: language built-in definition tests, plus a small JS-target smoke suite
In package.cirru and run caps:
{}
:dependencies $ {}
|Respo/respo.calcit |mainDOM syntax
; ns app.demo $ :require
respo.core :refer $ div
let
comp-demo $ fn (dispatch!)
respo.core/div
{}
:class-name "|demo-container"
:style $ {} (:color :red)
:on-click $ fn (event dispatch!)
dispatch! :clicked
respo.core/div $ {}
More examples adapted from calcit.cirru:
; ns app.demo $ :require
respo.core :refer $ defcomp a <>
let
comp-link $ fn (href text)
respo.core/a
{} $ :href href
respo.core/<> text
; ns app.demo $ :require
respo.core :refer $ list-> div
let
comp-list $ fn ()
respo.core/list->
{}
{}
:a $ respo.core/div ({})
Text Node:
; ns app.demo $ :require
respo.core :refer $ <>
let
comp-text $ fn (content)
respo.core/<> content
; with styles
respo.core/<> "|demo" $ {}
:color :red
:font-size 14
Component definition:
; ns app.demo $ :require
respo.core :refer $ div <>
let
comp-container $ fn (content)
respo.core/div
{}
:class-name |demo-container
:style $ {} (:color :red)
respo.core/<> content
App initialization:
; ns app.demo $ :require
respo.core :refer $ render-with!
; initialize store and update store
let
*store $ atom $ {} (:point 0) (:states {})
updater $ fn (store op)
match op
(:TODO a b) store
_ store
dispatch! $ fn (op)
reset! *store $ updater @*store op
mount-point nil
comp-container $ fn (state) state
dispatch! $ :: :TODO 1 2
; build the tree inside a managed memo frame, then render to the DOM
defn render-app! ()
respo.core/render-with! mount-point
fn () $ comp-container @*store
, dispatch!
Rerender on store changes:
let
*store $ atom $ {} (:point 0)
render-app! $ fn () nil
add-watch *store :changes $ fn ()
render-app!Memoize keyed list components inside the tree built by render-with!:
; ns app.demo $ :require
respo.core :refer $ list-> memo-comp-by >>
list->
{} (:class-name |task-list)
-> tasks .to-list .reverse $ map
fn (task)
let
task-id $ :id task
[] task-id $ memo-comp-by task-id comp-task (>> states task-id) task
memo-comp-by matches the component function, key, and complete argument list. Each
render-with! call records active keys and prunes entries that disappeared from the
latest tree. Passing nil as the key bypasses caching. Respo manages this cache
internally, so applications do not need memof for component memoization. See
Render list: memoization and memof migration
for setup, lifecycle, and migration details.
Reset virtual DOM caching during hot code swapping, and rerender:
; ns app.demo $ :require
respo.core :refer $ clear-cache!
let
*store $ atom $ {} (:point 0)
render-app! $ fn () nil
add-watch *store :changes $ fn ()
render-app!
remove-watch *store :changes
add-watch *store :changes $ fn ()
render-app!
respo.core/clear-cache!
render-app!
Adding effects to component:
; ns app.demo $ :require
respo.core :refer $ div
let
effect-a $ fn (text)
fn (action parent-element at-place?)
println action
; action could be :mount :update :amount
when (= :mount action) nil
comp-a $ fn (text)
[]
effect-a text
respo.core/div ({})
Define a hooks plugin based on Calcit Record, better use a pure function:
; ns app.demo $ :require
respo.core :refer $ div <>
let
plugin-x $ fn (states options)
%::
%{} :PluginX
:render $ fn (self) (nth self 1)
:show $ fn (self d! ? text) nil
, :plugin-name
respo.core/div ({}) (respo.core/<> "|Demo")
MIT
This index helps LLM tools automatically fetch and reference documentation using relative paths and the calcit CLI.
- Beginner Guide - Introduction to Respo concepts and component definition
- Respo-Agent Guide - 🤖 Detailed guide for LLM agents developing Respo apps (debugging, patterns, CLI tools)
- API Documentation Overview - Quick reference for all APIs
| Topic | Path | Overview |
|---|---|---|
| Why Respo | docs/guide/why-respo.md | Motivation and design philosophy |
| Virtual DOM | docs/guide/virtual-dom.md | Understanding virtual DOM concepts |
| Base Components | docs/guide/base-components.md | Core component patterns |
| DOM Elements | docs/guide/dom-elements.md | HTML element creation and usage |
| Component States | docs/guide/component-states.md | Managing component state |
| DOM Properties | docs/guide/dom-properties.md | DOM property binding |
| DOM Events | docs/guide/dom-events.md | Event handling in Respo |
| Typed Dispatch | docs/guide/type-slots.md | Entry-level Op binding and checks |
| Styles | docs/guide/styles.md | CSS and styling approach |
| Render Lists | docs/guide/render-list.md | Efficient list rendering |
| Common Primitives | docs/guide/common-primitives.md | Conditional UI, lifecycle, resources, errors, and batching |
| Hot Swapping | docs/guide/hot-swapping.md | Hot code reloading setup |
| Server Rendering | docs/guide/server-rendering.md | SSR capabilities |
| Pros and Cons | docs/guide/pros-and-cons.md | Framework comparison |
Core API descriptions are now stored in source doc strings inside calcit.cirru.
Use docs/api.md for the overview, or inspect a definition directly with Calcit CLI:
calcit query def respo.core/defcomp
calcit query def respo.core/render!
calcit query def respo.render.html/make-string| API | Namespace | Purpose |
|---|---|---|
defcomp |
respo.core/defcomp |
Define components with macro |
defeffect |
respo.core/defeffect |
Define lifecycle effects |
div |
respo.core/div |
Create div elements |
create-element |
respo.core/create-element |
Dynamically create elements |
render! |
respo.core/render! |
Sync virtual DOM to real DOM |
render-with! |
respo.core/render-with! |
Render with managed memo frame |
memo-comp-by |
respo.core/memo-comp-by |
Memoize keyed components |
memo-value-by |
respo.core/memo-value-by |
Memoize immutable derived data |
show |
respo.core/show |
Render a child conditionally |
for-keyed |
respo.core/for-keyed |
Build ordered keyed child pairs |
effect-on-mount |
respo.core/effect-on-mount |
Run a mount-only lifecycle callback |
effect-on-update |
respo.core/effect-on-update |
Run when immutable dependencies change |
effect-on-unmount |
respo.core/effect-on-unmount |
Run an unmount-only lifecycle callback |
effect-watch |
respo.core/effect-watch |
Dependency-aware lifecycle effect |
error-boundary |
respo.core/error-boundary |
Render a synchronous fallback |
make-render-scheduler |
respo.core/make-render-scheduler |
Coalesce render requests |
resource-reducer |
respo.resource/resource-reducer |
Reduce immutable async state |
resource-idle |
respo.resource/resource-idle |
Create initial resource state |
load-resource! |
respo.resource/load-resource! |
Emit async resource actions |
<> |
respo.core/<> |
Create text nodes |
comp-space |
respo.comp.space/comp-space |
Spacing component |
comp-inspect |
respo.comp.inspect/comp-inspect |
Inspection/debugging component |
clear-cache! |
respo.core/clear-cache! |
Clear memoization cache |
patch-instance! |
respo.controller.client/patch-instance! |
Patch DOM instances |
activate-instance! |
respo.controller.client/activate-instance! |
Activate DOM instances |
>> |
respo.core/>> |
Create state cursors |
purify-element |
respo.util.format/purify-element |
Clean element markup |
mute-element |
respo.util.format/mute-element |
Silence element output |
make-string |
respo.render.html/make-string |
Serialize to string |
find-element-diffs |
respo.render.diff/find-element-diffs |
Find DOM differences |
apply-dom-changes |
respo.render.patch/apply-dom-changes |
Apply DOM patches |
realize-ssr! |
respo.core/realize-ssr! |
Server-side rendering |
list-> |
respo.core/list-> |
Create list containers |
Legacy page names such as make-html and render-app were removed during the migration to source doc strings.
Agent-oriented CLI workflows (query/check-md automation) are maintained in Agents.md.