• Stars
    star
    230
  • Rank 174,053 (Top 4 %)
  • Language
    Clojure
  • License
    Apache License 2.0
  • Created almost 6 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A leiningen template to generate ClojureScript Terminal-User-Interface applications built on web technologies you already know.

ClojureScript Terminal-User-Interface Template

CLJS TUI Template Build Status CLJS TUI Template on Clojars Discuss with Clojurians on Zulip

Create rich Terminal-User-Interface (TUI) apps in ClojureScript using web technologies you already know.

Demo of CLJS TUI

Table of Contents

  1. Quick Start
  2. Features
  3. What's included?
  4. Usage
  5. Getting Started
  6. Dependencies and Further Information
  7. Frequently Asked Questions
  8. Credits
  9. Thanks
  10. Support
  11. Contributing
  12. License

Quick Start

Getting started is easy. Assuming you have node, clojure, and lein 2 installed:

lein new cljs-tui my-test-project
cd my-test-project
npm run init

Once the ClojureScript builds run it in another terminal window:

node --inspect target/js/compiled/my-test-project.js

You should now see the demo UI from the gif above.

Features

Develop rich apps, live with ClojureScript

Re-render on Save

cljs-tui save demo

Change a view within a ClojureScript source file, save it, and the build server will automatically re-build your app and re-render your views without losing state. Ideal when developing nested views.

Instant changes from REPL

cljs-tui REPL demo

Connect your editor to the nREPL server and send code changes to your running app without even saving a file. Ideal for changing application state, redefining functions, or debugging.

Use web technologies you already know

  • Write views in React with the ClojureScript Reagent wrapper.
  • Reagent views compose together just like React components

Create rich applications

  • Use Reagent atoms for simple, local state updates
  • Use Reframe for handling effects and updating shared app state
  • Leverage functional programming and data-oriented design to the fullest for a fast feedback cycle.

Distribute your applications

Transpile ClojureScript into vanilla JS and distribute your application on NPM for easy installation and quick startup times.

What's included?

Upon generating an app from this template the following resources will be available with slight differences depending on the build tool you choose.

<root>
|- bin/
|  |- <project-name>       - A JS script to run your compiled app as a npm binary
|- docs/
|  |- intro.md             - A docs into template
|- env/
|  |- <project_name>/
|  |  |- debug/views.cljs  - A debug view to display current state and captured text output
|  |  app.cljs             - Development app entrypoint. Handle reloading, re-rendering, and initializing the debug views
|  |- dev/user.clj         - Only for figwheel based builds
|- scripts/
|  |- build                - A bash script for creating a production build
|- src/
|  |- <project_name>/
|  |  |- demo/
|  |  |  |- views.cljs     - Demo app views. You can do whatever you want with these
|  |  |- core.cljs         - Initialize the stateful application dependencies like reframe, reagent, and blessed
|  |  |- events.cljs       - Re-frame event handlers and intercepters to update app state db
|  |  |- keys.cljs         - Utils for handling key presses and global keyboard event handlers
|  |  |- main.cljs         - Production app entrypoint
|  |  |- subs.cljs         - Re-frame subscriptions to app state db
|  |  |- views.cljs        - General views such as a primitive router and vertical menu components
|- test/
|  |- <project_name>/
|  |  |- core_test.cljs    - A sample test. Should fail until fixed
|  |  |- test_runner.cljs  - Figwheel builds only. Runs tests and ensures proper exit codes for CI
|- .gitignore
|- .hgignore
|- CHANGELOG.md
|- dev.cljs.edn            - Figwheel-main development config.
|- figwheel-main.edn       - Figwheel-main config only
|- LICENSE
|- package.json            - Used to manage your npm modules and config for publishing to npm
|- prod.cljs.edn           - Figwheel-main production config
|- project.clj             - Figwheel builds only
|- README.md
|- shadow-cljs.edn         - Shadow-cljs builds only. ClojureScript build configuration

Usage

Generating a project template

lein new cljs-tui <project-name> [+<build-tool>]

Generate a demo cljs-tui application for the specified build-tool.

Supported build-tool options:

+shadow (default)

http://shadow-cljs.org/

Generate a ClojureScript Terminal-User-Interface app template using shadow-cljs. This is the default build-tool.


+figwheel-main

https://figwheel.org/

Generate a ClojureScript Terminal-User-Interface app template using figwheel-main.


+lein-figwheel

https://github.com/bhauman/lein-figwheel

Generate a ClojureScript Terminal-User-Interface app template using lein-figwheel.


Getting Started

The following steps work for any supported build tool you choose. The tool specific commands have been placed into the project package.json scripts to make the commands consistent between each tool.

All of the following commands assume you are running them in a terminal from the root directory of your generated project.

Installing dependencies

To get started, install the required npm modules into a local node_modules folder.

npm install

Build for development

Start a development build server to watch your files for changes and automatically recompile and reload your app. Your re-frame app state will remain the same but the UI will re-render allowing you to make changes to components deeper into a flow without a tedious manual testing process.

npm start

Running your app

