How to start writing apps with ClojureDart

On April 16, ClojureDart was released, which means that Clojure lovers have the opportunity to write mobile, web and desktop applications on Flutter. Why use Clojure for this, however obvious, is beyond the scope of this article.

At the moment, the tools have not been polished yet, there is no repla (!) And auto-completions for the dart interop, but you can use it, and some clozhura goodies have already shown themselves (for example, nest– a macro that removes the nesting problem, and here is the code side by side).

In this article I want to tell you how to write your first flutter application in Clojure, what tools are convenient to use, where to look for answers to questions. An article for those who have at least minimal experience with Clojure.

And further, article will be maintained on github.

Tools

We put Flutter according to the official instructions and cli for Clojure. Extra won’t hurt clj-kondothrough which the macro warnings are currently working apha/widget.

Here’s what it looks like:

Choice code editor

At the moment, there is no interop support with dart, and you have to use hacks, which I will discuss in more detail below, but first a little about editors.

VSCode – quick start

I’m not a VSCode user, but as far as I know, this is the easiest way to get started. Install Calva, and everything will work by itself:

It does not hurt to put Flutter extension, more here.

Pros:

  • speed and ease of use;

  • unique plugin Joyridewhich allows you to write editor settings with repl on Clojure.

Intellij Idea – waiting for support

The result you can expect now:

There are autocompletions for Clojure (example with reduce- above), but there is no interop with a dart and you cannot disable these warnings.

Pros:

  • almost nothing needs to be set up and repaired;

  • support will come in the near future, and everything will work without your participation.

Minuses:

  • project opens extremely slowly (up to a minute on hello-world on my air, with vim I wait 125ms);

  • there is no way to configure the backlight and auto-completion (only turn it off);

To configure *.cljd support, you need to specify an extension for clojure:
preferences -> editor -> filetypes -> clojure file -> file patterns -> + -> *.cljd
Flutter support is configurable with plugins for Dart and Flutter, learn more here.
Warning support clj-kondo works with plugin clojure extras.

vim – customization

The same example with reduce-

Pros:

  • opening speed, the ability to open a dozen (hundred) projects simultaneously in milliseconds;

  • advanced customization;

  • repl itself integrates with the release of repla for ClojureDart;

  • the ability to write configs in Lisp (see below).

Minuses:

  • you need to learn how to use vim;

  • you need to spend time and configure everything yourself;

  • sometimes you need to fix it after updating plugins and vim itself.

There are several options on how to start vim for ClojureDart.

Nvim with lsp

We put plugin and 2 servers – for Clojure and Flutter (useful for flutter development teams + basic functionality for working with dart).
We write the setting for recognizing *.cljd as Clojure:

au! BufRead,BufNewFile *.cljd setfiletype clojure

I am currently using this configuration, and with the exception of the interop with dart, it has almost everything (refactoring, goto definition, find usages, auto-completion, documentation, namespace cleaning).

My config described on Fennel. A detailed analysis is beyond the scope of the article, but if you still want to use Lisp, then I would advise you to start with a plugin aniseed and dotfiles author. As an initial config, you can also take this projector ready assembly nyoom.

Vim/nvim with the VimIced plugin

You need to configure VimIced by instructions and connect clj-kondo as a linter (by this instructions). While there is no ClojureDart repla yet, most of the functionality will not be usable.

Fireplace

Didn’t check this pluginbut for sure it will work comparable to VimIced, if somewhere in Vim it is written that cljd -> this is a clojure.

au! BufRead,BufNewFile *.cljd setfiletype clojure

emacs

ClojureDart developers use Emacs, in clojure-mode already added *.cljd recognition. In my opinion, the pros and cons are comparable to vim, and the rest is an amateur.

Workflow

I recommend starting with hello worldto make sure everything works.

In the process of work, it is convenient to keep 3 windows open (at hand):

  1. Any file on dart (you can create a dart file in the lib/ directory) to immediately experiment, look at signatures, methods, fields, etc.

  2. Terminal to see logs and interact with the project.

  3. Emulator (in my experience, the android emulator is more stable and faster than the web version). The easiest way to set it up is to install AndroidStudio, and use Tools->DeviceManagement.

After running “watcher”:
сlj -M -m cljd.build flutter
We enter the loop of interactive development: we write the code, we save the file, we see the result, we write the code again…

If needed hot reloadsave the file.
If needed hot restartpress Enter in the terminal.
If all stops workingdelete the .clojuredart/ folder and restart “watcher”.

Using Libraries

As in a regular Flutter project, we add libraries to the pubspec.yaml file. Import by string, as in *.dart files in the format, as in regular Clojure:

(:require
    [clojure.string :refer [join]]
    ["package:graphql/client.dart" :as g])

The only way to use your own dart classes is to lay them out as a separate project and add them to pubspec.yaml. Perhaps support will be added in the future.

The approach to building a widget tree is different from Flutter on Dart

It almost always makes sense to create a function (as in examples:2 from the authors), rather than declaring a class with a deftype (as I did here:4). To create a StatefulWidget, it is most convenient to use a macro alpha/widget.

ClojureDart is different from Clojure

First of all, I recommend reading dock from the authors.

Another difference that you will definitely encounter is the lack of libraries that would translate data into the good old Clojurian PersistentHashMap. AT example(3) With GraphQL, I wrote a function to translate a Dart Map into a Closure PersistentHashMap.

Where to go with questions?

The community is on the edge clojurians, channel #clojuredart. Most of the questions have already been asked, and you can “google” them in the chat. The authors actively help, answer all questions. You can even upload the project to github and ask for advice/help in the chat. Someone will definitely look.

Useful Resources

  1. Official documentation by ClojureDart.

  2. Code examples from the authors.

  3. Sample Application with GraphQL and TEA architecture.

  4. Example writing custom widgets with deftype.

  5. Community in Slack – clojurianschannel #clojuredart

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *