{"id":13549773,"url":"https://github.com/bhauman/devcards","last_synced_at":"2025-04-11T03:29:48.053Z","repository":{"id":16861527,"uuid":"19621689","full_name":"bhauman/devcards","owner":"bhauman","description":"Devcards aims to provide a visual REPL experience for ClojureScript","archived":false,"fork":false,"pushed_at":"2023-09-17T15:16:13.000Z","size":7049,"stargazers_count":1532,"open_issues_count":30,"forks_count":112,"subscribers_count":40,"default_branch":"master","last_synced_at":"2025-04-03T18:09:58.119Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bhauman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["bhauman"]}},"created_at":"2014-05-09T18:46:00.000Z","updated_at":"2025-04-02T20:01:07.000Z","dependencies_parsed_at":"2024-05-01T15:27:26.401Z","dependency_job_id":"4d6d106f-73d4-41bb-b281-db039d9cd19f","html_url":"https://github.com/bhauman/devcards","commit_stats":{"total_commits":455,"total_committers":41,"mean_commits":"11.097560975609756","dds":"0.14065934065934071","last_synced_commit":"65caa84c9438dd8bdf8cd21964e6033b1a22c178"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhauman%2Fdevcards","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhauman%2Fdevcards/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhauman%2Fdevcards/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhauman%2Fdevcards/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bhauman","download_url":"https://codeload.github.com/bhauman/devcards/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248335267,"owners_count":21086545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T12:01:25.339Z","updated_at":"2025-04-11T03:29:48.014Z","avatar_url":"https://github.com/bhauman.png","language":"Clojure","funding_links":["https://github.com/sponsors/bhauman"],"categories":["Clojure","others","Awesome ClojureScript"],"sub_categories":["Development"],"readme":"# Devcards\n\n### Current release:\n\n[![Clojars Project](https://clojars.org/devcards/latest-version.svg)](https://clojars.org/devcards)\n\nDevcards aims to provide ClojureScript developers with an interactive\nvisual REPL. Devcards makes it simple to interactively surface code\nexamples that have a visual aspect into a browser interface. \n\nDevcards is **not** a REPL, as it is driven by code that exists in\nyour source files, but it attempts to provide a REPL-like experience\nby allowing developers to quickly try different code examples and\nsee how they behave in an actual DOM.\n\nDevcards is centered around a notion of a *card*. Every card\nrepresents some code to be displayed. Devcards provides an interface\nwhich allows the developer to navigate to different namespaces and view\nthe *cards* that have been defined in that namespace. \n\nWhen used in conjunction with [lein figwheel][leinfigwheel] the cards\ncan be created and edited **\"live\"** in one's ClojureScript source\nfiles. Essentially lifting the code example out of the file into the\nbrowser for you to try out immediately.\n\n\u003cimg src=\"https://s3.amazonaws.com/bhauman-blog-images/devcards-action-shot.png\"/\u003e\n\nFor example, the following code will create a *card* for a Sablono\ntemplate that you might be working on:\n\n```clojure\n(defcard two-zero-48-view \n  (sab/html\n    [:div.board \n      [:div.cells\n        [:div {:class \"cell xpos-1 ypos-1\"} 4]\n        [:div {:class \"cell xpos-1 ypos-2\"} 2]\n        [:div {:class \"cell xpos-1 ypos-3\"} 8]]]))\n```\n\nWhen used with [lein-figwheel][leinfigwheel], saving the file that\ncontains this definition will cause this Sablono template to be\nrendered into the Devcards interface.\n\nRead: [The Hard Sell](http://rigsomelight.com/devcards/#!/devdemos.core) \n\n[See the introduction video.](https://vimeo.com/97078905)\n\n[See the Strange Loop talk.](https://www.youtube.com/watch?v=G7Z_g2fnEDg)\n\n# Why???\n\nWe primarily design and iterate on our front end applications *inside*\nthe main application itself. In other words, our execution environment\nis constrained by the shape and demands of the application we are\nworking on. This is extremely limiting.\n\nThis doesn't seem like a problem, eh?\n\nWell think of it this way: the main application and its many\nsubcomponents can potentially embody a tremendous number of states. But\nworking against a single instance of the application only lets you\nlook at one state at a time. What if you could work on the application\nor component in several states at the same time? This is a powerful\nmultiplier. You are **increasing the bandwidth of the feedback** you are\ngetting while working on your code.\n\nAnother problem is that we often manually place our components into\ndifferent **important** states to run them through their paces as we\ndevelop them. But ... these test states are **ephemeral**. Wouldn't\nit be better to **keep** a development \"page\" as a permanent asset\nwhere these components are displayed in these various states as a\n\n* a lab space for future development\n* a code reference for new developers, and your future self\n* a tool for QA and application testers\n\nDeveloping your components in a different context than your main\napplication **starkly reveals environmental coupling**, in the same\nway that unit tests often do. This can lead to developing components\nthat are more independent than the ones that are developed inside the\nmain app.\n\nOne more thing: developing your components in a SPA that isn't your\nmain application provides you a space to create and use visual\ncomponents that are intended to help you understand the code you are\nworking on. We are UI programmers after all, why wait for IDEs to\ncreate the tools we need? Most problems are unique and can benefit\ntremendously from the creation of a very thin layer of custom tooling.\n\nDeveloping inside the main application is constraining and it isn't\nuntil you develop inside a **meta application** that you can see this\nmore clearly. With a meta application, you now have a space to try\nthings out that **do not have to interface or fit into the main\napplication**. This is extremely important as it gives you space to\ntry new things without the cost that is currently associated with\nexperiments (branching, new html host file, etc).\n\n## Examples\n\nRegardless of which path you take to get started with Devcards please\nsee the following examples:\n\n[Introduction examples](http://rigsomelight.com/devcards/#!/devdemos.core) ([src](https://github.com/bhauman/devcards/blob/master/example_src/devdemos/core.cljs))\n\n[An example implementation of 2048](http://rigsomelight.com/devcards/#!/devdemos.two_zero) ([src](https://github.com/bhauman/devcards/blob/master/example_src/devdemos/two_zero.cljs))\n\n[An introduction to the `defcard` api](http://rigsomelight.com/devcards/#!/devdemos.defcard_api) ([src](https://github.com/bhauman/devcards/blob/master/example_src/devdemos/defcard_api.cljs))\n\n## Super Quick Start\n\nThere is a Devcards Leiningen template to get you up an running quickly.\n\nMake sure you have the [latest version of leiningen installed](https://github.com/technomancy/leiningen#installation).\n\nType the following to create a fresh project with devcards setup for you:\n\n```\nlein new devcards hello-world\n```\n\nThen\n\n```\ncd hello-world\n\nlein figwheel\n```\n\nto start the figwheel interactive devserver.\n\nThen visit `http://localhost:3449/cards.html`\n\n## Quick Trial\n\nIf you want to quickly interact with a bunch of devcards demos:\n\n```\ngit clone https://github.com/bhauman/devcards.git\n\ncd devcards\n\nlein figwheel\n```\n\nThen visit `http://localhost:3449/devcards/index.html`\n\nThe code for the cards you are viewing in the devcards interface is\nlocated in the `example_src` directory.\n\nGo ahead and edit the code in the examples and see how the devcards\ninterface responds.\n\n## Usage\n\nFirst make sure you include the following `:dependencies` in your `project.clj` file.\n\n```clojure\n[org.clojure/clojurescript \"1.10.238\"]\n[devcards \"0.2.5\"]\n```\n\nYou will need an HTML file to host the devcards interface. It makes\nsense to have a separate file to host devcards. I would \ncreate the following `resources/public/cards.html` file (this is the same\nfile as in the leiningen template).\n\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\"\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003clink href=\"/css/example.css\" rel=\"stylesheet\" type=\"text/css\"\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cscript src=\"/js/compiled/example.js\" type=\"text/javascript\"\u003e\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Usage With Figwheel\n\n[lein-figwheel](https://github.com/bhauman/lein-figwheel) \nis not required to use Devcards but it is definitely recommended\nif you want to experience interactive coding with Devcards.\nSee the [lein-figwheel repo](https://github.com/bhauman/lein-figwheel)\nfor instructions on how to do that.\n\nConfigure your devcards build:\n\n```clojure\n:cljsbuild {\n :builds [\n   {:id \"devcards\"\n    :source-paths [\"src\"]   \n    :figwheel { :devcards true } ;; \u003c- note this\n    :compiler { :main    \"{{your lib name}}.core\"\n                :asset-path \"js/compiled/devcards_out\"\n                :output-to  \"resources/public/js/{{your lib name}}_devcards.js\"\n                :output-dir \"resources/public/js/devcards_out\"\n                :source-map-timestamp true }}]\n}                \n```\n\n\nNext you will need to include the Devcards macros into your file:\n\n```clojure\n(ns example.core\n  (:require\n   [sablono.core :as sab]) ; just for example\n  (:require-macros\n   [devcards.core :refer [defcard]]))\n\n(defcard my-first-card\n  (sab/html [:h1 \"Devcards is freaking awesome!\"]))\n```\n\nThis will create a card in the devcards interface.\n\nTake a look at [the `defcard` api](http://rigsomelight.com/devcards/#!/devdemos.defcard_api) ([src](https://github.com/bhauman/devcards/blob/master/example_src/devdemos/defcard_api.cljs))\n\n## Usage without Figwheel\n\nFigwheel does some magic so that Devcards can be included or excluded\nfrom your code easily. You can certainly use Devcards without Figwheel,\nbut there are three things that you will need to do.\n\n#### You need to specify `:devcards true` **in the build-options** of your ClojureScript build\n\n```clojure\n{ :main    \"{{name}}.core\"\n  :devcards true ; \u003c- note this\n  :asset-path \"js/compiled/devcards_out\"\n  :output-to  \"resources/public/js/{{sanitized}}_devcards.js\"\n  :output-dir \"resources/public/js/devcards_out\"\n  :source-map-timestamp true }\n```\n\nThis is important as it is a signal to the `defcard` macro to render\nthe cards. This is equivalent to adding `:figwheel { :devcards true }` \nin our figwheel based build above, but since we aren't using figwheel\nin this build adding the figwheel options doesn't help.\n\n#### You will need to require `devcards.core` in the files that use devcards as such:\n\n```clojure\n(ns example.core\n  (:require\n   [devcards.core :as dc] ; \u003c-- here\n   [sablono.core :as sab]) ; just for this example\n  (:require-macros\n   [devcards.core :refer [defcard]])) ; \u003c-- and here\n\n(defcard my-first-card\n  (sab/html [:h1 \"Devcards is freaking awesome!\"]))\n```\n\nThis isn't required with Figwheel because it puts `devcards.core` into the\nbuild automatically.\n\n#### You will need to start the Devcards UI\n\n```\n(devcards.core/start-devcard-ui!)\n```\n\nMake sure this is included in the file you have specified as `:main` \nin your build options. As mentioned above, you don't want the Devcards UI to compete with\nyour application's UI so you will want to make sure it isn't getting\nlaunched. \n\n\n## Devcards as a Standalone Website\n\nDevcards can easily be hosted as a standalone website by following\nsteps similar to those needed to use it locally without figwheel.\nIn this example, we will be adding a `hostedcards` profile to build\nour site.\n\n#### Add `:devcards true` **to the build-options** of our ClojureScript build profile\n\n```clojure\n{:id \"hostedcards\"\n :source-paths [\"src\"]\n :compiler {:main \"{{your lib name}}.core\"\n            :devcards true ; \u003c- note this\n            :asset-path \"js/compiled/out\"\n            :output-to  \"resources/public/js/compiled/{{your lib name}}.js\"\n            :optimizations :advanced}}\n```\n\n#### Require `devcards.core`in the files that use devcards\n\n```clojure\n(ns {{your lib name}}.core\n  (:require\n   [devcards.core :as dc]) \n  (:require-macros\n   [devcards.core :refer [defcard]])) \n```\n\n### Start the Devcards UI in {{your lib name}}.core\n```clojure\n(devcards.core/start-devcard-ui!)   \n```\n\n### Include the compiled JS in our HTML \n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n    \u003clink href=\"/css/{{your lib name}}.css\" rel=\"stylesheet\" type=\"text/css\"\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cdiv id=\"main-app-area\"\u003e\u003c/div\u003e\n    \u003cscript src=\"/js/compiled/{{your lib name}}.js\" type=\"text/javascript\"\u003e\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n``` \n\n\n### Run our Build\n\n`lein cljsbuild once hostedcards`\n\nOnce the build is complete, simply copy the contents of `resources\\public` \nto your webserver and serve it up as you would any other page.\n\n## FAQ\n\n#### Does Devcards only work with React or Om?\n\nNope, it can work with arbitrary CLJS code examples as well. Devcards\nprovides a `dom-node` helper that will give you a node in the DOM to\ndisplay stuff in.\n\n#### Does Devcards require Figwheel?\n\nDevcards will work automatically with REPL workflow or boot-reload.\n\nYou can also just reload the browser after making a change.\n\n#### What do I do for deployment?\n\nDevcards has been rewritten so that you can write Devcards alongside\nyour code with no impact on your production code.\n\nThat being said it is often helpful to move the bulk of your cards to\na different buildpath that is only built when working on the **devcards**\nbuild.\n\nWhen working with devcards I often have three builds \"devcards\",\n\"dev\", \"prod\".\n\n\n\n\n[leinfigwheel]: https://github.com/bhauman/lein-figwheel\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbhauman%2Fdevcards","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbhauman%2Fdevcards","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbhauman%2Fdevcards/lists"}