Hi, be sure to also check out the book Web Development with Clojure.
To answer your original question, Clojure is just fine for very basic projects. I use ClojureScript for my public websites and they are very simple.
Only a handful of functions are needed to get going and the REPL will give plenty of instant feedback on if your code works. You donāt need to write highly optimal and idiomatic code to get a working system, this will come with time.
Use a Clojure aware tool that works best for you
https://practicalli.github.io/clojure/clojure-editors/
Luminous has captured a lot of good ideas for building a server side and full stack apps. Try and use the simplest set of options and set aside some time to read the docs, there is a bit of a learning curve.
Ask the community for help, itās a great source of advice
http://practical.li/blog/posts/cloure-community-getting-help/
Hosting is a bit costly for jvm web apps. But if thatās not an issue for you, then I think Clojure is a good choice for apps of any scope and size.
Iām curious, who/what do you use for hosting?
For really small web-apps babashka + http-kit, which is currently being considered, might be an option:
If we include an opinionated set of web libraries (compojure or reitit, hiccup, jdbc.next + postgres support), this may work for some category of apps that donāt really need high performance and can run with a really low memory footprint compared to the JVM. Consider discussing in the issue if you like this idea.
Alternatively you can compose your web-app from GraalVM compatible components and compile your own native binary. Native-image binaries accept JVM flags like -Xmx30m
.
Not the person you were asking, but Iāve been happy with digital ocean. You can run a clojure app on a $5/month droplet.
Thanks Jacob, Iāve used DO for python web apps and been happy with them.
About a year ago for my Clojure web apps I started using Jelastic (sort of like Heroku for java apps, but much cheaper) and found that it ended up being free for hobby projects with low RAM usage. I wrote a blog post about it a while back and now my ears prick up when ever I hear people talking about Clojure web app hosting.
P.S. Complete aside, but I enjoyed reading your blog post which I stumbled upon a while back about your experience of being home-schooled. My wife and I home-schooled our son for 4 years and it was a wonderful experience.
Seems like mirhosting.com is flagged by my ISP netCaffe as being a malicious website, and Google also flags it as unsafe
For Clojure, no job is too small or large.
Large hobby projects are more fun if youāve already tackled small
hobby projects!
You will eventually settle on a bunch of tools. The parts fit
together pretty well in Clojure. You wonāt need a framework to do it
for you.
If you want to stay on a very (very) well-paved path, the first major
decision is Ring or Pedestal for the server. Canāt go wrong with
either. Thereās probably more advice floating around the internet
about Ring. Then just hop into a REPL and have at it.
After your first project with Ring, you can do anything. By the way,
do not be put off by scantiness of docs, or anyway, not by that alone.
People who come from, say, Python remember appreciating
the 1800-page Django manual, because Django is easy.
But Clojure is simple. A whole different ballgame.
Thank you Phil! Yes, itās very useful to hear the opinions here, how to approach thinks in Clojureverse and which libraries are commonly used for which tasks.
I am also experimenting with LFE, which is a full-blown mature lisp on top of BEAM virtual machine. Kinda best of Clojure combined with best of Erlang, which is exactly what you want for web projects.
Thatās not exactly confidence inspiring, is it? Whatās the Google tool that gave a warning about it? I just checked mirhosting.com on https://transparencyreport.google.com/ and there werenāt any warnings.
Clojure wonāt be significantly harder to build a web application on then say, ruby.
However, I know several professional clojure devs that use wordpress. I donāt know the trade off, but the implication is that it might we wiser to start with something much more ridged (less options but more defaults) if you can fit your problem into it.
WordPress just hides a lot of problems. Iāve seen pretty complex apps built quickly using plugins, and the performance seems great. But behind the scenes the plugins are doing things like LIKE = ā%x%ā, and youāll run into serious scaling issues at 10-100 users. Security seems okay if youāre small and always stay updated, but if you get big enough to be targeted then you need to be shelling out $99/mo for Wordfence. I constantly get breakage due to plugin updates, usually due to minor releases or supposedly ābugfixā releases, but with no automated tests or anything to discover that breakage. Itās basically the polar opposite of the Clojure ecosystem, and itās been very educational as to why Clojure does things the way it does. E.g., you really appreciate Clojureās dependency system and always using exact versions when your site dies because you have two plugins using the exact same version of the AWS SDK but with slightly different transitive dependencies on guzzle-http, only differing in the last digit. My solution was to just remove the AWS SDK dependency from my plugin, since it builds on the other and I donāt think one can do any better in WordPress.
Due to all of these issues, Iāve been using WP2Static as much as possible (and am now a committer). It doesnāt work for every site, but where it does it fixes most of the performance and security issues and allows you to get off the update->break hamster wheel. Most of my client sites use this with a Clojure server handling logins and controlling access to the site via ngx_http_auth_request_module. If the site works properly, you can just leave it alone ā no updates required. You can achieve the same thing by running the site locally in Docker or such, with no internet exposure.
For Google itās just the bad SSL warning that Chrome gives you: Untrusted connection.
And maybe thatās also why this McCaffee screener from my ISP triggers as well.
Hum, it seems itās blacklisted by McCaffee and runs an outdated version of PHP. Thatās all I could find. Donāt know why.
weāre slightly off-topic here, but I do remember one project that had a MVP on Wordpress and they hosted it on WP Engine ā those folks at WP Engine were absolutely killing it!!
World class support, responses in no time, helping with the craziest quirks one can imagine, and squeezing absolute maximum out of Wordpress. I was amazed whatās even possible on Wordpress.
Thatās how I got to Clojure actually. We had high concurrency situation, WP was stretched to limits (although WP Engine bought us a lot of time) and we were looking for solutions. Found Elixir and Clojure back then
Hi!
Iām a bit late to the party, but as far as your intial puzzle regarding size and scope of a Clojure Web App is concerned, Iāve been in pretty much the same predicament about 10 months ago when I was still unsure if should set out to learn Web Development using Clojure or a more āstandardā language. Most of all I was unsure if Iād be able to deploy my small time beginnerās apps to a fitting environment. For now Iāve found the Macchiato framework to occupy a sweet spot in that regard.
By now I consider Macchiato to be fairly accessible as long as you know the underlying technology (which I didnāt when starting out). It uses Node.js instead of the JVM for the server side and I now have several instances of it running on a single shared hosting plan ā so costs and entry barriers are minimal.
The handling is modeled on Ring and the whole experience seems to be very similar to Luminus (āseemsā because my own experience with Luminus is still limited). Sofar Iāve done a couple of small time projects with it, like classic dynamic Homepages (the kind you do when first learning PHP) ā and it does the job pretty well. Incidentally Iām currently working on a hotel booking site with parts of the frontend done with Reagent.
In oder to facilitate CRUD Iāve found DirectusĀ® to be a really versatile headless CMS with perfect transparency towards the underlying SQL. It offers a very nice API for which Iāve written some wrappers, so I can now query the DB from the frontend and backend using the same Clojurescript code.
There are obvious drawbacks, of course, with Node.js being much less rich as a platform and a good bunch of Clojurescript libraries not assuming it as a runtime (The inability to use hickory to parse HTML into Hiccup has been a pain for quite some time).
The biggest problem for me as a total beginner in (Web) development was the documentation, wich is also rather lightweight. Not many tutorials out there (only now there is one). If you have never heard the terms āroutingā and āhandlingā (I take it you have) youāll have a much harder time figuring that out than if you were learning, say, Node with Express. Reading Sotnikovās book on Luminus earlier definitely would have helped me. However, Clojure being Clojure, I was ultimately able to āreverse engineerā Macchiato step by step just following the various function call chains towards a sufficient understanding (I guess Rails would have been more opaque in that regard).
TL;DR, maybe, for small projects, consider Macchiato as a lightweight alternative to the Luminus stack. Maybe combine with a CMS like Directus to facilitate much of the CRUD work.
Cheers!
BTW: Hiccups, the Clojurescript version of Hiccup is safe insofar as it escapes dangerous symbols.
Iāve found DirectusĀ® to be a really versatile headless CMS with perfect transparency towards the underlying SQL. It offers a very nice API for which Iāve written some wrappers, so I can now query the DB from the frontend and backend using the same Clojurescript code.
Can you tell us more about what you use it for? How do you manage security if you query the DB from the frontend?
Thanks for asking! This piece has gotten bit long, so I considered opening a new thread for it but I feel itās actually on topic, so unless any of the moderators feel differently about this, hereās how I use Directus for small Clojurescript websites:
API Security has been a non-issue so far
The Directus API does offer authentication via access tokens. However, being quite new to web development Iāve been pretty paranoid about security; so up until recently I have successfully avoided the need to actually use the auth mechanism: Most of my data is either public for reading or completely off limits via the API. Directus offers fine grained control over the permissions for reading/writing tables and fields ā publicly, via authentication (or not at all).
Using only partially public access is completely sufficient as long as I only cater to a closed user base, i.e. I add the content creators manually to Directus and provide them with rights accordingly. So, for now, I ultimately rely on Directusā account and permission management for security.
Simple Example Project
Directus allows non-technical users to edit a SQL Database in many different ways. As an example you can look at the very first website Iāve made, for a musician. Among other things she needed the ability to manage programs, performers and concerts (connecting them to one another). The underlying SQL looks something like this:
Performers:
| name | id |
|---------------+----|
| Solo | 1 |
| Trio SƩrƩnade | 2 |
| Duo AdamƩ | 3 |
Programs:
| title | composer | id |
|----------------+----------------+----|
| Trio Piazzolla | Piazzolla | 1 |
| Hallelujah | Leonhard Cohen | 2 |
| preludes | Chopin | 3 |
Concerts:
| date | program_id | perfomer_id |
|------------+------------+-------------|
| 12.12.2020 | 2 | 3 |
| 14.01.2021 | 1 | 2 |
Directus offers several Frontend Interfaces for the various SQL relations which are created in one go with the tables and fields. The Interface for the O2Ms above looks like this (German, sorry):
To the left are the various collections (ā SQL tables). When adding a new concert item (ā SQL row) I get to fill relational fields via dropdowns (or other means). This Interface works very well for non-technical users but is still totally transparent as to the underlying SQL (unlike WordPress @John_Shaffer). Directus offers several interfaces per SQL relation ā one of them for multilingual content, which makes internationalization quite easy.
Most of these Interfaces are content-agnostic. In case none of the built-in interfaces make sense of the SQL, one can either write a custom one (in Angular ) or make something separate that works on the Database directly (or via API) ā Directus wonāt mind and just reflect any changes in case it is hooked up to the tables concerned.
Clojurescript integration (without overkill)
Thereās not even much to be said here. Directus automatically provides API endpoints for every public collection. So anyone can query the concerts collection with e.g. ā¦/items/concerts?fields=id,date,performer.name,performer.id
(I use some wrapper to generate these queries from nested Clojure vectors). In Clojurescript that gives me
[{:id 79
:date "2021-01-14"
:performer {:id: 2
:name: "Trio SƩrƩnade"}}
{:id 139
:date "2019-10-26"
:performer {:id 2
:name "Duo AdamƩ"}}]
I have a generic handler that asynchronously fetches multiple collections and then forwards them to a page formatter that processes them first to hiccup and then to HTML. Also I have written a couple of Directus-specific transformers, e.g. for multilingual collections etc. Maybe eventually, when I feel more confident about what Iām doing, Iāll make these into a small library or shadow-cljs-template.
TL;DR Without Directus Iād probably be deep down the WordPress rabbit hole by now. I give it to my clients to manage multilingual dynamic websites that are rather small, but highly customized ā with the occasional Reagent app for advanced interactivity.
Disclaimer: If any of the above sounds like Iām promoting Directus itās only because it really helped me get started with Web Development and allowed me to use a Lisp in the processā¦ also the maintainers around Ben Hanyes have helped me out on several occasionsā¦ so they deserve some good rep. I have no stock in them or anything
Thanks for explaining how it works. Sounds like your client edits their site their own account on the Directus website, and then their website pulls all the data it needs to display from the Directus API. Nice looking website you made fo the musician
For other types of apps (i.e. aside from content sites) it seems like you could also use Directus as a sort of replacement for a Django-style admin panel, in that it gives you a GUI view of your database?
How did you come to choose Directus out of all the other options for headless CMSs? I just had quick google and it seems like there are a huge range of options.
So far Iāve only used self-hosted instances of Directus. My clients have their own shared hosting plans where Iām running all three pieces: The Directus instance, the underlying SQL Database and the Clojurescript app (Macchiato). I havenāt used the Directus Cloud so far. It might be faster for frontend-querying, but for server-side rendering I expect self-hosting to have a performance edge. Also that way I can query the DB directly when I feel the need.
This is exactly what Iāve been doing (for the most part) ā probably not the first thing youād choose Clojure(script) for, but a good way to get some first real world experience. My approach still makes for a good amount of clojure code, so itās only cost-effective for stuff you cannot just throw a Wordpress plugin at.
āDatabase GUIā pretty much sums it up, so I assume you can use it for anything where an easy way to edit SQL comes in handy.
Iāve never used Django, so canāt really compare the two. Looking at what I could dig up just now it seems that Django offers more fine-grained control over the details of the admin panel ā at the expense of setup-easiness (maybe not simplicity ). Setting up Directus, once installed, is mostly a point-and-click adventure: The SQL relations are created together with the Interfaces. One should know how relational databases work and have an idea of how one wants to query the API, but thatās pretty much it. I have yet to write a single line of PHP or Angular for any Directus-Project.
Iāll try to make this short since ultimately the choice was more or less arbitrary. My main constraints at the time were
- Self-hosted
- PHP-based (I was unsure if Iād find a shared hosting space offering anything else in Germany)
- SQL-based
- WYSIWYG HTML editor for my clients.
- Integrated Thumbnailer
A nice guy on on StackExchange pointed me at http://cmsmatrix.org/, where I pretty much just stumbled across Directus. After a quick chat with Ben Haynes I was optimistic about getting it to work with a Reagent App, which it did just fine (only later did I find out about Macchiato and switched to server-side rendering).
Maybe some other CMS might have served my purposes just as well; in my case Directus happened to make the use of clojurescript viable for the small content sites I had to start with in order to get a feel for the matter.