Convert Figma logo to code with AI

bhauman logodevcards

Devcards aims to provide a visual REPL experience for ClojureScript

1,530
112
1,530
30

Top Related Projects

4,811

A minimalistic ClojureScript interface to React.js

A ClojureScript framework for building user interfaces, leveraging React

1,810

Simple, decomplected, isomorphic HTML UI library for Clojure and ClojureScript

2,720

Fast library for rendering HTML in Clojure

1,024

Simple and powerful tool for building web apps out of highly composable elements in ClojureScript.

Quick Overview

Devcards is a ClojureScript library that provides a visual REPL-like experience for developing user interface components. It allows developers to create isolated, interactive examples of their components, making it easier to develop, test, and document UI elements in a ClojureScript environment.

Pros

  • Enhances UI development workflow with live, interactive component examples
  • Facilitates easier testing and debugging of individual components
  • Serves as living documentation for UI components
  • Integrates well with ClojureScript and React-based projects

Cons

  • Limited to ClojureScript projects, not applicable for other languages or frameworks
  • Requires additional setup and configuration in projects
  • May have a learning curve for developers new to ClojureScript or functional programming
  • Documentation could be more comprehensive for advanced use cases

Code Examples

  1. Basic Devcard example:
(defcard my-first-card
  (reagent/as-element
    [:div
     [:h1 "Hello, Devcards!"]
     [:p "This is a simple example."]]))

This code creates a basic Devcard with a heading and a paragraph.

  1. Interactive Devcard with state:
