Open-source project
day8/re-frame-template avatar
day8/re-frame-template

re-frame-template turns lein new into a working re-frame app in a minute

A Leiningen template for creating a re-frame application (client only) with a shadow-cljs build.

601 stars87 forksClojureMIT

At a glance

What is it?
re-frame-template is a Leiningen template that scaffolds a client-side re-frame application with a shadow-cljs build, and lets you pick libraries for routing, debugging, CSS and editor integration as extras on the command line. It removes the setup decisions a new ClojureScript project otherwise starts with, and it is a template rather than a framework.
Who is it for?
re-frame-template suits a team starting a new browser-side ClojureScript application with re-frame who would rather pick their routing, debugging and editor tooling from a known list than assemble it themselves, and the extras mechanism makes that choice reproducible across projects. It is the wrong tool if you are building a full stack application, since the template is explicitly client only, or if you have already standardised on a different build and editor setup.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 176 days ago.
What is it written in?
Mainly Clojure, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the template actually generates

re-frame-template is a Leiningen template for creating a re-frame application scaffold, client only, with a shadow-cljs build. The pitch in the README is that it will take you 60 seconds to create your first re-frame app and start to edit it.

The base template includes three things: re-frame itself, shadow-cljs, and cljs-devtools. Those are the non-negotiable parts of a re-frame project, and choosing them yourself means picking a build tool and a REPL workflow before you write a line of application code.

The prerequisite list is short, and that is deliberate for a template. You need Leiningen, installed by following the linked instructions, and Node.js. There is no database, no backend service and no container to set up, because the scope is the client.

The project it produces is a ClojureScript application with a shadow-cljs build, and the README describes the two supported editor paths in detail, CIDER from Emacs and Calva from VS Code, down to the keystrokes and the URL you open when the app is running. The Calva path exists as its own section because Calva has built-in support for shadow-cljs projects, which is stated as the reason there is no +calva option.

For an engineer starting from nothing, this is the value: the decisions are made once by the template and the remaining work is your own application code.

Extras are the design decision the template hands to you

You can pick and choose the extras included in the scaffold, described as libraries to do routing, debugging and CSS. They are nominated on the command line when the template runs, and each has a short name.

The CSS extra is garden with spade, named +garden. The debug extras are re-frame-10x as +10x and re-frisk as +re-frisk. The development extras are cider as +cider, clj-kondo as +kondo, cljs.test as +test, and git-inject as +git-inject. The miscellaneous group holds re-com as +re-com, re-pressed as +re-pressed, breaking-point as +breaking-point and github-actions as +github-actions. Routing is bidi with pushy, named +routes.

To add one, append its name to the command line with a leading plus, and the README stresses that it is +re-com and not re-com:

code
lein new re-frame <app-name> +re-com

Any combination can be added at once:

code
lein new re-frame <app-name> +garden +re-com +routes +test +10x

That last example is a reasonable default for a new project, since it takes routing, a component library, CSS, a test setup and a debugging tool in one line. The README also advises, in a note, that for debugging you want either +10x or +re-frisk.

Because the extras are command-line flags, the scaffold is reproducible. You can put the exact lein new invocation in a README or a script and every developer gets the same dependency set, which removes the usual argument about which routing library a project uses.

Creating the project and starting the watch build

With the base template only, the command is:

sh
$ lein new re-frame <app-name>

The angle brackets are a placeholder you replace with your own name, and the README suggests names along the lines of my-killer-app or an-early-masterpiece.

Once the project exists, the run instructions are short. The first option is the npm scripts:

sh
npm install
npm run watch

The alternative drives shadow-cljs directly and names the builds explicitly:

sh
npm install
npx shadow-cljs watch app browser-test node-test

The difference is scope. The npm script is the everyday loop, while the explicit command shows which builds the project knows about, app, browser-test and node-test. To see the other available shadow-cljs commands, run:

code
npx shadow-cljs --help

After the build finishes, the app is served on port 8280, and the README says to wait perhaps 20 seconds while keeping an eye out for a sign the compile has finished, then browse to http://localhost:8280. The presence of browser-test and node-test builds in that command is worth noting, since it means the template ships with test targets already configured rather than leaving them to be added later.

The app name cljs breaks the compiler

There is one troubleshooting note in the README, and it is worth reading before you generate anything, because the failure it describes is confusing when it happens.

For the app name, do not use cljs. That name will confuse the compiler, and you will later see errors like cljs.core.init is not a function.

This is the kind of detail that a template is supposed to prevent, and here it did not, because the name is supplied by the user at generation time and the compiler only complains much later. The symptom appears far from the cause: an error about a core function not being a function, in a project where everything was generated by a tool that was supposed to work.

The same kind of trap is described in the browser setup notes. Before developing, you should tweak two settings in your browser devtools, one-time actions for each browser and laptop you use, the first being the Network option to disable cache while devtools is open. The README assumes Chrome for the explanation and points out that it is the devtools settings panel rather than the Chrome settings panel that you need. The second setting is cut off in the copy of the documentation available here, so the pair of changes is not fully specified in this file.