When a development build is first finished the generated JS file is written to target/js/compiled/<project-name>.js. You can execute the following program to start your app and connect to the development server and\or REPL:

node --inspect target/js/compiled/<project-name>.js

Build for production

When you are ready to release your app you will need to do a production build to produce a smaller JS footprint and build a single file the project's bin/<project-name> file will be able to find and use.

npm run build

This will build your ClojureScript app for production, run loose-envify to ensure your code runs in a production environment, and finally moves the compiled JS file to the lib folder as an npm convention. The build process can be found in the scripts/build file in your generated project folder.


Updating NPM dependencies

Your npm modules are managed through your project's package.json file. There are two common ways to update your project's deps.

NPM CLI

Run the following in the project directory:

npm install --save [@scope/]<package-name>[@<version>]

Example:

npm install --save highland

You can find more at npm's install docs

Manual

  1. Update your package.json file dependencies map.
  2. Save your updated package.json.
  3. Run npm install

Using NPM modules

To use a npm module in ClojureScript use JS interop require:

(def stream (js/require "highland"))

Updating Clojure dependencies

Clojure dependencies are handled a bit differently and vary a bit between figwheel and shadow-cljs projects.

After updating your dependencies it's recommended to restart your build server.

figwheel-main or lein-figwheel

Update the dependencies map in your project's project.clj file.

shadow-cljs

Update the dependencies map in your project's shadow-cljs.edn file.


Working with nREPL

All supported build tools do offer an nREPL server option if you would like to develop against the live state of your app. However, the process differs between build tools.

Both figwheel-main and lein-figwheel have an extra development file located in env/dev/user.clj which defines a (start) and (repl) function for working with nREPL.

Starting a nREPL server with figwheel-main or lein-figwheel

  1. Shutdown any running build servers, we're going to run them from the REPL.
  2. Run npm run repl
  3. When the Clojure REPL loads eval (start) to start the build server, nREPL server, and ClojureScript REPL interface.
  4. Once your application compiles, run the compiled node app in another terminal to initialize the ClojureScript REPL:
    node --inspect target/js/compiled/<my-project>.js
    

Starting a nREPL server with shadow-cljs

Amazingly, shadow-cljs starts an nREPL server automatically when you run the build server. When the build server starts it creates an .nrepl-port file most Clojure editor REPL plugins can use to connect with.


Connecting your editor to the REPL

You can use the .nrepl-port file to connect to the running nREPL server. Note when you connect it will be in Clojure and not ClojureScript. You can enter the ClojureScript REPL by evaluating the following form:

user=> (repl)

This behavior is defined in env/dev/user.clj and can be customized with your chosen build-tool's API.

Testing

To run tests run the command following from your project directory:

npm test

This will compile the test build, run the test runner, which will asynchronously run the imported tests files and print the results. The test runner will exit in a non-zero exit code if the tests fail making it compatible with various continuous integration (CI) services. In the near future I would like to setup auto testing so tests rerun upon save.


Dependencies and Further Documentation

This template makes use of many open source projects which may have more docs to support your development with a bigger community behind it.

Clojure

Name Description
Clojure Base tooling runs on Clojure
ClojureScript Language of choice for this template
figwheel-main One of the supported cljs build tools
leiningen Clojure\ClojureScript project management
lein-figwheel Another cljs build tool option, leiningen plugin

Clojure \ ClojureScript

Name Description
Mount Used to manage stateful dependencies
Reagent ClojureScript view layer
Reframe Manages application state and side effects
tools.cli Parse CLI args into hash-maps

npm modules

Name Description
Blessed Abstraction layer over terminal UI
Create-React-Class Bridge react and reagent
React nodejs view layer
React-Blessed Blessed backend for React views
React DOM Required by reagent
Shadow CLJS Default build tool, manages builds, compiles cljs

FAQs

Why ClojureScript?

I really enjoy working with ClojureScript, it's been a fun, productive, and empowering experience so far. My reasoning can be found in the announcement blog post.


Why is Shadow the default build-tool?

After working with all three tools, shadow-cljs provides the smoothest development experience, great docs, and fewest layers. I covered this more in the announcement blog post.


Does this template support boot?

Currently this template only supports leiningen. However, the shadow-cljs build option does not use leiningen or boot at all. Please create an issue if supporting boot would be of interest to you. πŸ˜„


Credits

In early 2019 I saw this link on Reddit in r/clojure:

https://github.com/denisidoro/floki

Denis Isidoro created this beautiful terminal-user-interface JSON explorer app using ClojureScript, Reagent, React, and Blessed. It completely blew my mind! This template would not exist without him or his work on Floki.

Camilo Polymeris came up with the concept and first implementation of this stack in the gist https://gist.github.com/polymeris/5e117676b79a505fe777df17f181ca2e. It then became the basis for Floki, and elements of it even made their way into this template.


Thanks

Big thanks to the Clojurians on Slack and Zulip! They've endured countless beginner Clojure and ClojureScript questions to help put this project together.

Also shout out to VenueBook for supporting my development efforts of this open-source project.


Support

