# ClojureDart for Flutter: A Clojure Dialect with Dart Interop

> Tensegritics/ClojureDart targets Flutter and plain Dart applications with a Clojure dialect, generated Dart dependencies, and a development workflow centered on `clj -M:cljd`. It suits Clojure developers who want immutable data structures and functional code while using Flutter widgets and the Dart ecosystem.

**Tensegritics/ClojureDart** — Clojure dialect for Flutter and Dart

- Repository: https://github.com/Tensegritics/ClojureDart
- Stars: 1,651 · Forks: 119
- Language: Clojure
- License: not declared
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/tensegritics-clojuredart

## Why ClojureDart targets Flutter and Dart

ClojureDart addresses a specific gap between two ecosystems. Clojure developers often want the language's persistent data structures, namespaces, functional composition, and concise syntax, while Flutter developers need Dart libraries and Flutter's widget model. The project combines those concerns by compiling Clojure dialect source into code that participates in the Flutter and Dart ecosystems.

The intended audience is narrower than the general Clojure audience. It is for people building native mobile or desktop applications with Flutter, as well as command-line applications that target plain Dart. The README describes ClojureDart as production-ready and says applications are being built with it, but it also labels several language areas incomplete. That combination makes it more useful than a teaching-only dialect, while still requiring careful checks against the project's completeness notes.

The repository does not present ClojureDart as a replacement for Dart or Flutter. Dart remains the host ecosystem, and Flutter remains the UI toolkit. ClojureDart is the language layer that lets a project express application logic and Flutter elements in Clojure syntax.

## How the ClojureDart compilation path connects to Flutter

The visible workflow centers on a Clojure dependency configuration in `deps.edn`, source files with the `.cljd` extension, and a command that starts the Flutter watcher. The initial project declares a main namespace and a `:cljd/opts` map. In the example, `:kind` is `:flutter` and `:main` is `acme.main`.

A ClojureDart source file requires Dart and Flutter packages through vector-style require entries. The example imports `"package:flutter/material.dart"` as `m` and `cljd.flutter` as `f`. The source then defines `main`, creates a `MaterialApp`, and nests Flutter widgets such as `Scaffold`, `AppBar`, `Center`, `Text`, `ThemeData`, and `TextStyle`. This shows the central data and call path: ClojureDart definitions reference Flutter API symbols, while `f/run` launches the application through the ClojureDart Flutter integration.

The repository's tooling also checks Flutter SDK selection. For bare `flutter` commands, it verifies that `.fvm/flutter_sdk` resolves to the directory named by `.fvmrc`. If the link is missing or stale, it attempts repair with `fvm use <version> --skip-pub-get` from the project root. A matching SDK does not require the FVM executable. If synchronization fails, the command reports the failure. Without `.fvmrc`, SDK and PATH fallback applies, while explicit executable paths and Dart commands bypass this synchronization path.

This arrangement reduces version drift between ClojureDart tooling and Flutter, but it also means the local SDK setup matters. A developer using multiple Flutter channels may need to understand how `.fvmrc` is intended to interact with the installed SDK.

## Installing ClojureDart and running the first Flutter app

The documented prerequisites are Clojure and Flutter, both available on `PATH`. The quick start creates a directory, downloads the latest stable `deps.edn` template, replaces its visible `change.me` placeholder, and initializes the project. The downloaded file is documented as being pinned to the immutable tag and Git SHA of the latest release.

This command creates `hello`, downloads the template, changes the example namespace to `acme.main`, and prints the resulting dependency file. The `sed` substitution is specifically for the placeholder shown in the repository.

```bash
mkdir hello
cd hello
curl --fail --location https://github.com/Tensegritics/ClojureDart/releases/latest/download/deps.latest.edn --output deps.edn.tmp &&
mv deps.edn.tmp deps.edn &&
sed -i.bak -e 's/change\.me/acme.main/' deps.edn &&
rm deps.edn.bak &&
cat deps.edn
```

The next command creates the project structure using the `:cljd` alias.

```bash
clj -M:cljd init
```

Create the source directory and write the first Flutter application. The `:require` entries import Flutter material widgets and the ClojureDart Flutter support namespace. The generated file uses `acme.main`, matching the `deps.edn` substitution.

```bash
mkdir -p src/acme
cat << EOF > src/acme/main.cljd
(ns acme.main
  (:require ["package:flutter/material.dart" :as m]
            [cljd.flutter :as f]))

(defn main []
  (f/run
    (m/MaterialApp
      .title "Welcome to Flutter"
      .theme (m/ThemeData .primarySwatch m.Colors/pink))
    .home
    (m/Scaffold
      .appBar (m/AppBar
                .title (m/Text "Welcome to ClojureDart")))
      .body
      m/Center
      (m/Text "Let's get coding!"
         .style (m/TextStyle
                  .color m.Colors/red
                  .fontSize 32.0))))
EOF
```

Start the compile, watch, and run workflow with the following command. In most environments, the README says this spawns a desktop application.

```bash
clj -M:cljd flutter
```

If a specific target is required, run `flutter devices` first and pass its device identifier to the watcher. The examples use device identifiers such as `macos`, `chrome`, or a long iOS simulator identifier. The exact available devices depend on the local Flutter installation.

## Plain Dart projects, samples, and the REPL boundary

ClojureDart is not limited to graphical applications. The documentation also links to a Plain Dart QuickStart for command-line applications. That distinction matters because Flutter is one target, not a prerequisite embedded in every ClojureDart project. A developer can choose the Flutter setup for widget applications or consult the plain Dart setup for CLI-oriented code.

