Clojure
made by https://0x3d.site
GitHub - seancorfield/honeysql: Turn Clojure data structures into SQLTurn Clojure data structures into SQL. Contribute to seancorfield/honeysql development by creating an account on GitHub.
Visit Site
GitHub - seancorfield/honeysql: Turn Clojure data structures into SQL
Honey SQL
SQL as Clojure data structures. Build queries programmatically -- even at runtime -- without having to bash strings together.
Build
This project follows the version scheme MAJOR.MINOR.COMMITS where MAJOR and MINOR provide some relative indication of the size of the change, but do not follow semantic versioning. In general, all changes endeavor to be non-breaking (by moving to new names rather than by breaking existing names). COMMITS is an ever-increasing counter of commits since the beginning of this repository.
Note: every commit to the develop branch runs CI (GitHub Actions) and successful runs push a MAJOR.MINOR.9999-SNAPSHOT build to Clojars so the very latest version of HoneySQL is always available either via that snapshot on Clojars or via a git dependency on the latest SHA.
HoneySQL 2.x requires Clojure 1.9 or later. It also supports recent versions of ClojureScript and Babashka.
Compared to the legacy 1.x version, HoneySQL 2.x provides a streamlined codebase and a simpler method for extending the DSL. It also supports SQL dialects out-of-the-box and will be extended to support vendor-specific language features over time (unlike 1.x).
Note: you can use 1.x and 2.x side-by-side as they use different group IDs and different namespaces. This allows for a piecemeal migration. See this summary of differences between 1.x and 2.x if you are migrating from 1.x!
Try HoneySQL Online!
John Shaffer has created this awesome
HoneySQL web app, written in ClojureScript,
so you can experiment with HoneySQL in a browser, including setting different
options so you can generate pretty SQL with inline values (via :inline true
)
for copying and pasting directly into your SQL tool of choice!
Note on code samples
Sample code in this documentation is verified via lread/test-doc-blocks.
Some of these samples show pretty-printed SQL: HoneySQL 2.x supports :pretty true
which inserts newlines between clauses in the generated SQL strings.
Usage
This section includes a number of usage examples but does not dive deep into the way the data structure acts as a DSL that can specify SQL statements (as hash maps) and SQL expressions and function calls (as vectors). It is recommended that you read the Getting Started section of the documentation before trying to use HoneySQL to build your own queries!
From Clojure:
(refer-clojure :exclude '[distinct filter for group-by into partition-by set update])
(require '[honey.sql :as sql]
;; CAUTION: this overwrites several clojure.core fns:
;;
;; distinct, filter, for, group-by, into, partition-by, set, and update
;;
;; you should generally only refer in the specific
;; helpers that you want to use!
'[honey.sql.helpers :refer :all :as h]
;; so we can still get at clojure.core functions:
'[clojure.core :as c])
From ClojureScript, we don't have :refer :all
. If we want to use :refer
, we have no choice but to be specific:
(refer-clojure :exclude '[filter for group-by into partition-by set update])
(require '[honey.sql :as sql]
'[honey.sql.helpers :refer [select select-distinct from
join left-join right-join
where for group-by having union
order-by limit offset values columns
update insert-into set composite
delete delete-from truncate] :as h]
'[clojure.core :as c])
Everything is built on top of maps representing SQL queries:
(def sqlmap {:select [:a :b :c]
:from [:foo]
:where [:= :foo.a "baz"]})
Column names can be provided as keywords or symbols (but not strings -- HoneySQL treats strings as values that should be lifted out of the SQL as parameters).
format
format
turns maps into next.jdbc
-compatible (and clojure.java.jdbc
-compatible), parameterized SQL:
(sql/format sqlmap)
=> ["SELECT a, b, c FROM foo WHERE foo.a = ?" "baz"]
;; sqlmap as symbols instead of keywords:
(-> '{select (a, b, c) from (foo) where (= foo.a "baz")}
(sql/format))
=> ["SELECT a, b, c FROM foo WHERE foo.a = ?" "baz"]
HoneySQL is a relatively "pure" library, it does not manage your JDBC connection
or run queries for you, it simply generates SQL strings. You can then pass them
to a JDBC library, such as next.jdbc
:
(jdbc/execute! conn (sql/format sqlmap))
Note: you'll need to add your preferred JDBC library as a dependency in your project -- HoneySQL deliberately does not make that choice for you.
If you want to format the query as a string with no parameters (e.g. to use the SQL statement in a SQL console), pass :inline true
as an option to sql/format
:
(sql/format sqlmap {:inline true})
=> ["SELECT a, b, c FROM foo WHERE foo.a = 'baz'"]
As seen above, the default parameterization uses positional parameters (?
) with the order of values in the generated vector matching the order of those placeholders in the SQL. As of 2.4.962, you can specified :numbered true
as an option to produce numbered parameters ($1
, $2
, etc):
(sql/format sqlmap {:numbered true})
=> ["SELECT a, b, c FROM foo WHERE foo.a = $1" "baz"]
Namespace-qualified keywords (and symbols) are generally treated as table-qualified columns: :foo/bar
becomes foo.bar
, except in contexts where that would be illegal (such as the list of columns in an INSERT
statement). This approach is likely to be more compatible with code that uses libraries like next.jdbc
and seql
, as well as being more convenient in a world of namespace-qualified keywords, following the example of clojure.spec
etc.
(def q-sqlmap {:select [:foo/a :foo/b :foo/c]
:from [:foo]
:where [:= :foo/a "baz"]})
(sql/format q-sqlmap)
=> ["SELECT foo.a, foo.b, foo.c FROM foo WHERE foo.a = ?" "baz"]
;; this also works with symbols instead of keywords:
(-> '{select (foo/a, foo/b, foo/c)
from (foo)
where (= foo/a "baz")}
(sql/format))
=> ["SELECT foo.a, foo.b, foo.c FROM foo WHERE foo.a = ?" "baz"]
As of 2.6.1126, there is a helper macro you can use with quoted symbolic queries (that are purely literal, not programmatically constructed) to provide "escape hatches" for certain symbols that you want to be treated as locally bound symbols (and, hence, their values):
;; quoted symbolic query with local substitution:
(let [search-value "baz"]
(sql/formatv [search-value]
'{select (foo/a, foo/b, foo/c)
from (foo)
where (= foo/a search-value)}))
=> ["SELECT foo.a, foo.b, foo.c FROM foo WHERE foo.a = ?" "baz"]
Note: this is a Clojure-only feature and is not available in ClojureScript, and it is intended for literal, inline symbolic queries only, not for programmatically constructed queries (where you would be able to substitute the values directly, as you build the query).
Documentation for the entire data DSL can be found in the Clause Reference, the Operator Reference, and the Special Syntax reference.
Vanilla SQL clause helpers
For every single SQL clause supported by HoneySQL (as keywords or symbols
in the data structure that is the DSL), there is also a corresponding
function in the honey.sql.helpers
namespace:
(-> (select :a :b :c)
(from :foo)
(where [:= :foo.a "baz"]))
=> {:select [:a :b :c] :from [:foo] :where [:= :foo.a "baz"]}
In general, (helper :foo expr)
will produce {:helper [:foo expr]}
(with a few exceptions -- see the docstring of the helper function
for details).
Order doesn't matter (for independent clauses):
(= (-> (select :*) (from :foo))
(-> (from :foo) (select :*)))
=> true
When using the vanilla helper functions, repeated clauses will be merged into existing clauses, in the natural evaluation order (where that makes sense):
(-> sqlmap (select :d))
=> {:from [:foo], :where [:= :foo.a "baz"], :select [:a :b :c :d]}
If you want to replace a clause, you can dissoc
the existing clause first, since this is all data:
(-> sqlmap
(dissoc :select)
(select :*)
(where [:> :b 10])
sql/format)
=> ["SELECT * FROM foo WHERE (foo.a = ?) AND (b > ?)" "baz" 10]
Note: the helpers always produce keywords so you can rely on
dissoc
with the desired keyword to remove. If you are building the data DSL "manually" and using symbols instead of keywords, you'll need todissoc
the symbol form instead.
where
will combine multiple clauses together using SQL's AND
:
(-> (select :*)
(from :foo)
(where [:= :a 1] [:< :b 100])
sql/format)
=> ["SELECT * FROM foo WHERE (a = ?) AND (b < ?)" 1 100]
The power of this approach comes from the abiliity to programmatically and conditionally build up queries:
(defn fetch-user [& {:keys [id name]}]
(-> (select :*)
(from :users)
(cond->
id (where [:= :id id])
name (where [:= :name name]))
sql/format))
You can call fetch-user
with either :id
or :name
or both and get back
a query with the appropriate WHERE
clause, since the helpers will merge the
conditions into the query DSL.
Column and table names may be aliased by using a vector pair of the original name and the desired alias:
(-> (select :a [:b :bar] :c [:d :x])
(from [:foo :quux])
(where [:= :quux.a 1] [:< :bar 100])
sql/format)
=> ["SELECT a, b AS bar, c, d AS x FROM foo AS quux WHERE (quux.a = ?) AND (bar < ?)" 1 100]
or conditionally:
(-> (select :a [:b :bar])
(cond->
need-c (select :c)
x-val (select [:d :x]))
(from [:foo :quux])
(where [:= :quux.a 1] [:< :bar 100])
(cond->
x-val (where [:> :x x-val]))
sql/format)
In particular, note that (select [:a :b])
means SELECT a AS b
rather than
SELECT a, b
-- helpers like select
are generally variadic and do not take
a collection of column names.
The examples in this README use a mixture of data structures and the helper
functions interchangably. For any example using the helpers, you could evaluate
it (without the call to sql/format
) to see what the equivalent data structure
would be.
Documentation for all the helpers can be found in the
honey.sql.helpers
API reference.
Inserts
Inserts are supported in two patterns. In the first pattern, you must explicitly specify the columns to insert, then provide a collection of rows, each a collection of column values:
(-> (insert-into :properties)
(columns :name :surname :age)
(values
[["Jon" "Smith" 34]
["Andrew" "Cooper" 12]
["Jane" "Daniels" 56]])
(sql/format {:pretty true}))
=> ["
INSERT INTO properties (name, surname, age)
VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?)
"
"Jon" "Smith" 34 "Andrew" "Cooper" 12 "Jane" "Daniels" 56]
;; or as pure data DSL:
(-> {:insert-into [:properties]
:columns [:name :surname :age]
:values [["Jon" "Smith" 34]
["Andrew" "Cooper" 12]
["Jane" "Daniels" 56]]}
(sql/format {:pretty true}))
=> ["
INSERT INTO properties (name, surname, age)
VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?)
"
"Jon" "Smith" 34 "Andrew" "Cooper" 12 "Jane" "Daniels" 56]
If the rows are of unequal lengths, they will be padded with NULL
values to make them consistent.
Alternately, you can simply specify the values as maps:
(-> (insert-into :properties)
(values [{:name "John" :surname "Smith" :age 34}
{:name "Andrew" :surname "Cooper" :age 12}
{:name "Jane" :surname "Daniels" :age 56}])
(sql/format {:pretty true}))
=> ["
INSERT INTO properties (name, surname, age)
VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?)
"
"John" "Smith" 34
"Andrew" "Cooper" 12
"Jane" "Daniels" 56]
;; or as pure data DSL:
(-> {:insert-into [:properties]
:values [{:name "John", :surname "Smith", :age 34}
{:name "Andrew", :surname "Cooper", :age 12}
{:name "Jane", :surname "Daniels", :age 56}]}
(sql/format {:pretty true}))
=> ["
INSERT INTO properties (name, surname, age)
VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?)
"
"John" "Smith" 34
"Andrew" "Cooper" 12
"Jane" "Daniels" 56]
The set of columns used in the insert will be the union of all column names from all
the hash maps: columns that are missing from any rows will have NULL
as their value
unless you specify those columns in the :values-default-columns
option, which takes
a set of column names that should get the value DEFAULT
instead of NULL
:
(-> (insert-into :properties)
(values [{:name "John" :surname "Smith" :age 34}
{:name "Andrew" :age 12}
{:name "Jane" :surname "Daniels"}])
(sql/format {:pretty true}))
=> ["
INSERT INTO properties (name, surname, age)
VALUES (?, ?, ?), (?, NULL, ?), (?, ?, NULL)
"
"John" "Smith" 34
"Andrew" 12
"Jane" "Daniels"]
(-> (insert-into :properties)
(values [{:name "John" :surname "Smith" :age 34}
{:name "Andrew" :age 12}
{:name "Jane" :surname "Daniels"}])
(sql/format {:pretty true :values-default-columns #{:age}}))
=> ["
INSERT INTO properties (name, surname, age)
VALUES (?, ?, ?), (?, NULL, ?), (?, ?, DEFAULT)
"
"John" "Smith" 34
"Andrew" 12
"Jane" "Daniels"]
Nested subqueries
The column values do not have to be literals, they can be nested queries:
(let [user-id 12345
role-name "user"]
(-> (insert-into :user_profile_to_role)
(values [{:user_profile_id user-id
:role_id (-> (select :id)
(from :role)
(where [:= :name role-name]))}])
(sql/format {:pretty true})))
=> ["
INSERT INTO user_profile_to_role (user_profile_id, role_id)
VALUES (?, (SELECT id FROM role WHERE name = ?))
"
12345
"user"]
;; or as pure data DSL:
(let [user-id 12345
role-name "user"]
(-> {:insert-into [:user_profile_to_role]
:values [{:user_profile_id 12345,
:role_id {:select [:id],
:from [:role],
:where [:= :name "user"]}}]}
(sql/format {:pretty true})))
=> ["
INSERT INTO user_profile_to_role (user_profile_id, role_id)
VALUES (?, (SELECT id FROM role WHERE name = ?))
"
12345
"user"]
(-> (select :*)
(from :foo)
(where [:in :foo.a (-> (select :a) (from :bar))])
(sql/format))
=> ["SELECT * FROM foo WHERE foo.a IN (SELECT a FROM bar)"]
;; or as pure data DSL:
(-> {:select [:*],
:from [:foo],
:where [:in :foo.a {:select [:a], :from [:bar]}]}
(sql/format))
=> ["SELECT * FROM foo WHERE foo.a IN (SELECT a FROM bar)"]
Because values can be nested queries -- and also because values can be function calls -- whenever you are working with values that are, themselves, structured data, you will need to tell HoneySQL not to interpret that structured data as part of the DSL. This especially affects using JSON values with HoneySQL (e.g., targeting PostgreSQL). There are two possible approaches:
- Use named parameters instead of having the values directly in the DSL structure (see
:param
under Miscellaneous below), or - Use
[:lift ..]
wrapped around any structured values which tells HoneySQL not to interpret the vector or hash map value as a DSL.
Composite types
Composite types are supported:
(-> (insert-into :comp_table)
(columns :name :comp_column)
(values
[["small" (composite 1 "inch")]
["large" (composite 10 "feet")]])
(sql/format {:pretty true}))
=> ["
INSERT INTO comp_table (name, comp_column)
VALUES (?, (?, ?)), (?, (?, ?))
"
"small" 1 "inch" "large" 10 "feet"]
;; with numbered parameters:
(-> (insert-into :comp_table)
(columns :name :comp_column)
(values
[["small" (composite 1 "inch")]
["large" (composite 10 "feet")]])
(sql/format {:pretty true :numbered true}))
=> ["
INSERT INTO comp_table (name, comp_column)
VALUES ($1, ($2, $3)), ($4, ($5, $6))
"
"small" 1 "inch" "large" 10 "feet"]
;; or as pure data DSL:
(-> {:insert-into [:comp_table],
:columns [:name :comp_column],
:values [["small" [:composite 1 "inch"]]
["large" [:composite 10 "feet"]]]}
(sql/format {:pretty true}))
=> ["
INSERT INTO comp_table (name, comp_column)
VALUES (?, (?, ?)), (?, (?, ?))
"
"small" 1 "inch" "large" 10 "feet"]
Updates
Updates are possible too:
(-> (update :films)
(set {:kind "dramatic"
:watched [:+ :watched 1]})
(where [:= :kind "drama"])
(sql/format {:pretty true}))
=> ["
UPDATE films
SET kind = ?, watched = watched + ?
WHERE kind = ?
"
"dramatic"
1
"drama"]
;; or as pure data DSL:
(-> {:update :films,
:set {:kind "dramatic", :watched [:+ :watched 1]},
:where [:= :kind "drama"]}
(sql/format {:pretty true}))
=> ["
UPDATE films
SET kind = ?, watched = watched + ?
WHERE kind = ?
"
"dramatic"
1
"drama"]
If you are trying to build a compound update statement (with from
or join
),
be aware that different databases have slightly different syntax in terms of
where SET
should appear. The default above is to put SET
before FROM
which
is how PostgreSQL (and other ANSI-SQL dialects work). If you are using MySQL,
you will need to select the :mysql
dialect in order to put the SET
after
any JOIN
clause.
Deletes
Deletes look as you would expect:
(-> (delete-from :films)
(where [:<> :kind "musical"])
(sql/format))
=> ["DELETE FROM films WHERE kind <> ?" "musical"]
;; or as pure data DSL:
(-> {:delete-from [:films],
:where [:<> :kind "musical"]}
(sql/format))
=> ["DELETE FROM films WHERE kind <> ?" "musical"]
If your database supports it, you can also delete from multiple tables:
(-> (delete [:films :directors])
(from :films)
(join :directors [:= :films.director_id :directors.id])
(where [:<> :kind "musical"])
(sql/format {:pretty true}))
=> ["
DELETE films, directors
FROM films
INNER JOIN directors ON films.director_id = directors.id
WHERE kind <> ?
"
"musical"]
;; or pure data DSL:
(-> {:delete [:films :directors],
:from [:films],
:join [:directors [:= :films.director_id :directors.id]],
:where [:<> :kind "musical"]}
(sql/format {:pretty true}))
=> ["
DELETE films, directors
FROM films
INNER JOIN directors ON films.director_id = directors.id
WHERE kind <> ?
"
"musical"]
If you want to delete everything from a table, you can use truncate
:
(-> (truncate :films)
(sql/format))
=> ["TRUNCATE TABLE films"]
;; or as pure data DSL:
(-> {:truncate :films}
(sql/format))
=> ["TRUNCATE TABLE films"]
Set operations
Queries may be combined with a :union
, :union-all
, :intersect
or :except
keyword:
(sql/format {:union [(-> (select :*) (from :foo))
(-> (select :*) (from :bar))]})
=> ["SELECT * FROM foo UNION SELECT * FROM bar"]
There are also helpers for each of those:
(sql/format (union (-> (select :*) (from :foo))
(-> (select :*) (from :bar))))
=> ["SELECT * FROM foo UNION SELECT * FROM bar"]
Note: different databases have different precedence rules for these set operations when used in combination -- you may need to use
:nest
to add(
..)
in order to combine these operations in a single SQL statement, if the natural order produced by HoneySQL does not work "as expected" for your database.
Functions
Function calls (and expressions with operators) can be specified as vectors where the first element is either a keyword or a symbol:
(-> (select :*) (from :foo)
(where [:> :date_created [:date_add [:now] [:interval 24 :hours]]])
(sql/format))
=> ["SELECT * FROM foo WHERE date_created > DATE_ADD(NOW(), INTERVAL ? HOURS)" 24]
Note: The above example may be specific to MySQL but the general principle of vectors for function calls applies to all dialects.
A shorthand syntax also exists for simple function calls:
keywords that begin with %
are interpreted as SQL function calls:
(-> (select :%count.*) (from :foo) sql/format)
=> ["SELECT COUNT(*) FROM foo"]
;; with an alias:
(-> (select [:%count.* :total]) (from :foo) sql/format)
=> ["SELECT COUNT(*) AS total FROM foo"]
(-> (select :%max.id) (from :foo) sql/format)
=> ["SELECT MAX(id) FROM foo"]
Since regular function calls are indicated with vectors and so are aliased pairs, this shorthand can be more convenient due to the extra wrapping needed for the regular function calls in a select:
(-> (select [[:count :*]]) (from :foo) sql/format)
=> ["SELECT COUNT(*) FROM foo"]
(-> (select [[:count :*] :total]) (from :foo) sql/format)
=> ["SELECT COUNT(*) AS total FROM foo"]
(-> (select [:%count.*]) (from :foo) sql/format)
=> ["SELECT COUNT(*) FROM foo"]
;; or even:
(-> (select :%count.*) (from :foo) sql/format)
=> ["SELECT COUNT(*) FROM foo"]
(-> (select [[:max :id]]) (from :foo) sql/format)
=> ["SELECT MAX(id) FROM foo"]
(-> (select [[:max :id] :highest]) (from :foo) sql/format)
=> ["SELECT MAX(id) AS highest FROM foo"]
;; the pure data DSL requires an extra level of brackets:
(-> {:select [[[:max :id]]], :from [:foo]} sql/format)
=> ["SELECT MAX(id) FROM foo"]
(-> {:select [[[:max :id] :highest]], :from [:foo]} sql/format)
=> ["SELECT MAX(id) AS highest FROM foo"]
;; the shorthand makes this simpler:
(-> {:select [[:%max.id]], :from [:foo]} sql/format)
=> ["SELECT MAX(id) FROM foo"]
(-> {:select [[:%max.id :highest]], :from [:foo]} sql/format)
=> ["SELECT MAX(id) AS highest FROM foo"]
;; or even (no alias):
(-> {:select [:%max.id], :from [:foo]} sql/format)
=> ["SELECT MAX(id) FROM foo"]
;; or even (no alias, no other columns):
(-> {:select :%max.id, :from :foo} sql/format)
=> ["SELECT MAX(id) FROM foo"]
Custom columns using functions are built with the same vector format. Be sure to properly nest the vectors so that the first element in the selection is the custom function and the second is the column alias.
(sql/format
{:select [:job_name ;; A bare field selection
[[:avg [:/ [:- :end_time :start_time] 1000.0]] ;; A custom function
:avg_exec_time_seconds ;; The column alias
]]
:from [:job_data]
:group-by :job_name})
=> ["SELECT job_name, AVG((end_time - start_time) / ?) AS avg_exec_time_seconds FROM job_data GROUP BY job_name" 1000.0]
If a keyword begins with '
, the function name is formatted as a SQL
entity rather than being converted to uppercase and having hyphens -
converted to spaces). That means that hyphens -
will become underscores _
unless you have quoting enabled:
(-> (select :*) (from :foo)
(where [:'my-schema.SomeFunction :bar 0])
(sql/format))
=> ["SELECT * FROM foo WHERE my_schema.SomeFunction(bar, ?)" 0]
(-> (select :*) (from :foo)
(where [:'my-schema.SomeFunction :bar 0])
(sql/format :quoted true))
=> ["SELECT * FROM \"foo\" WHERE \"my-schema\".\"SomeFunction\"(\"bar\", ?)" 0]
(-> (select :*) (from :foo)
(where [:'my-schema.SomeFunction :bar 0])
(sql/format :dialect :mysql))
=> ["SELECT * FROM `foo` WHERE `my-schema`.`SomeFunction`(`bar`, ?)" 0]
Note: in non-function contexts, if a keyword begins with
'
, it is transcribed into the SQL exactly as-is, with no case or character conversion at all.
Bindable parameters
Keywords that begin with ?
are interpreted as bindable parameters:
(-> (select :id)
(from :foo)
(where [:= :a :?baz])
(sql/format {:params {:baz "BAZ"}}))
=> ["SELECT id FROM foo WHERE a = ?" "BAZ"]
;; or with numbered parameters:
(-> (select :id)
(from :foo)
(where [:= :a :?baz])
(sql/format {:params {:baz "BAZ"} :numbered true}))
=> ["SELECT id FROM foo WHERE a = $1" "BAZ"]
;; or as pure data DSL:
(-> {:select [:id], :from [:foo], :where [:= :a :?baz]}
(sql/format {:params {:baz "BAZ"}}))
=> ["SELECT id FROM foo WHERE a = ?" "BAZ"]
Miscellaneous
Sometimes you want to provide SQL fragments directly or have certain values placed into the SQL string rather than turned into a parameter.
The :raw
syntax lets you embed SQL fragments directly into a HoneySQL expression.
It accepts either a single string to embed or a vector of expressions that will be
converted to strings and embedded as a single string.
The :inline
syntax attempts to turn a Clojure value into a SQL value and then
embeds that string, e.g., [:inline "foo"]
produces 'foo'
(a SQL string).
The :param
syntax identifies a named parameter whose value will be supplied
via the :params
argument to format
.
The :lift
syntax will prevent interpretation of Clojure data structures as
part of the DSL and instead turn such values into parameters (useful when you
want to pass a vector or a hash map directly as a positional parameter value,
for example when you have extended next.jdbc
's SettableParameter
protocol
to a data structure -- as is common when working with PostgreSQL's JSON/JSONB types).
Finally, the :nest
syntax will cause an extra set of parentheses to be
wrapped around its argument, after formatting that argument as a SQL expression.
These can be combined to allow more fine-grained control over SQL generation:
(def call-qualify-map
(-> (select [[:foo :bar]] [[:raw "@var := foo.bar"]])
(from :foo)
(where [:= :a [:param :baz]] [:= :b [:inline 42]])))
call-qualify-map
=> {:where [:and [:= :a [:param :baz]] [:= :b [:inline 42]]]
:from (:foo)
:select [[[:foo :bar]] [[:raw "@var := foo.bar"]]]}
(sql/format call-qualify-map {:params {:baz "BAZ"}})
=> ["SELECT FOO(bar), @var := foo.bar FROM foo WHERE (a = ?) AND (b = 42)" "BAZ"]
(-> (select :*)
(from :foo)
(where [:< :expired_at [:raw ["now() - '" 5 " seconds'"]]])
(sql/format))
=> ["SELECT * FROM foo WHERE expired_at < now() - '5 seconds'"]
(-> (select :*)
(from :foo)
(where [:< :expired_at [:raw ["now() - '" [:lift 5] " seconds'"]]])
(sql/format))
=> ["SELECT * FROM foo WHERE expired_at < now() - '? seconds'" 5]
(-> (select :*)
(from :foo)
(where [:< :expired_at [:raw ["now() - '" [:param :t] " seconds'"]]])
(sql/format {:params {:t 5}}))
=> ["SELECT * FROM foo WHERE expired_at < now() - '? seconds'" 5]
(-> (select :*)
(from :foo)
(where [:< :expired_at [:raw ["now() - " [:inline (str 5 " seconds")]]]])
(sql/format))
=> ["SELECT * FROM foo WHERE expired_at < now() - '5 seconds'"]
PostGIS
A common example in the wild is the PostGIS extension to PostgreSQL where you have a lot of function calls needed in code:
(-> (insert-into :sample)
(values [{:location [:ST_SetSRID
[:ST_MakePoint 0.291 32.621]
[:cast 4325 :integer]]}])
(sql/format {:pretty true}))
=> ["
INSERT INTO sample (location)
VALUES (ST_SETSRID(ST_MAKEPOINT(?, ?), CAST(? AS INTEGER)))
"
0.291 32.621 4325]
Entity Names
To quote SQL entity names, pass the :quoted true
option to format
and they will
be quoted according to the selected dialect. If you override the dialect in a
format
call, by passing the :dialect
option, SQL entity names will be automatically
quoted. You can override the dialect and turn off quoting by passing :quoted false
.
Valid :dialect
options are :ansi
(the default, use this for PostgreSQL),
:mysql
, :oracle
, or :sqlserver
. As of 2.5.1091, :nrql
is also supported:
(-> (select :foo.a)
(from :foo)
(where [:= :foo.a "baz"])
(sql/format {:dialect :mysql}))
=> ["SELECT `foo`.`a` FROM `foo` WHERE `foo`.`a` = ?" "baz"]
(-> (select :foo.a)
(from :foo)
(where [:= :foo.a "baz"])
(sql/format {:dialect :nrql}))
=> ["SELECT `foo.a` FROM foo WHERE `foo.a` = 'baz'"]
See New Relic NRQL Support for more details of the NRQL dialect.
Locking
The ANSI/PostgreSQL/SQLServer dialects support locking selects via a FOR
clause as follows:
:for [<lock-strength> <table(s)> <qualifier>]
where<lock-strength>
is required and may be one of::update
:no-key-update
:share
:key-share
- Both
<table(s)>
and<qualifier>
are optional but if present,<table(s)>
must either be:- a single table name (as a keyword) or
- a sequence of table names (as keywords)
<qualifier>
can be:nowait
,:wait
,:skip-locked
etc.
If <table(s)>
and <qualifier>
are both omitted, you may also omit the [
..]
and just say :for :update
etc.
(-> (select :foo.a)
(from :foo)
(where [:= :foo.a "baz"])
(for :update)
(sql/format))
=> ["SELECT foo.a FROM foo WHERE foo.a = ? FOR UPDATE" "baz"]
If the :mysql
dialect is selected, an additional locking clause is available:
:lock :in-share-mode
.
(sql/format {:select [:*] :from :foo
:where [:= :name [:inline "Jones"]]
:lock [:in-share-mode]}
{:dialect :mysql :quoted false})
=> ["SELECT * FROM foo WHERE name = 'Jones' LOCK IN SHARE MODE"]
Dashes are allowed in quoted names:
(sql/format
{:select [:f.foo-id :f.foo-name]
:from [[:foo-bar :f]]
:where [:= :f.foo-id 12345]}
{:quoted true})
=> ["SELECT \"f\".\"foo-id\", \"f\".\"foo-name\" FROM \"foo-bar\" AS \"f\" WHERE \"f\".\"foo-id\" = ?" 12345]
Big, complicated example
Here's a big, complicated query. Note that HoneySQL makes no attempt to verify that your queries make any sense. It merely renders surface syntax.
(def big-complicated-map
(-> (select-distinct :f.* :b.baz :c.quux [:b.bla "bla-bla"]
[[:now]] [[:raw "@x := 10"]])
(from [:foo :f] [:baz :b])
(join :draq [:= :f.b :draq.x]
:eldr [:= :f.e :eldr.t])
(left-join [:clod :c] [:= :f.a :c.d])
(right-join :bock [:= :bock.z :c.e])
(where [:or
[:and [:= :f.a "bort"] [:not= :b.baz [:param :param1]]]
[:and [:< 1 2] [:< 2 3]]
[:in :f.e [1 [:param :param2] 3]]
[:between :f.e 10 20]])
(group-by :f.a :c.e)
(having [:< 0 :f.e])
(order-by [:b.baz :desc] :c.quux [:f.a :nulls-first])
(limit 50)
(offset 10)))
big-complicated-map
=> {:select-distinct [:f.* :b.baz :c.quux [:b.bla "bla-bla"]
[[:now]] [[:raw "@x := 10"]]]
:from [[:foo :f] [:baz :b]]
:join [:draq [:= :f.b :draq.x]
:eldr [:= :f.e :eldr.t]]
:left-join [[:clod :c] [:= :f.a :c.d]]
:right-join [:bock [:= :bock.z :c.e]]
:where [:or
[:and [:= :f.a "bort"] [:not= :b.baz [:param :param1]]]
[:and [:< 1 2] [:< 2 3]]
[:in :f.e [1 [:param :param2] 3]]
[:between :f.e 10 20]]
:group-by [:f.a :c.e]
:having [:< 0 :f.e]
:order-by [[:b.baz :desc] :c.quux [:f.a :nulls-first]]
:limit 50
:offset 10}
(sql/format big-complicated-map
{:params {:param1 "gabba" :param2 2}
:pretty true})
=> ["
SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS \"bla-bla\", NOW(), @x := 10
FROM foo AS f, baz AS b
INNER JOIN draq ON f.b = draq.x INNER JOIN eldr ON f.e = eldr.t
LEFT JOIN clod AS c ON f.a = c.d
RIGHT JOIN bock ON bock.z = c.e
WHERE ((f.a = ?) AND (b.baz <> ?)) OR ((? < ?) AND (? < ?)) OR (f.e IN (?, ?, ?)) OR f.e BETWEEN ? AND ?
GROUP BY f.a, c.e
HAVING ? < f.e
ORDER BY b.baz DESC, c.quux ASC, f.a NULLS FIRST
LIMIT ?
OFFSET ?
"
"bort" "gabba" 1 2 2 3 1 2 3 10 20 0 50 10]
;; with numbered parameters:
(sql/format big-complicated-map
{:params {:param1 "gabba" :param2 2}
:pretty true :numbered true})
=> ["
SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS \"bla-bla\", NOW(), @x := 10
FROM foo AS f, baz AS b
INNER JOIN draq ON f.b = draq.x INNER JOIN eldr ON f.e = eldr.t
LEFT JOIN clod AS c ON f.a = c.d
RIGHT JOIN bock ON bock.z = c.e
WHERE ((f.a = $1) AND (b.baz <> $2)) OR (($3 < $4) AND ($5 < $6)) OR (f.e IN ($7, $8, $9)) OR f.e BETWEEN $10 AND $11
GROUP BY f.a, c.e
HAVING $12 < f.e
ORDER BY b.baz DESC, c.quux ASC, f.a NULLS FIRST
LIMIT $13
OFFSET $14
"
"bort" "gabba" 1 2 2 3 1 2 3 10 20 0 50 10]
;; Printable and readable
(require '[clojure.edn :as edn])
(= big-complicated-map (edn/read-string (pr-str big-complicated-map)))
=> true
Extensibility
Any keyword (or symbol) that appears as the first element of a vector will be treated as a generic function unless it is declared to be an operator or "special syntax". Any keyword (or symbol) that appears as a key in a hash map will be treated as a SQL clause -- and must either be built-in or must be registered as a new clause.
If your database supports <=>
as an operator, you can tell HoneySQL about it using the register-op!
function (which should be called before the first call to honey.sql/format
):
(sql/register-op! :<=>)
;; all operators are assumed to be variadic:
(-> (select :a) (where [:<=> :a "foo"]) sql/format)
=> ["SELECT a WHERE a <=> ?" "foo"]
(-> (select :a) (where [:<=> "food" :a "fool"]) sql/format)
=> ["SELECT a WHERE ? <=> a <=> ?" "food" "fool"]
Sometimes you want an operator to ignore nil
clauses (:and
and :or
are declared that way):
(sql/register-op! :<=> :ignore-nil true)
Or perhaps your database supports syntax like a BETWIXT b AND c
, in which case you can use register-fn!
to tell HoneySQL about it (again, called before the first call to honey.sql/format
):
;; the formatter will be passed your new operator (function) and a
;; sequence of the arguments provided to it (so you can write any arity ops):
(sql/register-fn! :betwixt
(fn [op [a b c]]
(let [[sql-a & params-a] (sql/format-expr a)
[sql-b & params-b] (sql/format-expr b)
[sql-c & params-c] (sql/format-expr c)]
(-> [(str sql-a " " (sql/sql-kw op) " "
sql-b " AND " sql-c)]
(c/into params-a)
(c/into params-b)
(c/into params-c)))))
;; example usage:
(-> (select :a) (where [:betwixt :a 1 10]) sql/format)
=> ["SELECT a WHERE a BETWIXT ? AND ?" 1 10]
;; with numbered parameters:
(-> (select :a) (where [:betwixt :a 1 10]) (sql/format {:numbered true}))
=> ["SELECT a WHERE a BETWIXT $1 AND $2" 1 10]
Note: the generation of positional placeholders (
?
) or numbered placeholders ($1
,$2
, etc) is handled automatically byformat-expr
so you get this behavior "for free" in your extensions, as long as you use the public API forhoney.sql
. You should avoid writing extensions that generate placeholders directly if you want them to work with numbered parameters.
You can also register SQL clauses, specifying the keyword, the formatting function, and an existing clause that this new clause should be processed before:
;; the formatter will be passed your new clause and the value associated
;; with that clause in the DSL (which is often a sequence but does not
;; need to be -- it can be whatever syntax you desire in the DSL):
(sql/register-clause! :foobar
(fn [clause x]
(let [[sql & params]
(if (ident? x)
(sql/format-expr x)
(sql/format-dsl x))]
(c/into [(str (sql/sql-kw clause) " " sql)] params)))
:from) ; SELECT ... FOOBAR ... FROM ...
;; example usage:
(sql/format {:select [:a :b] :foobar :baz})
=> ["SELECT a, b FOOBAR baz"]
(sql/format {:select [:a :b] :foobar {:where [:= :id 1]}})
=> ["SELECT a, b FOOBAR WHERE id = ?" 1]
If you find yourself registering an operator, a function (syntax), or a new clause, consider submitting a pull request to HoneySQL so others can use it, too. If it is dialect-specific, let me know in the pull request.
HoneySQL 1.x will continue to get critical security fixes but otherwise should be considered "legacy" at this point.
License
Copyright (c) 2020-2024 Sean Corfield. HoneySQL 1.x was copyright (c) 2012-2020 Justin Kramer and Sean Corfield.
Distributed under the Eclipse Public License, the same as Clojure.
More Resourcesto explore the angular.
mail [email protected] to add your project or resources here 🔥.
- 1Biff | Clojure web framework
https://biffweb.com/
A Clojure web framework for solo developers.
- 2Kamalavelan / column · GitLab
https://gitlab.com/demonshreder/column
Column sits on top of pedestal to support your software
- 3Clojure Tutorials
https://www.youtube.com/channel/UC6yONKYeoE2P3bsahDtsimg/videos:
A collection programming tutorials for Clojure, covering logic programming, transducers, core.async, program optimization, and many more topics. Q) These videos aren't available in my country! A) Videos are also available via Dropbox and Google Drive: (payment options below) same price, billed once a month. Users get access to raw .mp4 files. This is a manual process, so expect a 1-2 day delay, but this method should work better for some users. If you don't mind the Youtube experience, using this site will most likely be more satisfactory Paypal: http://goo.gl/xgTq0j Bitcoin: http://goo.gl/TUk79e Q) Why do you charge for videos? Isn't Youtube free? A) Unfortunately, in order to get any sort of income from Youtube, videos must have a very high view count. Somewhere in the range of 100k views per video. Getting that sort of viewing of tutorials related to programming in any programming language would be hard.
- 4reborg
https://www.youtube.com/channel/UCH0CkLvbv6yEyrUnw9qujpQ/videos:
A weekly screencast about the functions in the Clojure standard library. The screencast is based on the book "Clojure Standard Library, An Annotated Reference" by Manning available at https://www.manning.com/books/clojure-standard-library.
- 5Misophistful
https://www.youtube.com/user/Misophistful/videos:
Screencasts and presentations about programming with Clojure.
- 6ClojureVids
https://www.youtube.com/channel/UCrwwOZ4h2FQhAdTMfjyQfQA/playlists
ClojureVids is dedicated to delivering high-quality Clojure video training for all skill levels.
- 7Experiments in realtime web framework design. Like Meteor, but for Clojure(Script)
https://github.com/venantius/photon
Experiments in realtime web framework design. Like Meteor, but for Clojure(Script) - venantius/photon
- 8{{ mustache }} for Clojure
https://github.com/fhd/clostache
{{ mustache }} for Clojure. Contribute to fhd/clostache development by creating an account on GitHub.
- 9Clojure JSON and JSON SMILE (binary json format) encoding/decoding
https://github.com/dakrone/cheshire
Clojure JSON and JSON SMILE (binary json format) encoding/decoding - dakrone/cheshire
- 10A neural networks library for Clojure
https://github.com/mrdimosthenis/clj-synapses
A neural networks library for Clojure. Contribute to mrdimosthenis/clj-synapses development by creating an account on GitHub.
- 11Clojure(Script) library for declarative data description and validation
https://github.com/plumatic/schema
Clojure(Script) library for declarative data description and validation - plumatic/schema
- 12Simple, high-performance event-driven HTTP client+server for Clojure
https://github.com/http-kit/http-kit
Simple, high-performance event-driven HTTP client+server for Clojure - http-kit/http-kit
- 13The Pedestal Server-side Libraries
https://github.com/pedestal/pedestal
The Pedestal Server-side Libraries. Contribute to pedestal/pedestal development by creating an account on GitHub.
- 14local. mutable. variables.
https://github.com/ztellman/proteus
local. mutable. variables. Contribute to ztellman/proteus development by creating an account on GitHub.
- 15A library for development of single-page full-stack web applications in clj/cljs
https://github.com/fulcrologic/fulcro
A library for development of single-page full-stack web applications in clj/cljs - fulcrologic/fulcro
- 16fireplace.vim: Clojure REPL support
https://github.com/tpope/vim-fireplace
fireplace.vim: Clojure REPL support. Contribute to tpope/vim-fireplace development by creating an account on GitHub.
- 17Home
https://github.com/cgrand/enlive/wiki
a selector-based (à la CSS) templating and transformation system for Clojure - cgrand/enlive
- 18This is the home of O'Reilly's Clojure Cookbook - http://clojure-cookbook.com
https://github.com/clojure-cookbook/clojure-cookbook
This is the home of O'Reilly's Clojure Cookbook - http://clojure-cookbook.com - clojure-cookbook/clojure-cookbook
- 19Graph based visualization tool for re-frame event chains
https://github.com/ertugrulcetin/re-frame-flow
Graph based visualization tool for re-frame event chains - ertugrulcetin/re-frame-flow
- 20Build software better, together
https://github.com/lacuna/bifurcan:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 21Daniel Amber
https://www.youtube.com/c/onthecodeagain/videos:
Hey guys, I'm Daniel Amber! I created this channel to be about all aspects of web development. The initial idea was to have a channel that focused on the process of learning web and software development as a beginner, but I want to expand the channel to cover more advanced programming topics in a variety of different languages including JavaScript, PHP and Clojure. If you are a new programmer and are looking for some good tutorials this is a channel for you. Or if you are a seasoned developer looking for a bit of self-improvement this might be up your alley as well! In short, if you are or want to be a web developer or any kind of coder, then this channel was made for people like you :)
- 22Build software better, together
https://github.com/bitemyapp/revise:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 23Moved to Codeberg; this is a convenience mirror
https://github.com/technomancy/leiningen
Moved to Codeberg; this is a convenience mirror. Contribute to technomancy/leiningen development by creating an account on GitHub.
- 24Build software better, together
https://github.com/noprompt/meander:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 25Build software better, together
https://github.com/redplanetlabs/specter:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 26DI is a dependency injection framework that allows you to define dependencies as cheaply as defining function arguments.
https://github.com/darkleaf/di
DI is a dependency injection framework that allows you to define dependencies as cheaply as defining function arguments. - darkleaf/di
- 27Build software better, together
https://github.com/juxt/tick:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 28:rainbow: Simpler Rainbow Parentheses
https://github.com/junegunn/rainbow_parentheses.vim
:rainbow: Simpler Rainbow Parentheses. Contribute to junegunn/rainbow_parentheses.vim development by creating an account on GitHub.
- 29An optimized pattern matching library for Clojure
https://github.com/clojure/core.match
An optimized pattern matching library for Clojure. Contribute to clojure/core.match development by creating an account on GitHub.
- 30a catalog of common Clojure errors and their meaning
https://github.com/yogthos/clojure-error-message-catalog
a catalog of common Clojure errors and their meaning - yogthos/clojure-error-message-catalog
- 31Security library for Clojure
https://github.com/funcool/buddy
Security library for Clojure. Contribute to funcool/buddy development by creating an account on GitHub.
- 32Build software better, together
https://github.com/jimpil/duratom:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 33Build software better, together
https://github.com/apa512/clj-rethinkdb:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 34Modeling domain data on the basis of Clojure records.
https://github.com/friemen/domaintypes
Modeling domain data on the basis of Clojure records. - friemen/domaintypes
- 35A Clojure linter focused on style and code shape.
https://github.com/NoahTheDuke/splint
A Clojure linter focused on style and code shape. Contribute to NoahTheDuke/splint development by creating an account on GitHub.
- 36First-class patterns for Clojure. Made with love, functions, and just the right amount of syntax.
https://github.com/missingfaktor/akar
First-class patterns for Clojure. Made with love, functions, and just the right amount of syntax. - missingfaktor/akar
- 37A document database written in Clojure
https://github.com/robashton/cravendb
A document database written in Clojure. Contribute to robashton/cravendb development by creating an account on GitHub.
- 38Project your Clojure(Script) REPL into the same context as your code when it ran
https://github.com/vvvvalvalval/scope-capture
Project your Clojure(Script) REPL into the same context as your code when it ran - vvvvalvalval/scope-capture
- 39Clojure bindings for the BigML.io API
https://github.com/bigmlcom/clj-bigml
Clojure bindings for the BigML.io API. Contribute to bigmlcom/clj-bigml development by creating an account on GitHub.
- 40Easier-than-print dataflow tracing to tap> and Portal with automatic last-input function replay on eval, instant re-render and effortless extraction of traced data
https://github.com/gnl/playback
Easier-than-print dataflow tracing to tap> and Portal with automatic last-input function replay on eval, instant re-render and effortless extraction of traced data - gnl/playback
- 41Multi-target Clojure/script HTTP client
https://github.com/nervous-systems/kvlt
Multi-target Clojure/script HTTP client. Contribute to nervous-systems/kvlt development by creating an account on GitHub.
- 42Clojure wrappers for Lettuce (Java Redis client)
https://github.com/lerouxrgd/celtuce
Clojure wrappers for Lettuce (Java Redis client) . Contribute to lerouxrgd/celtuce development by creating an account on GitHub.
- 43A small spying and stubbing library for Clojure and ClojureScript
https://github.com/GreenPowerMonitor/test-doubles
A small spying and stubbing library for Clojure and ClojureScript - GreenPowerMonitor/test-doubles
- 44Clojure support for Visual Studio Code
https://github.com/avli/clojureVSCode
Clojure support for Visual Studio Code. Contribute to avli/clojureVSCode development by creating an account on GitHub.
- 45An extensible authentication and authorization library for Clojure Ring web applications and services.
https://github.com/cemerick/friend
An extensible authentication and authorization library for Clojure Ring web applications and services. - GitHub - cemerick/friend: An extensible authentication and authorization library for Clojur...
- 46A migration library for clojure
https://github.com/macourtney/drift
A migration library for clojure. Contribute to macourtney/drift development by creating an account on GitHub.
- 47Clojure library for fast JSON encoding and decoding.
https://github.com/metosin/jsonista
Clojure library for fast JSON encoding and decoding. - metosin/jsonista
- 48Fibers, Channels and Actors for Clojure
https://github.com/puniverse/pulsar
Fibers, Channels and Actors for Clojure. Contribute to puniverse/pulsar development by creating an account on GitHub.
- 49A Clojure library for JavaFX
https://github.com/aaronc/fx-clj
A Clojure library for JavaFX. Contribute to aaronc/fx-clj development by creating an account on GitHub.
- 50Clojure wrapper around JGit
https://github.com/clj-jgit/clj-jgit
Clojure wrapper around JGit. Contribute to clj-jgit/clj-jgit development by creating an account on GitHub.
- 51Clojure REPL that is aware of surrounding lexical scope
https://github.com/GeorgeJahad/debug-repl
Clojure REPL that is aware of surrounding lexical scope - GeorgeJahad/debug-repl
- 52A better Vim integration story for Clojure
https://github.com/dgrnbrg/vim-redl
A better Vim integration story for Clojure. Contribute to dgrnbrg/vim-redl development by creating an account on GitHub.
- 53Verbal-Exprejon is a Clojure library that helps you build complex regexes without any regex
https://github.com/WeshGuillaume/Verbal-Exprejon
Verbal-Exprejon is a Clojure library that helps you build complex regexes without any regex - WeshGuillaume/Verbal-Exprejon
- 54(+ clj cljs datomic datascript re-frame-esque-frp)
https://github.com/metasoarous/datsys
(+ clj cljs datomic datascript re-frame-esque-frp) - metasoarous/datsys
- 55JDBC library for Clojure
https://github.com/funcool/clojure.jdbc
JDBC library for Clojure. Contribute to funcool/clojure.jdbc development by creating an account on GitHub.
- 56Build software better, together
https://github.com/Malabarba/lazy-map-clojure:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 57Build tooling for Clojure.
https://github.com/boot-clj/boot
Build tooling for Clojure. Contribute to boot-clj/boot development by creating an account on GitHub.
- 58Build software better, together
https://github.com/datacrypt-project/hitchhiker-tree:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 59Build software better, together
https://github.com/mpenet/spandex:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 60Build software better, together
https://github.com/amalloy/ordered:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 61Build software better, together
https://github.com/AppsFlyer/aerospike-clj:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 62Build software better, together
https://github.com/mpenet/alia:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 63Build software better, together
https://github.com/TheLadders/sqlium/
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 64Build software better, together
https://github.com/xtdb/xtdb:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 65Clojure HTTP server abstraction
https://github.com/ring-clojure/ring
Clojure HTTP server abstraction. Contribute to ring-clojure/ring development by creating an account on GitHub.
- 66Build software better, together
https://github.com/Factual/durable-queue:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 67Fast library for rendering HTML in Clojure
https://github.com/weavejester/hiccup
Fast library for rendering HTML in Clojure. Contribute to weavejester/hiccup development by creating an account on GitHub.
- 68A Library to parse natural language in pure Clojure and ClojureScript
https://github.com/turbopape/postagga
A Library to parse natural language in pure Clojure and ClojureScript - turbopape/postagga
- 69JDBC from Clojure (formerly clojure.contrib.sql)
https://github.com/clojure/java.jdbc
JDBC from Clojure (formerly clojure.contrib.sql). Contribute to clojure/java.jdbc development by creating an account on GitHub.
- 70A concise routing library for Ring/Clojure
https://github.com/weavejester/compojure
A concise routing library for Ring/Clojure. Contribute to weavejester/compojure development by creating an account on GitHub.
- 71A Clojure(script) SQL library for building APIs: Datomic® (GraphQL-ish) pull syntax, data driven configuration, dynamic filtering with relations in mind
https://github.com/walkable-server/walkable
A Clojure(script) SQL library for building APIs: Datomic® (GraphQL-ish) pull syntax, data driven configuration, dynamic filtering with relations in mind - walkable-server/walkable
- 72A library to create and manipulate SQL database schemas with migrations support.
https://github.com/budu/lobos
A library to create and manipulate SQL database schemas with migrations support. - budu/lobos
- 73Database-independent migration library
https://github.com/weavejester/ragtime
Database-independent migration library. Contribute to weavejester/ragtime development by creating an account on GitHub.
- 74Reloaded components à la carte
https://github.com/danielsz/system
Reloaded components à la carte. Contribute to danielsz/system development by creating an account on GitHub.
- 75Clojure practice challenges – train on code kata
https://www.codewars.com/kata/search/clojure
Practice Clojure coding with code challenges designed to engage your programming skills. Solve coding problems and pick up new techniques from your fellow peers.
- 76A simple, fast and versatile Datalog database
https://github.com/juji-io/datalevin
A simple, fast and versatile Datalog database. Contribute to juji-io/datalevin development by creating an account on GitHub.
- 77ClojureScript compilation made easy
https://github.com/thheller/shadow-cljs
ClojureScript compilation made easy. Contribute to thheller/shadow-cljs development by creating an account on GitHub.
- 78A fast data-driven routing library for Clojure/Script
https://github.com/metosin/reitit
A fast data-driven routing library for Clojure/Script - metosin/reitit
- 79Staged compilation for Clojure through environment & special-form aware syntax-quoting.
https://github.com/brandonbloom/metaclj
Staged compilation for Clojure through environment & special-form aware syntax-quoting. - brandonbloom/metaclj
- 80A music programming language for musicians. :notes:
https://github.com/alda-lang/alda
A music programming language for musicians. :notes: - alda-lang/alda
- 81Connection pools for JDBC databases. Simple wrapper around C3P0.
https://github.com/metabase/connection-pool
Connection pools for JDBC databases. Simple wrapper around C3P0. - metabase/connection-pool
- 82Complete instrumentation for clojure.spec
https://github.com/jeaye/orchestra
Complete instrumentation for clojure.spec. Contribute to jeaye/orchestra development by creating an account on GitHub.
- 83Facilities for async programming and communication in Clojure
https://github.com/clojure/core.async
Facilities for async programming and communication in Clojure - clojure/core.async
- 84A library for calendar operations that are aware of weekends and holidays
https://github.com/luciolucio/holi
A library for calendar operations that are aware of weekends and holidays - luciolucio/holi
- 85Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more.
https://github.com/uncomplicate/fluokitten
Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more. - uncomplicate/fluokitten
- 86Klipse is a JavaScript plugin for embedding interactive code snippets in tech blogs.
https://github.com/viebel/klipse
Klipse is a JavaScript plugin for embedding interactive code snippets in tech blogs. - viebel/klipse
- 87Leiningen plugin for consuming and compiling protobuf schemas
https://github.com/AppsFlyer/lein-protodeps
Leiningen plugin for consuming and compiling protobuf schemas - AppsFlyer/lein-protodeps
- 88tools.build's missing piece – install, sign and deploy libraries easily and securely like with Leiningen
https://github.com/gnl/build.simple
tools.build's missing piece – install, sign and deploy libraries easily and securely like with Leiningen - gnl/build.simple
- 89Macros for defining monads, and definition of the most common monads
https://github.com/clojure/algo.monads
Macros for defining monads, and definition of the most common monads - clojure/algo.monads
- 90A Clojure wrapper to HikariCP JDBC connection pool
https://github.com/tomekw/hikari-cp
A Clojure wrapper to HikariCP JDBC connection pool - tomekw/hikari-cp
- 91The Clojure Interactive Development Environment that Rocks for Emacs
https://github.com/clojure-emacs/cider
The Clojure Interactive Development Environment that Rocks for Emacs - clojure-emacs/cider
- 92Midje provides a migration path from clojure.test to a more flexible, readable, abstract, and gracious style of testing
https://github.com/marick/Midje
Midje provides a migration path from clojure.test to a more flexible, readable, abstract, and gracious style of testing - marick/Midje
- 93A date and time library for Clojure, wrapping the Joda Time library.
https://github.com/clj-time/clj-time
A date and time library for Clojure, wrapping the Joda Time library. - clj-time/clj-time
- 94A powerful Clojure web library, full HTTP, full async - see https://juxt.pro/yada/index.html
https://github.com/juxt/yada
A powerful Clojure web library, full HTTP, full async - see https://juxt.pro/yada/index.html - juxt/yada
- 95Asynchronous streaming communication for Clojure - web server, web client, and raw TCP/UDP
https://github.com/clj-commons/aleph
Asynchronous streaming communication for Clojure - web server, web client, and raw TCP/UDP - clj-commons/aleph
- 96An integrated security system for applications built on component
https://github.com/juxt/bolt
An integrated security system for applications built on component - juxt/bolt
- 97Category Theory and Algebraic abstractions for Clojure and ClojureScript.
https://github.com/funcool/cats
Category Theory and Algebraic abstractions for Clojure and ClojureScript. - funcool/cats
- 98A functional effect and streaming system for Clojure/Script
https://github.com/leonoel/missionary
A functional effect and streaming system for Clojure/Script - leonoel/missionary
- 99Coroutine support for clojure
https://github.com/leonoel/cloroutine
Coroutine support for clojure. Contribute to leonoel/cloroutine development by creating an account on GitHub.
- 100Facilities for async programming and communication in Clojure
https://github.com/clojure/core.async/
Facilities for async programming and communication in Clojure - clojure/core.async
- 101Clojure and Clojurescript support for Gradle
https://github.com/clojurephant/clojurephant
Clojure and Clojurescript support for Gradle. Contribute to clojurephant/clojurephant development by creating an account on GitHub.
- 102The Next-Level background job processing library for Clojure
https://github.com/nilenso/goose
The Next-Level background job processing library for Clojure - nilenso/goose
- 103A modern low-level Clojure wrapper for JDBC-based access to databases.
https://github.com/seancorfield/next-jdbc
A modern low-level Clojure wrapper for JDBC-based access to databases. - seancorfield/next-jdbc
- 104A Clojure hierarchical set.
https://github.com/llasram/hier-set
A Clojure hierarchical set. Contribute to llasram/hier-set development by creating an account on GitHub.
- 105Flexible datastore migration and seeding for Clojure projects
https://github.com/juxt/joplin
Flexible datastore migration and seeding for Clojure projects - juxt/joplin
- 106Tools for transparent data transformation
https://github.com/noprompt/meander
Tools for transparent data transformation. Contribute to noprompt/meander development by creating an account on GitHub.
- 107Modern cryptography (libsodium/NaCl) for Clojure
https://github.com/lvh/caesium
Modern cryptography (libsodium/NaCl) for Clojure. Contribute to lvh/caesium development by creating an account on GitHub.
- 108An optional type system for Clojure
https://github.com/clojure/core.typed
An optional type system for Clojure. Contribute to clojure/core.typed development by creating an account on GitHub.
- 109Clojure email support
https://github.com/drewr/postal
Clojure email support. Contribute to drewr/postal development by creating an account on GitHub.
- 110efficient small collections for clojure
https://github.com/ztellman/clj-tuple
efficient small collections for clojure. Contribute to ztellman/clj-tuple development by creating an account on GitHub.
- 111Join clojurians on Slack
http://clojurians.net/
Slack is a new way to communicate with your team. It’s faster, better organized, and more secure than email.
- 112Clojure support for protocol buffers
https://github.com/AppsFlyer/pronto
Clojure support for protocol buffers. Contribute to AppsFlyer/pronto development by creating an account on GitHub.
- 113Tasty SQL for Clojure.
https://github.com/korma/Korma
Tasty SQL for Clojure. Contribute to korma/Korma development by creating an account on GitHub.
- 114Structural validation library for Clojure(Script)
https://github.com/funcool/struct
Structural validation library for Clojure(Script). Contribute to funcool/struct development by creating an account on GitHub.
- 115MIGRATE ALL THE THINGS!
https://github.com/yogthos/migratus
MIGRATE ALL THE THINGS! Contribute to yogthos/migratus development by creating an account on GitHub.
- 116Clojure on Exercism
http://exercism.io/languages/clojure
Get fluent in Clojure by solving 88 exercises. And then level up with mentoring from our world-class team.
- 117A library designed to generate cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets.
https://github.com/lk-geimfari/secrets.clj
A library designed to generate cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets. - lk-geimfari/secr...
- 118A Leiningen plugin designed to tell you your code is bad, and that you should feel bad
https://github.com/dakrone/lein-bikeshed
A Leiningen plugin designed to tell you your code is bad, and that you should feel bad - dakrone/lein-bikeshed
- 119Terminal UI library for Clojure
https://github.com/lambdaisland/trikl
Terminal UI library for Clojure. Contribute to lambdaisland/trikl development by creating an account on GitHub.
- 120Basic REPL breakpoints.
https://github.com/technomancy/limit-break
Basic REPL breakpoints. Contribute to technomancy/limit-break development by creating an account on GitHub.
- 121Multilingual library to easily parse date strings to java.util.Date objects.
https://github.com/tokenmill/timewords
Multilingual library to easily parse date strings to java.util.Date objects. - tokenmill/timewords
- 122Bidirectional Ring router. REST oriented. Rails inspired.
https://github.com/darkleaf/router
Bidirectional Ring router. REST oriented. Rails inspired. - darkleaf/router
- 123A Clojurey wrapper around the Lanterna terminal output library.
https://github.com/MultiMUD/clojure-lanterna
A Clojurey wrapper around the Lanterna terminal output library. - MultiMUD/clojure-lanterna
- 124Emacs minor mode that keeps your code always indented. More reliable than electric-indent-mode.
https://github.com/Malabarba/aggressive-indent-mode
Emacs minor mode that keeps your code always indented. More reliable than electric-indent-mode. - Malabarba/aggressive-indent-mode
- 125Write Java inside Clojure
https://github.com/tailrecursion/javastar
Write Java inside Clojure. Contribute to tailrecursion/javastar development by creating an account on GitHub.
- 126A clojure(script) unit testing framework designed to be used from the REPL
https://github.com/amokfa/datest
A clojure(script) unit testing framework designed to be used from the REPL - amokfa/datest
- 127A macro to define clojure functions with parameter pattern matching just like erlang or elixir.
https://github.com/killme2008/defun
A macro to define clojure functions with parameter pattern matching just like erlang or elixir. - killme2008/defun
- 128Managed lifecycle of stateful objects in Clojure
https://github.com/stuartsierra/component
Managed lifecycle of stateful objects in Clojure. Contribute to stuartsierra/component development by creating an account on GitHub.
- 1291.3 update of clojure.contrib.trace
https://github.com/clojure/tools.trace
1.3 update of clojure.contrib.trace. Contribute to clojure/tools.trace development by creating an account on GitHub.
- 130Small library for using neural networks and core.matrix
https://github.com/gigasquid/k9
Small library for using neural networks and core.matrix - gigasquid/k9
- 131A Vim plugin for Clojure's Eastwood linter
https://github.com/venantius/vim-eastwood
A Vim plugin for Clojure's Eastwood linter. Contribute to venantius/vim-eastwood development by creating an account on GitHub.
- 132Clojure & ClojureScript Language Server (LSP) implementation
https://github.com/clojure-lsp/clojure-lsp
Clojure & ClojureScript Language Server (LSP) implementation - clojure-lsp/clojure-lsp
- 133Application state management made simple: a Clojure map that implements java.io.Closeable.
https://github.com/piotr-yuxuan/closeable-map
Application state management made simple: a Clojure map that implements java.io.Closeable. - piotr-yuxuan/closeable-map
- 134A simple validation library for Clojure and ClojureScript
https://github.com/markwoodhall/clova
A simple validation library for Clojure and ClojureScript - markwoodhall/clova
- 135A classy high-level Clojure library for defining application models and retrieving them from a DB
https://github.com/metabase/toucan
A classy high-level Clojure library for defining application models and retrieving them from a DB - metabase/toucan
- 136Build software better, together
https://github.com/hellonico/origami:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 137Fast Clojure Matrix Library
https://github.com/uncomplicate/neanderthal
Fast Clojure Matrix Library. Contribute to uncomplicate/neanderthal development by creating an account on GitHub.
- 138A fast clojure console library
https://github.com/aaron-santos/zaffre
A fast clojure console library. Contribute to kelsey-sorrels/zaffre development by creating an account on GitHub.
- 139Light structure and support for dependency injection
https://github.com/juxt/clip
Light structure and support for dependency injection - juxt/clip
- 140A DSL in Clojure for SQL query, DML, and DDL. Supports a majority of MySQL's statements.
https://github.com/stch-library/sql
A DSL in Clojure for SQL query, DML, and DDL. Supports a majority of MySQL's statements. - stch-library/sql
- 141Enhanced try and throw for Clojure leveraging Clojure's capabilities
https://github.com/scgilardi/slingshot
Enhanced try and throw for Clojure leveraging Clojure's capabilities - scgilardi/slingshot
- 142Clojure wrapper for the Tesseract OCR software
https://github.com/antoniogarrote/clj-tesseract
Clojure wrapper for the Tesseract OCR software. Contribute to antoniogarrote/clj-tesseract development by creating an account on GitHub.
- 143inference and machine learning in clojure
https://github.com/aria42/infer
inference and machine learning in clojure. Contribute to aria42/infer development by creating an account on GitHub.
- 144Automatic PostgreSQL CRUD queries
https://github.com/tatut/specql/
Automatic PostgreSQL CRUD queries. Contribute to tatut/specql development by creating an account on GitHub.
- 145A Leiningen plugin for a superior development environment
https://github.com/venantius/ultra
A Leiningen plugin for a superior development environment - venantius/ultra
- 146SWANK and nREPL servers for clojure providing JPDA based debuggers
https://github.com/pallet/ritz
SWANK and nREPL servers for clojure providing JPDA based debuggers - pallet/ritz
- 147bifurcan/test/bifurcan at master · lacuna/bifurcan
https://github.com/lacuna/bifurcan/blob/master/test/bifurcan
functional, durable data structures. Contribute to lacuna/bifurcan development by creating an account on GitHub.
- 148Trace-oriented debugging tools for Clojure
https://github.com/dgrnbrg/spyscope
Trace-oriented debugging tools for Clojure. Contribute to dgrnbrg/spyscope development by creating an account on GitHub.
- 149A compatibility layer for event-driven abstractions
https://github.com/ztellman/manifold
A compatibility layer for event-driven abstractions - clj-commons/manifold
- 150An HTTP client for Clojure, wrapping JDK 11's HttpClient
https://github.com/gnarroway/hato
An HTTP client for Clojure, wrapping JDK 11's HttpClient - gnarroway/hato
- 151A small machine learning library written in Lisp (Clojure) aimed at providing simple, concise implementations of machine learning techniques and utilities.
https://github.com/cloudkj/lambda-ml
A small machine learning library written in Lisp (Clojure) aimed at providing simple, concise implementations of machine learning techniques and utilities. - cloudkj/lambda-ml
- 152code-walking without caveats
https://github.com/ztellman/riddley
code-walking without caveats. Contribute to ztellman/riddley development by creating an account on GitHub.
- 153A better IDE integration story for Clojure
https://github.com/dgrnbrg/redl
A better IDE integration story for Clojure. Contribute to dgrnbrg/redl development by creating an account on GitHub.
- 154Machine Learning in Clojure
https://github.com/rinuboney/clatern
Machine Learning in Clojure. Contribute to rinuboney/clatern development by creating an account on GitHub.
- 155Sweet web apis with Compojure & Swagger
https://github.com/metosin/compojure-api
Sweet web apis with Compojure & Swagger. Contribute to metosin/compojure-api development by creating an account on GitHub.
- 156Suite of tools for deploying and training deep learning models using the JVM. Highlights include model import for keras, tensorflow, and onnx/pytorch, a modular and tiny c++ library for running math code and a java based math library on top of the core c++ library. Also includes samediff: a pytorch/tensorflow like library for running deep learn...
https://github.com/deeplearning4j/deeplearning4j
Suite of tools for deploying and training deep learning models using the JVM. Highlights include model import for keras, tensorflow, and onnx/pytorch, a modular and tiny c++ library for running mat...
- 157Exception net
https://github.com/mpenet/ex
Exception net. Contribute to mpenet/ex development by creating an account on GitHub.
- 158Minimalistic statistics library for Clojure
https://github.com/clojurewerkz/statistiker
Minimalistic statistics library for Clojure. Contribute to clojurewerkz/statistiker development by creating an account on GitHub.
- 159Generate Graphviz diagrams from FSM data
https://github.com/jebberjeb/fsmviz
Generate Graphviz diagrams from FSM data. Contribute to jebberjeb/fsmviz development by creating an account on GitHub.
- 160A minimalist's unit testing framework ("classic" version)
https://github.com/clojure-expectations/expectations
A minimalist's unit testing framework ("classic" version) - clojure-expectations/expectations
- 161High-performance Bayesian Data Analysis on the GPU in Clojure
https://github.com/uncomplicate/bayadera
High-performance Bayesian Data Analysis on the GPU in Clojure - uncomplicate/bayadera
- 162A Clojure library designed to provide hassle-free, ready to go gRPC experience without ton of preparations and Java code.
https://github.com/otwieracz/clj-grpc
A Clojure library designed to provide hassle-free, ready to go gRPC experience without ton of preparations and Java code. - otwieracz/clj-grpc
- 163Awesome print: like clojure.pprint, but awesome
https://github.com/razum2um/aprint
Awesome print: like clojure.pprint, but awesome. Contribute to razum2um/aprint development by creating an account on GitHub.
- 164Visualize Clojure zippers using Graphviz
https://github.com/lambdaisland/zipper-viz
Visualize Clojure zippers using Graphviz. Contribute to lambdaisland/zipper-viz development by creating an account on GitHub.
- 165A fast, immutable, distributed & compositional Datalog engine for everyone.
https://github.com/replikativ/datahike
A fast, immutable, distributed & compositional Datalog engine for everyone. - GitHub - replikativ/datahike: A fast, immutable, distributed & compositional Datalog engine for everyone.
- 166Clojure-based, R-like statistical computing and graphics environment for the JVM
https://github.com/incanter/incanter
Clojure-based, R-like statistical computing and graphics environment for the JVM - incanter/incanter
- 167simple graph and tree visualization
https://github.com/ztellman/rhizome
simple graph and tree visualization. Contribute to ztellman/rhizome development by creating an account on GitHub.
- 168A Vim plugin for cljfmt, the Clojure formatting tool.
https://github.com/venantius/vim-cljfmt
A Vim plugin for cljfmt, the Clojure formatting tool. - venantius/vim-cljfmt
- 169Micro-framework for data-driven architecture
https://github.com/weavejester/integrant
Micro-framework for data-driven architecture. Contribute to weavejester/integrant development by creating an account on GitHub.
- 170Immutable database and Datalog query engine for Clojure, ClojureScript and JS
https://github.com/tonsky/datascript
Immutable database and Datalog query engine for Clojure, ClojureScript and JS - tonsky/datascript
- 171Clojure wrapper for Encog (v3) (Machine-Learning framework that specialises in neural-nets)
https://github.com/jimpil/enclog
Clojure wrapper for Encog (v3) (Machine-Learning framework that specialises in neural-nets) - jimpil/enclog
- 172A Parser Combinators Library for Clojure
https://github.com/blancas/kern
A Parser Combinators Library for Clojure. Contribute to blancas/kern development by creating an account on GitHub.
- 173An idiomatic clojure http client wrapping the apache client. Officially supported version.
https://github.com/dakrone/clj-http
An idiomatic clojure http client wrapping the apache client. Officially supported version. - dakrone/clj-http
- 174Utility library for writing microservices in Clojure, with support for Swagger and OAuth
https://github.com/zalando/friboo
Utility library for writing microservices in Clojure, with support for Swagger and OAuth - zalando/friboo
- 175A Clojure & ClojureScript DSL for SQL
https://github.com/r0man/sqlingvo
A Clojure & ClojureScript DSL for SQL. Contribute to r0man/sqlingvo development by creating an account on GitHub.
- 176Generate images from Graphviz dot strings in Clojure and Clojurescript
https://github.com/jebberjeb/viz.cljc
Generate images from Graphviz dot strings in Clojure and Clojurescript - jebberjeb/viz.cljc
- 177ClojureCL is a Clojure library for parallel computations with OpenCL.
https://github.com/uncomplicate/clojurecl
ClojureCL is a Clojure library for parallel computations with OpenCL. - uncomplicate/clojurecl
- 178arohner/spectrum
https://github.com/arohner/spectrum
Contribute to arohner/spectrum development by creating an account on GitHub.
- 179A machine learning library for Clojure built on top of Weka and friends
https://github.com/antoniogarrote/clj-ml
A machine learning library for Clojure built on top of Weka and friends - antoniogarrote/clj-ml
- 180Clojure library for debugging core functions
https://github.com/AppsFlyer/mate-clj
Clojure library for debugging core functions. Contribute to AppsFlyer/mate-clj development by creating an account on GitHub.
- 181A Clojure DSL for Apache Spark
https://github.com/yieldbot/flambo
A Clojure DSL for Apache Spark. Contribute to sorenmacbeth/flambo development by creating an account on GitHub.
- 182An extremely light layer over TensorFlow's Java api
https://github.com/kieranbrowne/clojure-tensorflow
An extremely light layer over TensorFlow's Java api - kieranbrowne/clojure-tensorflow
- 183Neural Networks in Clojure
https://github.com/japonophile/synaptic
Neural Networks in Clojure. Contribute to japonophile/synaptic development by creating an account on GitHub.
- 184Clojure test coverage tool
https://github.com/cloverage/cloverage
Clojure test coverage tool. Contribute to cloverage/cloverage development by creating an account on GitHub.
- 185Interactive evaluation for Neovim (Clojure, Fennel, Janet, Racket, Hy, MIT Scheme, Guile, Python and more!)
https://github.com/Olical/conjure
Interactive evaluation for Neovim (Clojure, Fennel, Janet, Racket, Hy, MIT Scheme, Guile, Python and more!) - Olical/conjure
- 186A nice little wrapper around java.util.zip.* using streams
https://github.com/AeroNotix/swindon
A nice little wrapper around java.util.zip.* using streams - AeroNotix/swindon
- 187A Clojure 3D Game Engine (Wrapper), Powered by jMonkeyEngine
https://github.com/ertugrulcetin/jme-clj
A Clojure 3D Game Engine (Wrapper), Powered by jMonkeyEngine - ertugrulcetin/jme-clj
- 188Clojure documentation tool
https://github.com/weavejester/codox
Clojure documentation tool. Contribute to weavejester/codox development by creating an account on GitHub.
- 189A Leiningen plugin for finding dead code
https://github.com/venantius/yagni
A Leiningen plugin for finding dead code. Contribute to venantius/yagni development by creating an account on GitHub.
- 190Dynamic Tensor Graph library in Clojure (think PyTorch, DynNet, etc.)
https://github.com/aria42/flare
Dynamic Tensor Graph library in Clojure (think PyTorch, DynNet, etc.) - aria42/flare
- 191salve.vim: static support for Leiningen and Boot
https://github.com/tpope/vim-salve
salve.vim: static support for Leiningen and Boot. Contribute to tpope/vim-salve development by creating an account on GitHub.
- 192Clojure Katas inspired by Alice in Wonderland
https://github.com/gigasquid/wonderland-clojure-katas
Clojure Katas inspired by Alice in Wonderland. Contribute to gigasquid/wonderland-clojure-katas development by creating an account on GitHub.
- 193a library to define a continuous delivery pipeline in code
https://github.com/flosell/lambdacd
a library to define a continuous delivery pipeline in code - flosell/lambdacd
- 194Efficient, hassle-free function call validation with a concise inline syntax for clojure.spec and Malli
https://github.com/fulcrologic/guardrails
Efficient, hassle-free function call validation with a concise inline syntax for clojure.spec and Malli - fulcrologic/guardrails
- 195Java 8 Date-Time API for Clojure
https://github.com/dm3/clojure.java-time
Java 8 Date-Time API for Clojure. Contribute to dm3/clojure.java-time development by creating an account on GitHub.
- 196Minor mode for Emacs that deals with parens pairs and tries to be smart about it.
https://github.com/Fuco1/smartparens
Minor mode for Emacs that deals with parens pairs and tries to be smart about it. - Fuco1/smartparens
- 197Clojure library for CUDA development
https://github.com/uncomplicate/clojurecuda
Clojure library for CUDA development. Contribute to uncomplicate/clojurecuda development by creating an account on GitHub.
- 198Utility library for Clojure and ClojureScript
https://github.com/ertugrulcetin/kezban
Utility library for Clojure and ClojureScript. Contribute to ertugrulcetin/kezban development by creating an account on GitHub.
- 199Flexible retries library for Clojure
https://github.com/grammarly/perseverance
Flexible retries library for Clojure. Contribute to grammarly/perseverance development by creating an account on GitHub.
- 200Machine learning in Clojure
https://github.com/originrose/cortex
Machine learning in Clojure. Contribute to originrose/cortex development by creating an account on GitHub.
- 201Integration testing framework using a state monad in the backend for building and composing flows
https://github.com/nubank/state-flow
Integration testing framework using a state monad in the backend for building and composing flows - nubank/state-flow
- 202A debugger for Clojure and ClojureScript with some unique features.
https://github.com/flow-storm/flow-storm-debugger
A debugger for Clojure and ClojureScript with some unique features. - flow-storm/flow-storm-debugger
- 203Deprecated in favor of https://github.com/facebook/duckling
https://github.com/wit-ai/duckling
Deprecated in favor of https://github.com/facebook/duckling - facebookarchive/duckling_old
- 204Realtime web comms library for Clojure/Script
https://github.com/ptaoussanis/sente
Realtime web comms library for Clojure/Script. Contribute to taoensso/sente development by creating an account on GitHub.
- 205Hiccup-style generation of Graphviz graphs in Clojure
https://github.com/daveray/dorothy
Hiccup-style generation of Graphviz graphs in Clojure - daveray/dorothy
- 206A Clojure machine learning library
https://github.com/scicloj/scicloj.ml
A Clojure machine learning library. Contribute to scicloj/scicloj.ml development by creating an account on GitHub.
- 207Clojure Interactive Development Environment for Vim8/Neovim
https://github.com/liquidz/vim-iced
Clojure Interactive Development Environment for Vim8/Neovim - liquidz/vim-iced
- 208Distributed, masterless, high performance, fault tolerant data processing
https://github.com/onyx-platform/onyx
Distributed, masterless, high performance, fault tolerant data processing - onyx-platform/onyx
- 209There's a function for that!
https://github.com/jonase/kibit
There's a function for that! Contribute to clj-commons/kibit development by creating an account on GitHub.
- 210A rules engine for Clojure(Script)
https://github.com/oakes/odoyle-rules
A rules engine for Clojure(Script). Contribute to oakes/odoyle-rules development by creating an account on GitHub.
- 211Graph library for Clojure. Mailing list https://groups.google.com/forum/#!forum/loom-clj
https://github.com/aysylu/loom
Graph library for Clojure. Mailing list https://groups.google.com/forum/#!forum/loom-clj - aysylu/loom
- 212Bidirectional, data-driven RSS/Atom feed consumer, producer and feeds aggregator
https://github.com/alekseysotnikov/buran
Bidirectional, data-driven RSS/Atom feed consumer, producer and feeds aggregator - alekseysotnikov/buran
- 213Compact pretty printer
https://github.com/cgrand/packed-printer
Compact pretty printer. Contribute to cgrand/packed-printer development by creating an account on GitHub.
- 214The missing tool
https://github.com/razum2um/clj-debugger
The missing tool. Contribute to razum2um/clj-debugger development by creating an account on GitHub.
- 215Emacs rainbow delimiters mode
https://github.com/Fanael/rainbow-delimiters
Emacs rainbow delimiters mode. Contribute to Fanael/rainbow-delimiters development by creating an account on GitHub.
- 216Slamhound rips your namespace form apart and reconstructs it.
https://github.com/technomancy/slamhound
Slamhound rips your namespace form apart and reconstructs it. - technomancy/slamhound
- 217Sunsetting Atom
https://atom.io/packages/proto-repl
We are archiving Atom and all projects under the Atom organization for an official sunset on December 15, 2022.
- 218managing Clojure and ClojureScript app state since (reset)
https://github.com/tolitius/mount
managing Clojure and ClojureScript app state since (reset) - tolitius/mount
- 219Static analyzer and linter for Clojure code that sparks joy
https://github.com/borkdude/clj-kondo
Static analyzer and linter for Clojure code that sparks joy - clj-kondo/clj-kondo
- 220Erlang-style supervisor error handling for Clojure
https://github.com/MichaelDrogalis/dire
Erlang-style supervisor error handling for Clojure - MichaelDrogalis/dire
- 221Clojure & ClojureScript Interactive Programming for VS Code
https://github.com/BetterThanTomorrow/calva
Clojure & ClojureScript Interactive Programming for VS Code - BetterThanTomorrow/calva
- 222Better exception reporting middleware for Ring.
https://github.com/magnars/prone
Better exception reporting middleware for Ring. Contribute to magnars/prone development by creating an account on GitHub.
- 223Beagle helps you identify keywords, phrases, regexes, and complex search queries of interest in streams of text documents.
https://github.com/tokenmill/beagle
Beagle helps you identify keywords, phrases, regexes, and complex search queries of interest in streams of text documents. - tokenmill/beagle
- 224Build software better, together
https://github.com/uncomplicate/bayadera:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 225A Clojure and ClojureScript game library
https://github.com/oakes/play-cljc
A Clojure and ClojureScript game library. Contribute to oakes/play-cljc development by creating an account on GitHub.
- 226A Clojure library for Apache Spark: fast, fully-features, and developer friendly
https://github.com/gorillalabs/sparkling
A Clojure library for Apache Spark: fast, fully-features, and developer friendly - GitHub - gorillalabs/sparkling: A Clojure library for Apache Spark: fast, fully-features, and developer friendly
- 227A library designed to bridge the gap between the triad of CLJ/CLJS, web-sockets and core.async.
https://github.com/jarohen/chord
A library designed to bridge the gap between the triad of CLJ/CLJS, web-sockets and core.async. - jarohen/chord
- 228Streaming Histograms for Clojure/Java
https://github.com/bigmlcom/histogram
Streaming Histograms for Clojure/Java. Contribute to bigmlcom/histogram development by creating an account on GitHub.
- 229some ideas which are almost good
https://github.com/ztellman/potemkin
some ideas which are almost good. Contribute to clj-commons/potemkin development by creating an account on GitHub.
- 230The Automagic Project Planner
https://github.com/turbopape/milestones
The Automagic Project Planner. Contribute to turbopape/milestones development by creating an account on GitHub.
- 231Bash-like shell based on Clojure
https://github.com/dundalek/closh
Bash-like shell based on Clojure. Contribute to dundalek/closh development by creating an account on GitHub.
- 232Configuration powertool with `metosin/malli`
https://github.com/piotr-yuxuan/malli-cli
Configuration powertool with `metosin/malli`. Contribute to piotr-yuxuan/malli-cli development by creating an account on GitHub.
- 233Fast, Clojure-based rule engine
https://github.com/yipeeio/arete
Fast, Clojure-based rule engine. Contribute to yipeeio/arete development by creating an account on GitHub.
- 234Practice Clojure using Interactive Programming in your editor
https://github.com/PEZ/rich4clojure
Practice Clojure using Interactive Programming in your editor - PEZ/rich4clojure
- 235Full featured next gen Clojure test runner
https://github.com/lambdaisland/kaocha
Full featured next gen Clojure test runner. Contribute to lambdaisland/kaocha development by creating an account on GitHub.
- 236Redis client + message queue for Clojure
https://github.com/ptaoussanis/carmine
Redis client + message queue for Clojure. Contribute to taoensso/carmine development by creating an account on GitHub.
- 237A validation DSL for Clojure & Clojurescript applications
https://github.com/leonardoborges/bouncer
A validation DSL for Clojure & Clojurescript applications - theleoborges/bouncer
- 238Ultra-lightweight literate programming for clojure inspired by docco
https://github.com/gdeer81/marginalia
Ultra-lightweight literate programming for clojure inspired by docco - clj-commons/marginalia
- 239Natural Language Processing in Clojure (opennlp)
https://github.com/dakrone/clojure-opennlp
Natural Language Processing in Clojure (opennlp). Contribute to dakrone/clojure-opennlp development by creating an account on GitHub.
- 240Library for helping print things prettily, in Clojure - ANSI fonts, formatted exceptions
https://github.com/AvisoNovate/pretty
Library for helping print things prettily, in Clojure - ANSI fonts, formatted exceptions - clj-commons/pretty
- 241A fast, Django inspired template system in Clojure.
https://github.com/yogthos/Selmer
A fast, Django inspired template system in Clojure. - yogthos/Selmer
- 242Engelberg/instaparse
https://github.com/Engelberg/instaparse
Contribute to Engelberg/instaparse development by creating an account on GitHub.
- 243Grep-like utility based on Lucene Monitor compiled with GraalVM native-image
https://github.com/dainiusjocas/lucene-grep
Grep-like utility based on Lucene Monitor compiled with GraalVM native-image - dainiusjocas/lucene-grep
- 244Server-side application framework for Clojure
https://github.com/weavejester/duct
Server-side application framework for Clojure. Contribute to duct-framework/duct development by creating an account on GitHub.
- 245Recompile Java code without restarting the REPL
https://github.com/ztellman/virgil
Recompile Java code without restarting the REPL. Contribute to clj-commons/virgil development by creating an account on GitHub.
- 246Figwheel builds your ClojureScript code and hot loads it into the browser as you are coding!
https://github.com/bhauman/lein-figwheel
Figwheel builds your ClojureScript code and hot loads it into the browser as you are coding! - bhauman/lein-figwheel
- 247Seesaw turns the Horror of Swing into a friendly, well-documented, Clojure library
https://github.com/daveray/seesaw
Seesaw turns the Horror of Swing into a friendly, well-documented, Clojure library - clj-commons/seesaw
- 248Forward-chaining rules in Clojure(Script)
https://github.com/cerner/clara-rules
Forward-chaining rules in Clojure(Script). Contribute to oracle-samples/clara-rules development by creating an account on GitHub.
- 249Asynchronous streaming communication for Clojure - web server, web client, and raw TCP/UDP
https://github.com/ztellman/aleph
Asynchronous streaming communication for Clojure - web server, web client, and raw TCP/UDP - clj-commons/aleph
- 250Pattern matching for the monads in the cats Clojure library
https://github.com/zalando/cats.match
Pattern matching for the monads in the cats Clojure library - zalando-stups/cats.match
- 251yetanalytics/dl4clj
https://github.com/yetanalytics/dl4clj
Contribute to yetanalytics/dl4clj development by creating an account on GitHub.
- 252Pure Clojure Webdriver protocol implementation
https://github.com/igrishaev/etaoin
Pure Clojure Webdriver protocol implementation. Contribute to clj-commons/etaoin development by creating an account on GitHub.
- 253Build software better, together
https://github.com/uncomplicate/neanderthal:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 254Build software better, together
https://github.com/linpengcheng/ClojureBoxNpp:
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 255Turn Clojure data structures into SQL
https://github.com/jkk/honeysql
Turn Clojure data structures into SQL. Contribute to seancorfield/honeysql development by creating an account on GitHub.
- 256Clojure lint tool
https://github.com/jonase/eastwood
Clojure lint tool. Contribute to jonase/eastwood development by creating an account on GitHub.
- 257High-performance data-driven data specification library for Clojure/Script.
https://github.com/metosin/malli
High-performance data-driven data specification library for Clojure/Script. - metosin/malli
- 258A community coding style guide for the Clojure programming language
https://github.com/bbatsov/clojure-style-guide
A community coding style guide for the Clojure programming language - bbatsov/clojure-style-guide
Related Articlesto learn about angular.
- 1Clojure for Beginners: A Functional Approach to Programming
- 2Understanding Clojure's Lisp Syntax
- 3Building a Simple Web App: Web Development in Clojure
- 4Full-Stack Development with Clojure and ClojureScript
- 5Data Manipulation in Clojure using Sequences and Collections
- 6Integrating Clojure with Databases: A Guide to Datomic and JDBC
- 7Concurrency in Clojure: Working with Atoms, Refs, and Agents
- 8Parallelism in Clojure: core.async and Futures
- 9Clojure Macros: Writing Code That Writes Code
- 10Building a Real-Time Application with Clojure: A WebSocket-Based Chat App
FAQ'sto learn more about Angular JS.
mail [email protected] to add more queries here 🔍.
- 1
why clojure is used
- 2
why learn clojure
- 3
where is clojure used
- 4
is clojure a functional programming language
- 5
who uses clojure programming language
- 6
is clojurescript dead
- 7
what is clojure used for
- 8
who uses clojure
- 9
who programmed programming
- 10
is clojure fast
- 11
is clojure dying
- 12
who developed cobol programming language
- 13
how to learn clojure
- 14
what is clojure
- 15
what is clojure programming language
- 16
is clojure hard to learn
- 17
how popular is clojure
- 18
how to run clojure
- 19
when to use clojure
- 20
is clojure slow
- 21
which companies use clojure
- 22
do clojure used today
- 23
why use clojure
- 24
why is clojure not popular
- 25
is clojure a lisp
- 26
what is clojure language
- 27
when clojure made
- 28
why is clojure so highly paid
- 29
who created cobol programming language
- 30
is clojure worth learning
- 31
why to learn and use clojure
- 32
is clojure dead
More Sitesto check out once you're finished browsing here.
https://www.0x3d.site/
0x3d is designed for aggregating information.
https://nodejs.0x3d.site/
NodeJS Online Directory
https://cross-platform.0x3d.site/
Cross Platform Online Directory
https://open-source.0x3d.site/
Open Source Online Directory
https://analytics.0x3d.site/
Analytics Online Directory
https://javascript.0x3d.site/
JavaScript Online Directory
https://golang.0x3d.site/
GoLang Online Directory
https://python.0x3d.site/
Python Online Directory
https://swift.0x3d.site/
Swift Online Directory
https://rust.0x3d.site/
Rust Online Directory
https://scala.0x3d.site/
Scala Online Directory
https://ruby.0x3d.site/
Ruby Online Directory
https://clojure.0x3d.site/
Clojure Online Directory
https://elixir.0x3d.site/
Elixir Online Directory
https://elm.0x3d.site/
Elm Online Directory
https://lua.0x3d.site/
Lua Online Directory
https://c-programming.0x3d.site/
C Programming Online Directory
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
https://r-programming.0x3d.site/
R Programming Online Directory
https://perl.0x3d.site/
Perl Online Directory
https://java.0x3d.site/
Java Online Directory
https://kotlin.0x3d.site/
Kotlin Online Directory
https://php.0x3d.site/
PHP Online Directory
https://react.0x3d.site/
React JS Online Directory
https://angular.0x3d.site/
Angular JS Online Directory