(defcard-rg stateful-card
  "A card with interactive state"
  (fn [state _]
    [:div
     [:h3 "Click count: " @state]
     [:button {:on-click #(swap! state inc)} "Increment"]])
  (reagent/atom 0))

This example demonstrates a Devcard with interactive state, showing a click counter.

  1. Devcard with markdown documentation:
(defcard markdown-doc
  "## Component Documentation
   
   This is an example of using markdown in Devcards.
   
   - Point 1
   - Point 2
   
   ```clojure
   (def example-code 'here)
   ```")

This code shows how to include markdown documentation within a Devcard.

Getting Started

To use Devcards in your ClojureScript project:

  1. Add Devcards to your project dependencies:

    [devcards "0.2.7"]
    
  2. Create a separate build for Devcards in your project.clj:

    :cljsbuild {:builds
                [{:id "devcards"
                  :source-paths ["src"]
                  :figwheel {:devcards true}
                  :compiler {:main "your-project.devcards"
                             :asset-path "js/devcards-out"
                             :output-to "resources/public/js/devcards.js"
                             :output-dir "resources/public/js/devcards-out"
                             :source-map-timestamp true}}]}
    
  3. Create a main namespace for Devcards:

    (ns your-project.devcards
      (:require [devcards.core :as dc :refer-macros [defcard deftest]]))
    
    (defcard first-card
      "## This is your first devcard")
    
  4. Run your project with Figwheel, specifying the Devcards build.

Competitor Comparisons

4,811

A minimalistic ClojureScript interface to React.js

Pros of Reagent

  • More comprehensive framework for building React applications in ClojureScript
  • Offers a simpler and more idiomatic way to define React components
  • Provides efficient re-rendering through a reactive atom-based model

Cons of Reagent

  • Steeper learning curve for developers new to ClojureScript or functional programming
  • Less focused on development-time tooling and visualization compared to Devcards
  • May require additional libraries for advanced state management in complex applications

Code Comparison

Reagent component:

(defn hello-world []
  [:div
   [:h1 "Hello, World!"]
   [:p "Welcome to Reagent"]])

Devcards component:

(defcard hello-world
  (fn [data-atom _]
    [:div
     [:h1 "Hello, World!"]
     [:p "Welcome to Devcards"]]))

While both examples create similar UI components, Reagent's syntax is more concise and directly represents the component structure. Devcards, on the other hand, wraps the component in a card definition, which is useful for isolated development and testing but adds an extra layer of abstraction.

A ClojureScript framework for building user interfaces, leveraging React

Pros of re-frame

  • Provides a comprehensive architecture for building complex SPAs
  • Offers a robust event-driven model for state management
  • Integrates well with React and ClojureScript ecosystem

Cons of re-frame

  • Steeper learning curve for developers new to functional programming
  • More opinionated structure, which may be limiting for some projects
  • Requires more boilerplate code for simple applications

Code Comparison

re-frame:

(re-frame/reg-event-db
 :initialize-db
 (fn [_ _]
   {:name "re-frame"}))

(re-frame/reg-sub
 :name
 (fn [db _]
   (:name db)))

Devcards:

(defcard my-first-card
  (reagent/as-element
    [:div
     [:h1 "Hello, Devcards!"]
     [:p "This is a simple example."]]))

Key Differences

  • re-frame focuses on application architecture and state management
  • Devcards emphasizes component development and visual testing
  • re-frame is better suited for large-scale applications
  • Devcards excels in isolated component development and documentation

Use Cases

  • Choose re-frame for building complex, data-driven SPAs
  • Opt for Devcards when developing and testing UI components in isolation
1,810

Simple, decomplected, isomorphic HTML UI library for Clojure and ClojureScript

Pros of Rum

  • Lightweight and fast, with a small footprint
  • Supports server-side rendering out of the box
  • More flexible architecture, allowing for easier integration with other libraries

Cons of Rum

  • Less comprehensive documentation compared to Devcards
  • Steeper learning curve for beginners
  • Fewer built-in development tools and utilities

Code Comparison

Rum example:

(rum/defc hello-world []
  [:div "Hello, World!"])

(rum/mount (hello-world)
           (. js/document (getElementById "app")))

Devcards example:

(defcard hello-world
  (reagent/as-element
    [:div "Hello, World!"]))

(defcard-rg interactive-component
  "An interactive component"
  (fn [data-atom _]
    [:div "Clicked " @data-atom " times"
     [:button {:on-click #(swap! data-atom inc)} "Click me"]])
  (reagent/atom 0))

Summary

Rum is a lightweight and flexible ClojureScript library for building user interfaces, while Devcards focuses on providing a development environment for interactive documentation and testing. Rum offers better performance and server-side rendering capabilities, but Devcards excels in providing a rich set of tools for component development and testing. The choice between the two depends on project requirements and developer preferences.

2,720

Fast library for rendering HTML in Clojure

Pros of Hiccup

  • Lightweight and focused on HTML generation
  • Simpler learning curve for basic HTML rendering
  • More widely adopted in the Clojure ecosystem

Cons of Hiccup

  • Limited to HTML generation, lacks interactive development features
  • No built-in support for live reloading or component isolation
  • Less suitable for complex UI development and testing

Code Comparison

Hiccup:

(html [:div {:class "example"}
       [:h1 "Hello, World!"]
       [:p "This is a simple Hiccup example."]])

DevCards:

(defcard my-component
  (fn [data-atom _]
    [:div
     [:h1 "Interactive Component"]
     [:p "Current value: " @data-atom]
     [:button {:on-click #(swap! data-atom inc)} "Increment"]])
  (reagent/atom 0))

Summary

Hiccup is a lightweight library for generating HTML in Clojure, offering a simple syntax for creating markup. It's widely used and easy to learn but lacks features for interactive development.

DevCards, on the other hand, provides a more comprehensive toolkit for developing and testing UI components in isolation. It offers live reloading, state management, and interactive examples, making it more suitable for complex UI development but with a steeper learning curve.

Choose Hiccup for simple HTML generation tasks, and DevCards for more advanced UI development and testing workflows in ClojureScript projects.

1,024

Simple and powerful tool for building web apps out of highly composable elements in ClojureScript.

Pros of Hoplon

  • Full-stack web framework, offering a complete solution for building web applications
  • Leverages ClojureScript's reactive programming model for efficient UI updates
  • Provides a unified language (Clojure) for both client and server-side development

Cons of Hoplon

  • Steeper learning curve due to its comprehensive nature and unique concepts
  • Less focused on component-level development and testing
  • May be overkill for smaller projects or those not requiring a full-stack solution

Code Comparison

Hoplon example:

(page "index.html"
  (:require [hoplon.core :as h])
  (h/body
    (h/h1 "Hello, Hoplon!")
    (h/p "Welcome to my Hoplon app.")))

Devcards example:

(defcard my-first-card
  (fn [data-atom _] [:div "Hello, Devcards!"])
  {:initial-data {}})

Key Differences

Hoplon is a full-stack web framework, while Devcards focuses on component development and testing. Hoplon uses a more declarative syntax for building UIs, whereas Devcards leverages React-style components. Devcards excels in isolated component development and documentation, while Hoplon provides a more integrated approach to building entire web applications.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Devcards

Current release:

Clojars Project

Devcards aims to provide ClojureScript developers with an interactive visual REPL. Devcards makes it simple to interactively surface code examples that have a visual aspect into a browser interface.

Devcards is not a REPL, as it is driven by code that exists in your source files, but it attempts to provide a REPL-like experience by allowing developers to quickly try different code examples and see how they behave in an actual DOM.

Devcards is centered around a notion of a card. Every card represents some code to be displayed. Devcards provides an interface which allows the developer to navigate to different namespaces and view the cards that have been defined in that namespace.

When used in conjunction with lein figwheel the cards can be created and edited "live" in one's ClojureScript source files. Essentially lifting the code example out of the file into the browser for you to try out immediately.

For example, the following code will create a card for a Sablono template that you might be working on:

(defcard two-zero-48-view 
  (sab/html
    [:div.board 
      [:div.cells
        [:div {:class "cell xpos-1 ypos-1"} 4]
        [:div {:class "cell xpos-1 ypos-2"} 2]
        [:div {:class "cell xpos-1 ypos-3"} 8]]]))

When used with lein-figwheel, saving the file that contains this definition will cause this Sablono template to be rendered into the Devcards interface.

Read: The Hard Sell

See the introduction video.

See the Strange Loop talk.

Why???

We primarily design and iterate on our front end applications inside the main application itself. In other words, our execution environment is constrained by the shape and demands of the application we are working on. This is extremely limiting.

This doesn't seem like a problem, eh?

Well think of it this way: the main application and its many subcomponents can potentially embody a tremendous number of states. But working against a single instance of the application only lets you look at one state at a time. What if you could work on the application or component in several states at the same time? This is a powerful multiplier. You are increasing the bandwidth of the feedback you are getting while working on your code.

Another problem is that we often manually place our components into different important states to run them through their paces as we develop them. But ... these test states are ephemeral. Wouldn't it be better to keep a development "page" as a permanent asset where these components are displayed in these various states as a

  • a lab space for future development
  • a code reference for new developers, and your future self
  • a tool for QA and application testers

Developing your components in a different context than your main application starkly reveals environmental coupling, in the same way that unit tests often do. This can lead to developing components that are more independent than the ones that are developed inside the main app.

One more thing: developing your components in a SPA that isn't your main application provides you a space to create and use visual components that are intended to help you understand the code you are working on. We are UI programmers after all, why wait for IDEs to create the tools we need? Most problems are unique and can benefit tremendously from the creation of a very thin layer of custom tooling.

Developing inside the main application is constraining and it isn't until you develop inside a meta application that you can see this more clearly. With a meta application, you now have a space to try things out that do not have to interface or fit into the main application. This is extremely important as it gives you space to try new things without the cost that is currently associated with experiments (branching, new html host file, etc).

Examples

Regardless of which path you take to get started with Devcards please see the following examples:

Introduction examples (src)

An example implementation of 2048 (src)

An introduction to the defcard api (src)

Super Quick Start

There is a Devcards Leiningen template to get you up an running quickly.

Make sure you have the latest version of leiningen installed.

Type the following to create a fresh project with devcards setup for you:

lein new devcards hello-world

Then

cd hello-world

lein figwheel

to start the figwheel interactive devserver.

Then visit http://localhost:3449/cards.html

Quick Trial

If you want to quickly interact with a bunch of devcards demos:

git clone https://github.com/bhauman/devcards.git

cd devcards

lein figwheel

Then visit http://localhost:3449/devcards/index.html

The code for the cards you are viewing in the devcards interface is located in the example_src directory.

Go ahead and edit the code in the examples and see how the devcards interface responds.

Usage

First make sure you include the following :dependencies in your project.clj file.

[org.clojure/clojurescript "1.10.238"]
[devcards "0.2.5"]

You will need an HTML file to host the devcards interface. It makes sense to have a separate file to host devcards. I would create the following resources/public/cards.html file (this is the same file as in the leiningen template).

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta charset="UTF-8">
    <link href="/css/example.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <script src="/js/compiled/example.js" type="text/javascript"></script>
  </body>
</html>

Usage With Figwheel

lein-figwheel is not required to use Devcards but it is definitely recommended if you want to experience interactive coding with Devcards. See the lein-figwheel repo for instructions on how to do that.

Configure your devcards build:

:cljsbuild {
 :builds [
   {:id "devcards"
    :source-paths ["src"]   
    :figwheel { :devcards true } ;; <- note this
    :compiler { :main    "{{your lib name}}.core"
                :asset-path "js/compiled/devcards_out"
                :output-to  "resources/public/js/{{your lib name}}_devcards.js"
                :output-dir "resources/public/js/devcards_out"
                :source-map-timestamp true }}]
}                

Next you will need to include the Devcards macros into your file:

(ns example.core
  (:require
   [sablono.core :as sab]) ; just for example
  (:require-macros
   [devcards.core :refer [defcard]]))

(defcard my-first-card
  (sab/html [:h1 "Devcards is freaking awesome!"]))

This will create a card in the devcards interface.

Take a look at the defcard api (src)

Usage without Figwheel

Figwheel does some magic so that Devcards can be included or excluded from your code easily. You can certainly use Devcards without Figwheel, but there are three things that you will need to do.

You need to specify :devcards true in the build-options of your ClojureScript build

{ :main    "{{name}}.core"
  :devcards true ; <- note this
  :asset-path "js/compiled/devcards_out"
  :output-to  "resources/public/js/{{sanitized}}_devcards.js"
  :output-dir "resources/public/js/devcards_out"
  :source-map-timestamp true }

This is important as it is a signal to the defcard macro to render the cards. This is equivalent to adding :figwheel { :devcards true } in our figwheel based build above, but since we aren't using figwheel in this build adding the figwheel options doesn't help.

You will need to require devcards.core in the files that use devcards as such:

(ns example.core
  (:require
   [devcards.core :as dc] ; <-- here
   [sablono.core :as sab]) ; just for this example
  (:require-macros
   [devcards.core :refer [defcard]])) ; <-- and here

(defcard my-first-card
  (sab/html [:h1 "Devcards is freaking awesome!"]))

This isn't required with Figwheel because it puts devcards.core into the build automatically.

You will need to start the Devcards UI

(devcards.core/start-devcard-ui!)

Make sure this is included in the file you have specified as :main in your build options. As mentioned above, you don't want the Devcards UI to compete with your application's UI so you will want to make sure it isn't getting launched.

Devcards as a Standalone Website

Devcards can easily be hosted as a standalone website by following steps similar to those needed to use it locally without figwheel. In this example, we will be adding a hostedcards profile to build our site.

Add :devcards true to the build-options of our ClojureScript build profile

{:id "hostedcards"
 :source-paths ["src"]
 :compiler {:main "{{your lib name}}.core"
            :devcards true ; <- note this
            :asset-path "js/compiled/out"
            :output-to  "resources/public/js/compiled/{{your lib name}}.js"
            :optimizations :advanced}}

Require devcards.corein the files that use devcards

(ns {{your lib name}}.core
  (:require
   [devcards.core :as dc]) 
  (:require-macros
   [devcards.core :refer [defcard]])) 

Start the Devcards UI in {{your lib name}}.core

(devcards.core/start-devcard-ui!)   

Include the compiled JS in our HTML

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="/css/{{your lib name}}.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div id="main-app-area"></div>
    <script src="/js/compiled/{{your lib name}}.js" type="text/javascript"></script>
  </body>
</html>

Run our Build

lein cljsbuild once hostedcards

Once the build is complete, simply copy the contents of resources\public to your webserver and serve it up as you would any other page.

FAQ

Does Devcards only work with React or Om?

Nope, it can work with arbitrary CLJS code examples as well. Devcards provides a dom-node helper that will give you a node in the DOM to display stuff in.

Does Devcards require Figwheel?

Devcards will work automatically with REPL workflow or boot-reload.

You can also just reload the browser after making a change.

What do I do for deployment?

Devcards has been rewritten so that you can write Devcards alongside your code with no impact on your production code.

That being said it is often helpful to move the bulk of your cards to a different buildpath that is only built when working on the devcards build.

When working with devcards I often have three builds "devcards", "dev", "prod".