A template reduces the number of decisions, but it does not remove the possibility of a wrong input.

Editor wiring for CIDER and Calva

Two editor paths are documented, and they work differently.

With the +cider extra you start CIDER from Emacs, and the README refers you to the shadow-cljs Emacs and CIDER documentation for the details. The relevant point is that the template creates a dir-local.el file, which is how the per-project editor configuration reaches Emacs.

Calva from VS Code takes the longer path. You run npm install, then issue the Calva command to start a project REPL and connect, using the keybinding ctrl+alt+c ctrl+alt+j. Calva detects that the project is a shadow-cljs project and asks which build to compile, and you select :app. The README notes that :app is the only configured build but that the VS Code menu for this is a bit strange, so you should make sure the :app checkbox is really ticked before proceeding.

From there, the output window logs progress, and once the app is compiled you open http://localhost:8280 and confirm that it says Hello from re-frame. Depending on how long the app takes to compile, you might need to reload the page a few times. You then open views.cljs from src/<your-project-name> and load the current file and its dependencies, and confirm the connection by evaluating a JavaScript alert. The last check is the useful one, changing the greeting message to confirm that Shadow hot reloading works.

In this workflow you skip the run application steps entirely, since the jack-in has already started the app.

Doing it by hand versus starting from the template

The alternative to the template is to assemble the project yourself: write a project.clj with re-frame, shadow-cljs and cljs-devtools as dependencies, create the shadow-cljs configuration with an :app build and the browser-test and node-test targets, set up the npm scripts, and then add whichever routing, CSS and debugging libraries you prefer. Every one of those choices is small, and all of them are decisions.

The template's approach is to fix the first set of choices and expose the second set as named flags. The difference in approach is where the opinions live. In a hand-built project every dependency is an individual argument in one conversation, and the resulting project.clj looks different from project to project. In a templated project the base is fixed, the extras are visible on the command line, and the difference between two projects is a single string you can read off the terminal.

There is a second difference worth naming. A template can encode the things that are easy to miss, such as the shadow-cljs build configuration, the npm scripts, the presence of test targets and, in the case of +cider, the dir-local.el file that makes Emacs pick up the project configuration. Hand assembly gets those right only if you remember them.

What the template does not do is change the shape of the application. It is a client-only scaffold, so a full stack project that also needs a server is not what it produces, and there is no extra to add for that.

Release cadence and what the template leaves under version control

The releases move in small steps. The recent tags are v2.4.15 on 2026-04-30, v2.4.14 on 2026-04-29 and v2.4.13 on 2024-04-27, so the last two patch releases arrived on consecutive days and the one before them is more than two years older. The last push was on 2026-04-30, and the repository is not archived. The template is published on Clojars as re-frame/lein-template, which is where lein new resolves it from.

For a team, the practical consequence is that you can pin the template version when you generate a project, which makes the scaffold reproducible across a team and across time. The downside is that a scaffold generated a year ago with an old tag will not receive updates to the base dependency set, since the base is baked in at generation time.

The licence is MIT, so the generated scaffold and the template itself can be used, modified and redistributed with attribution and no other obligation.

The repository layout gives a sense of how the template is assembled. There is a create-templates.sh script at the root, a project.clj for the template project itself, and resources and src directories that hold the files copied into a generated project. There is also a CHANGELOG.md, a docs directory, and, notably, AGENTS.md and CLAUDE.md files along with a .claude directory and a .beads directory, which point to the project being maintained with AI assistance tooling in mind.

Editorial conclusion

re-frame-template suits a team starting a new browser-side ClojureScript application with re-frame who would rather pick their routing, debugging and editor tooling from a known list than assemble it themselves, and the extras mechanism makes that choice reproducible across projects. It is the wrong tool if you are building a full stack application, since the template is explicitly client only, or if you have already standardised on a different build and editor setup. Verify first that the extras you need exist, since the list is fixed and includes entries such as +routes, +10x and +cider, and check that the generated project starts with npm install and npm run watch before you build on top of it.

Frequently asked questions

How do I create a new re-frame application with re-frame-template?

Install Leiningen and Node.js, then run lein new re-frame with your app name, for example lein new re-frame my-killer-app. Add extras such as +routes or +10x with a leading plus sign on the same command line.

Which extras are available in re-frame-template?

The extras cover CSS with garden and spade as +garden, debugging with re-frame-10x as +10x and re-frisk as +re-frisk, development tools such as +cider, +kondo, +test and +git-inject, libraries such as +re-com, +re-pressed and +breaking-point, +github-actions, and routing with bidi and pushy as +routes.

How do I run the generated re-frame app?

Run npm install and then npm run watch, or drive shadow-cljs directly with npx shadow-cljs watch app browser-test node-test. Once the compile finishes, open http://localhost:8280 and you should see the Hello from re-frame greeting.

Is there a problem with naming my app cljs?

Yes. The README warns not to use cljs as the app name because it confuses the compiler, and you will later see errors like cljs.core.init is not a function.

Official sources

  1. day8/re-frame-template on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/day8-re-frame-template.svg)](https://hysenlabs.com/projects/day8-re-frame-template)

Was this useful?