Please create issues on related dependencies unless it is specific to this template. The library communities are more active and have more support resources. If you do run into problems with this template please create an issue on this repo. For the quickest response, share your issue or questions in the cljs-tui-template topic on the Clojurians Zulip chat.


Contributing

Contributors are welcome, please create pull requests or file issues if you would like to discuss it first. There's a lot of potential in this project and it would be better to provide more library views for prototyping apps quickly.


License

Copyright Β© 2019 Jay Zawrotny

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

More Repositories

1

doom-icon

A proposed doom Emacs icon
Clojure
87
star
2

book-report

A Clojure library that turns files into interactive notebooks to make learning from books easier.
Clojure
58
star
3

lein-rebl-example

Example and instructions to use REBL with Leiningen's REPL.
Clojure
27
star
4

clj-cgi-example

A repo of scripts and mini guides for running Clojure as a cgi-script on shared hosts with Babashka
Clojure
24
star
5

dotfiles

Lua
7
star
6

eccentric-icons

A collection of fun alternative icons for various apps.
Clojure
7
star
7

cli-glob

A glob cli to find files quickly including reading from stdin so it can be piped to other unix apps.
JavaScript
7
star
8

gulp-mc-inline-css

A gulp plugin for sending HTML to mailchimp's CSS API
JavaScript
6
star
9

clj-lineart

Generative line art from a clojure-cgi script
Clojure
5
star
10

gulp-sass-grapher

A gulp plugin that makes use of sass-graph.
CoffeeScript
5
star
11

Scripts

Just some bash scripts to make things easier.
Shell
4
star
12

Portfolio

My personal portfolio site/first django app.
Python
4
star
13

doom-conf

Let's make it happen!
4
star
14

clojure-socket-rebl-example

An example of how to setup REBL with a Clojure Socket REPL server.
Clojure
4
star
15

howto-doom

A collection of common quetions and answers about Doom emacs
4
star
16

braincore

An immutable daily log format powered by https://notion.so APIs
Clojure
4
star
17

html_builder

If you are forced to output HTML within a block of PHP you can use my abstraction system to generate well formed HTML and keep your PHP code clean.
PHP
3
star
18

nbb-netlify-demo

Clojure
3
star
19

anakondo-layer

A rudimentary Spacemacs layer for anakondo with Clojure
Emacs Lisp
3
star
20

Python-Lesssons

First note I've been programing for 10 years however I decided to do and complete every lesson from "Learn Python the Hard Way" file by file, and word by word.
Python
3
star
21

beecat

Implementation of NYT's Spelling Bee game in CLJS for my spouse as a birthday present
JavaScript
3
star
22

file-prompt

An interactive prompt for files inspired by git add -i
JavaScript
2
star
23

spelling-bee

An automated solver for the NYTimes Spelling Bee game using ClojureScript, Lumo, and Puppeteer
Clojure
2
star
24

idle-parens

Build source of my github hosted blog
Clojure
2
star
25

960-css-grid

A CSS 960 grid framework, very basic and fairly light.
2
star
26

grid-generator

A cljs app for generating PDF Goodnotes templates with grids
Clojure
2
star
27

learn-ramda

Learn functional programming with Ramda JS
JavaScript
1
star
28

suprepl

A super Repl library to combine nREPL, Cider, REBL, and Rebel-Readline.
Clojure
1
star
29

htmlajax

Code to help a friend.
JavaScript
1
star
30

r5

A functional programming inspired frontend app framework
JavaScript
1
star
31

timepunch

Python
1
star
32

wp-developer-theme

PHP
1
star
33

Jquery-Rotator

Another jQuery Rotator Plugin, aimed more towards developers that I didn't include many options with the intent of keeping lighter, more easily managed code.
1
star
34

for-map

A Clojure hash-map comprehension macro library. Used to emulate python's dict comprehension.
Clojure
1
star
35

robostangsv3

A JS rotator to work with my WordPress mini-theme framework.
PHP
1
star
36

typeflags

A collaborative project for my Type III college course.
JavaScript
1
star
37

vim-cmdttree

A simple plugin to get more out of NERDTree and CMD T
Vim Script
1
star
38

100-days-of-clojure

Write a tiny Clojure program every day!
Clojure
1
star
39

cljs-ring-express

Create a cljs-based web server using node's express + cljs ring interface for middleware
JavaScript
1
star
40

ed-fingerspool

Exploration Divers Finger Spool Test
1
star
41

nbb-fetch-ws-example

How to use node babashka to use the fetch api with node 18
Clojure
1
star
42

AS3-Website-Class

My website ActionScript3 class for website stuff. It's going to need some iterating tom make useful though :P
ActionScript
1
star
43

Reset-CSS

Eric Meyer's Reset CSS with some edits of mine
1
star
44

comicsbulletin

PHP
1
star
45

pierce_engineering

JavaScript
1
star
46

Wordpress-Vanilla-Login-Plugin

A plugin that basically allows users from a local vanilla forum to write comments which post to a discussion and use their vanilla profiles, login info, and their user registration page.
PHP
1
star