m3tti / borkweb

🥇 babashka`s first fullstack clojure framework. That works with jvm clojure. ❗Batteries included❗
https://borkweb.org
MIT License
59 stars 1 forks source link

Borkweb

Borkweb: A Simpler Approach to modern Web Development

Borkweb is an effort to create a full-stack Clojure framework that is simple, minimal and traditional. I believe that the complexity and overhead of modern web development frameworks have made it difficult for developers to focus on building great applications. Our goal is to provide a tool that allows developers to work efficiently and effectively, without getting bogged down in unnecessary configurations and integrations.

Why Borkweb?

I didn't create Borkweb as a proof-of-concept or a side project. I created it because I needed it. I was building real applications and was frustrated with the complexity and overhead of existing frameworks. I wanted a tool that would allow me to focus on building great applications, without getting bogged down in unnecessary configurations and integrations. Borkweb is the result of my efforts, and I've been using it in production for my own applications.

Core Values

Full-Stack Clojure

Borkweb is a full-stack framework that uses Clojure on all ends. This means you can write your frontend code in ClojureScript using Squint, your CSS in Gaka, and your backend code in Babashka. Everything backed by a traditional SQL database.

No Overhead

One of the key benefits of Borkweb is that it requires minimal overhead. You don't need to worry about setting up a complex build pipeline or managing a multitude of dependencies. With Babashka, you can simply write your code and run it. No need for Node.js, no need for a separate frontend build process. Just write, run, and deploy.

Contributing

Borkweb is an open-source project, and I welcome contributions from anyone who is interested in helping to make it better. If you have an idea for a feature or a bug fix, please open an issue or submit a pull request.

Dependencies

Frontend third party

Get started

borkweb only needs babashka to get started. To run the template just do a bb -m core and you are good to go. Make sure you have a postgres database at hand find documentation for that down below. If you need a postgres db there is a docker-compose.yaml there. Start it up as always docker-compose up -d.

Everything starts with a Database

The initialization of the database is currently done with an init.sql which you can trigger either with bb -m database.core/initialize-db. Or by a tool of your choice. The database connection parameters are available in database/core.cljs just replace as you like. Currently postgres is used for the database backend but you can basically use any sql database that you like and which is supported by your runtime. If you want to use a diffrent db like datalevin you'll lose the registration and login functionality and have to adjust some stuff.

Routing

Routing can be done in the routes.clj file found in the base folder. There are already premade helper functions to generate routes in a compojuresque style.

(route path method (fn [req] body))
(get path (fn [req] body))
(post path (fn [req] body))

CLJS

borkweb provides already everything you need to get started with cljs no need for any bundler or anything else. Get to resources/cljs drop your cljs code that is squint compliant and you are good to go. borkweb allready includes some examples for preact and preact web components. There are helper functions to compile cljs code in your hiccup templates. You can find them in view/components.clj cljs-module to generate js module code and cljs-resource to create plain javascript code. there is even ->js which can be used to trigger squint/cljs code inline.

;; resources/cljs/counter.cljs
(require '["https://esm.sh/preact@10.19.2" :as react])
(require '["https://esm.sh/preact@10.19.2/hooks" :as hooks])

(defn Counter []
  (let [[counter setCounter] (hooks/useState 0)]
    #jsx [:<>
          [:div "Counter " counter]
          [:div {:role "group" :class "btn-group"}
           [:button {:class "btn btn-primary" :onClick #(setCounter (inc counter))} "+"]
           [:button {:class "btn btn-primary" :onClick #(setCounter (dec counter))} "-"]]]))

(defonce el (js/document.getElementById "cljs"))

(react/render #jsx [Counter] el)
;; view/some_page.clj
(require '[view.components :as c])

(defn some-page [req]
  [:h1 "My fancy component page"]
  [:div#cljs]
  ;; just use the filename without cljs. the function will search in the resource/cljs folder.
  (c/cljs-module "counter"))

Roadmap

Articles