The `samples/` directory contains examples for Flutter widgets and language features, including counters, forms, navigation, gestures, animation, grids, data tables, isolates, FFI, and fetching data. To run one from the repository, the README documents cloning the repository, changing into a sample directory, initializing it, and starting the Flutter watcher.

```bash
git clone https://github.com/Tensegritics/ClojureDart.git
cd ClojureDart/samples/fab
clj -M:cljd init
clj -M:cljd flutter
```

The sample should run in Chrome or as a desktop application according to the available environment. For an exact target, the documentation uses `flutter devices` and passes the selected identifier with `-d`.

The REPL is explicitly marked beta. The README says that `clojure.repl`, including functions such as `doc` and `apropos`, has not been ported. This is a concrete limitation for development workflows that depend on those REPL facilities. Multimethods are also partial, with no hierarchy or type system support. Developers porting code that depends heavily on those features should inspect `doc/differences.md` and `doc/FAQ.md` before assuming JVM Clojure compatibility.

## Release pinning and the cost of staying current

ClojureDart uses releases as an explicit project boundary. The quick start template points at the latest stable release, and the README says that the dependency is pinned to the immutable tag and Git SHA of that release. The listed recent releases include `0.9.20261002`, `0.9.20260917`, and `0.9.20260822a`. The repository's last push was on 2026-10-14, so the visible maintenance signal is recent rather than an archived or stale repository.

For an existing project, the documented upgrade command is short:

```bash
clj -M:cljd upgrade
```

That convenience reduces the initial cost of adopting a newer ClojureDart release, but the project does not promise automatic compatibility across every language feature or Flutter API. The release pin also means an upgrade is a reproducible dependency change rather than an unconstrained floating dependency.

The repository identifies no license in the repository listing. That means an engineer cannot determine redistribution, modification, or integration obligations from the available repository facts. The license should be checked directly in the repository before shipping a product or distributing a modified version. The project does not document a separate commercial-use exception, support commitment, or migration policy in the available files.

## ClojureDart versus ordinary Flutter and Dart development

The main alternative is conventional Flutter development in Dart. That approach uses Dart source files and Flutter APIs directly, so there is no additional Clojure dialect or Clojure CLI initialization step. It is usually a simpler fit for teams whose existing expertise, debugging practices, and libraries are already centered on Dart.

ClojureDart adds a different working model. The project uses `deps.edn`, `.cljd` files, Clojure namespaces, and a tool invoked through `clj -M:cljd`. The source still imports and invokes Flutter classes, including `MaterialApp`, `Scaffold`, and `Text`, so the project does not remove Flutter's widget hierarchy. The benefit is the ability to express that hierarchy through Clojure syntax and use ClojureDart's language facilities alongside Dart packages.

The trade-off is visible in the completeness status. A team that needs a complete REPL or full multimethod behavior may find ordinary Dart, or possibly another Clojure-compatible environment with a different target, a better match. A team already invested in Clojure's data-oriented style may find ClojureDart more suitable than writing the entire Flutter layer in Dart. The decision is about language fit and supported feature coverage, not a claim that one ecosystem is universally better.

## Practical adoption checks for ClojureDart projects

The first adoption check should be the minimum language surface used by the application. The README identifies the REPL as beta and says `clojure.repl` has not been ported. It also describes multimethod support as partial and specifically excludes hierarchies and type system support. These are not minor version details because they affect interactive development and dispatch code directly.

The second check is Flutter SDK selection. The bare `flutter` command can trigger `.fvm` synchronization, while explicit executable paths and Dart commands do not. Teams with a prescribed Flutter channel should compare that policy with `.fvmrc` and the local SDK layout before adding the project to continuous integration. The README documents reporting failed synchronization, but it does not provide a separate CI configuration.

The third check is dependency provenance. Confirm the release tag and Git SHA in the downloaded `deps.edn` before committing it. Then review the unknown license status from the repository's actual license file. These checks are concrete and tied to files named by the project: `deps.edn`, `.fvmrc`, `.fvm/flutter_sdk`, `doc/differences.md`, and the repository license file.

## Conclusion

ClojureDart fits Clojure developers building Flutter interfaces or plain Dart applications who can accept a beta REPL and partial multimethod support. It is less suitable for teams that require fully portable Clojure features or a clearly identified repository license. Verify the pinned release SHA, selected Flutter SDK, and required language features before adoption.

## FAQ

### What is ClojureDart used for?

ClojureDart is a Clojure dialect for building native mobile and desktop applications with Flutter, as well as command-line applications that target plain Dart. It lets projects use Clojure syntax while calling Flutter and Dart libraries.

### How do I install and run a ClojureDart Flutter application?

Install Clojure and Flutter, download the latest stable `deps.edn` template, run `clj -M:cljd init`, create a `.cljd` source file, and start the workflow with `clj -M:cljd flutter`. A specific device can be selected with `flutter devices` and the `-d` option.

### Is the ClojureDart REPL production-ready?

The README labels the REPL beta and states that `clojure.repl`, including `doc` and `apropos`, has not been ported. Projects that depend on those REPL functions should verify the available development tooling before adoption.

## Sources

- [Issues](https://github.com/Tensegritics/ClojureDart/issues)
- [README](https://github.com/Tensegritics/ClojureDart/blob/main/README.md)
- [Releases](https://github.com/Tensegritics/ClojureDart/releases)
- [Tensegritics/ClojureDart on GitHub](https://github.com/Tensegritics/ClojureDart)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tensegritics-clojuredart
