Liking cljdoc? Tell your friends :D


  • or, or-join, not and not-jon support in queries (#238, #50)


  • Implement on datascript/DB (#281)
  • Drop Clojure 1.7 and 1.8 support
  • Fix externs.js syntax (PR #216, thx @thheller)
  • Support :as in Pull API an attr-with-opts syntax (#270, PR #271, thx @Jumblemuddle)
  • Support idents expansion (PR #245, thx bamarco)
  • JS API correctly handles nested maps with {":db/id"} in transactions (#228, thx @serebrianyi)
  • Calling transaction fns through idents directly (PR #185, thx @refset)


  • AOT artifacts are now deployed with classifiers (0.16.9-aot1.7, 0.16.9-aot1.8, 0.16.9-aot1.9). Main DataScript artifact has no AOTed code (related: #241, #279, #280)



  • Removed references to perf from datascript.query-v3 (closes #272)
  • Fixed compile error under java 11 (PR #273, thx Ryan Belohlavek)


  • Add support for renamed DB functions :db/retractEntity and :db/cas (#265, PR #256, thx Kenny Williams)


  • Provision AOT-compiled classes in datascript.jar (closes #241)
  • Fixed direct-linking compatibility (rolled back #197, fixed #219, closes #259)


  • Support string tempids (#251, PR #252, thx Kenny Williams)
  • Better compatibility with JS / CLJS 1.9.946 (aget, aset on plain objects)
  • Added rseek-datoms (#253, PR #254, thx Jeremy Taylor)
  • Object.equals for entites (PR #255, thx Camilo Roca)


  • Silently skip nils in transaction (was stopping processing without an error before)


  • Fixed compatibility with CLJS 1.9.660 (#233, #236)


  • Fixed rules ignoring false arguments passed to them (#218)


  • Fixed infinite loop in parser on CLJS 1.9.456+ (#210)
  • Added contains? to built-ins (#211)
  • Fixed handling of false values in entity cache (PR #198, thx Brandon Bloom)
  • Fixed issue when string values were interpreted as lookup refs (#214)
  • Speed up rschema calculation (#192, thx Andre R.)
  • Optimize generated JS code by declaring fn arities (#197)
  • [ BREAKING ] Removed ^:exports from datascript.core to enable dead code elimination (#191). This should only affect you if you were using DataScript from JS and were importing datascript.core directly


  • Add vector, hash-map, array-map, list and set to built-in query functions (PR #186, thx Linus Ericsson)
  • When filtering already filtered DB, filters were applied in the wrong order


  • ~30% better performance for predicate and fn calls in queries (see #180)
  • JS API now supports lookup refs in index lookups and queries (see #179)
  • Lookup refs now work with :db.unique/value too (issue #171)


  • Compatibility with 1.9 records (issue #176)
  • Resolve query functions and predicates on JVM (issue #177, PR #178, thx Luke VanderHart)


  • large long entity ids were breaking init-db (issue #165)


  • get-else throws if nil is used for default value
  • JS API: Do not keywordize attribute names in schema (PR #155, issue #153, thx typeetfunc)
  • init-db sets correct max-eid when processing facts about transactions (PR #164, issue #163, thx Nick Alexander)


  • Better error messages for upsert conflicts
  • Backtracking of tempids when redefining them later with upserts (issue #76)
  • Upsert works in vector form too (issue #99, #109)
  • Can specify transaction number in :db/add
  • Can put datoms into transaction directly (issue #121: supports both addition and retration datoms, keeps tx number)
  • Added all datascript.core symbols to externs so they can be called directly from JS (e.g. in combination with mori, issue #139)
  • Added reset-conn, conn-from-datoms and conn-from-db (issue #45)


  • Unify fn binding results with existing relations (PR #138, issue #141, thx Aaron Brooks)
  • [ BREAKING ] get-some returns [attr value] instead of just value (#143, same as Datomic)
  • [ BREAKING ] Returning nil from query function filters out tuple from result
  • Throw when calling unbound predicate/function inside a query (#111)
  • Added several built-ins, including count (#142) and subs (#111)
  • Lookups with nil value ([<attr> nil]) resolve to nil (#140)
  • Allow pull-pattern to be specified with a input variable without ? prefix (#136, #122)
  • Retract functions do not fail if lookup ref is pointing nowhere (#131)
  • Fixed BTSet implementation of IReduceInit (#124)



  • Fixed issue #120 with binding of large collections


  • Guard conn? will check that value is derefable instead of checking for (instance? Atom)


  • [ BREAKING ] Main namespace to include is now datascript.core, not datascript
  • [ BREAKING ] Old datascript.core (internal namespace) was renamed to datascript.db
  • [ BREAKING ] datascript.shim (internal namespace) was renamed to datascript.arrays


  • Usage of top-level namespaces is discouraged and even generates a warning in CLJS.
  • Better sooner than later.
  • 0.13 seems like a great number for this sort of release.

Migration procedure:

  • Just change (require '[datascript :as d]) to (require '[datascript.core :as d]) and you’re good to go.

For the sake of easy migration, there’re no other changes in this release. Just renamings.


  • Fix null pointer exception when contains? is called with an entity (PR #114, thx Kevin Lynagh)


  • db-init respects :db/index property


[ BREAKING ] Introducing new :db/index schema attribute:

  • Attributes are not put to AVET by default anymore

  • Following attributes are put to AVET:

    • :db/index true
    • :db/unique :db.unique/identity
    • :db/unique :db.unique/value
    • :db/valueType :db.type/ref
  • All attributes put to AVET should be comparable. Note: maps and list are not comparable by default, vectors are compared value-by-value

  • [ BREAKING ] Min/max aggregation functions will only work on a comaparable values


  • You can finally store any trash easily and reliably in DataScript database: maps, vectors, functions, JS objects. It doesn’t even have to be comparable. Just do not mark it as :db/index and do not make it :db.cardinality/many
  • Faster transactions. There’s ⅓ less indexes to fill
  • Good defaults. Most cases where you’ll probably use AVET (lookup by value)—lookup refs, external ids, references—they are all indexed by default


  • Your code may break (see below)
  • Queries can do lookup by value event without :db/index attribute, but it’ll be slower

Migration procedure:

  • Check your code for datoms, seek-datoms calls with :avet index, and index-range call
  • Check your queries to see if they utilize AVET index. It happens when you use this pattern: [?free-var <constant-attr> <constant-value>]
  • Mark necessary attributes with :db/index true in the schema


  • msec argument to squuid (#95, #97)
  • lookup refs in JS API pull, pull_many, entity (#94, thx Matt Senior)
  • fix in Pull API for reverse non-component attributes (#91, thx Matt Senior)
  • Node.js and Browser repls for dev profile (#93)
  • Preconditions to validate db/conn arguments (#101)
  • Id allocation bug (#66)


  • Ported BTSet to JVM
  • BTSet and BTSetIter implement ChunkedSeq
  • New benchmark runner

This release brings a significant performance boost for JVM version of DataScript (numbers are in comparison to JS/v8 version):

  • queries with single clause, no join: ~5–6 times faster
  • queries with joins: ~3–4.5 times faster
  • transact: ~3 times faster
  • init-db: ~3–4 times faster
  • rules: ~3-4 times faster


Experimental support for Clojure on JVM:

  • sorted-set instead of BTSet
  • polymorphic get lookup in query
  • no sorting optimisation for init-db

Performance numbers so far (raw data):

  • queries with single clause, no join: 30–50% faster
  • queries with joins: ~50% slower
  • transact: ~3.5–4 times faster
  • init-db: ~2–2.5 times slower
  • rules: ~2–5 times faster
  • db equiv: ~5 times slower
  • db hash: ~10 times slower


  • Fixed UUID constructor warning under CLJS 0.0-3291 and later


  • Support reverse attribute refs in combination with wildcards (issue #80)
  • *.cljc sources do not conflict with Clojure now. Code compiles under [lein-cljsbuild "1.0.6"]


  • Return nil from entity when passed nil eid (issue #75)


  • Fixed init_db in js (issue #73)
  • Preliminary work for Clojure port (PR #70, #71)
  • [ BREAKING ] DS now requires CLJS 0.0-3196 or later


  • New parser for query and rules
  • Added a lot of meaningful error messages and validations to query parser
  • Support for _ (ignore binding) in :in and fn-clause bindings
  • Fixed id allocation bug when nested maps are used for referenced entities (issue #59)
  • Fixed squuids omitting leading zeros (issue #60)
  • Fixed a bug when cross-referencing components caused infinite loop in Pull API (isuue #58, pull request #61)
  • Pull API handles recursion more like Datomic does (issue #62)
  • Exposed DB filter API to js (pull request #65)
  • Added ICounted, ISequable, IEmptyableCollection to datascript.core/DB
  • Force put Datom and DB tag readers to cljs.reader/*tag-table*, do not rely on data_readers.clj


  • Lookup refs can be inlined in query :where patterns (issue #53)
  • Pull API (issue #37, pull request #51) by David Thomas Hume
  • pull form in :find clause


  • :db/unique constraints
  • Upserts
  • Lookup refs
  • entid function


  • Find specifications: collection :find [?e ...], tuple :find [?e ?v], and scalar :find ?e .
  • Support for :db/isComponent (issue #3)
  • Support for nested maps in transact! (also fixes #38)
  • [ BREAKING ] Custom aggregate fns must be called via special syntax (aggregate keyword): (q '[:find (aggregate ?myfn ?e) :in $ ?myfn ...]). Built-in aggregates work as before: (q '[:find (count ?e) ...]
  • Return nil from entity when passed nil eid (issue #47)
  • Transaction data is now validated, with proper error messages (also fixes #48)


  • Fixed a bug with function call after function relation was filtered out (issue #44)


  • Fixed a bug when emtpy coll in input was not creating empty relation


  • BTSet and its slices (returned by datoms/seek-datoms/index-range calls) now support fast reverse iteration via reverse.
  • (datascript/datom e a v & [tx added]) call for creating new datoms
  • Added missing aggregate funs: avg, median, variance, stddev and count-distinct (issue #42, thx @montyxcantsin)
  • min and max aggregates use comparator instead of default js < comparison
  • Fixed a bug when fn inside a query on empty relation returned non-empty result
  • Filtered DB support via filter


  • [ BREAKING ] Entity ids and transaction ids now have to be numbers, attributes can only be keywords (strings if used from JS)
  • New method init-db for fast creation of DB from existing datoms (useful for e.g. initialization from serialized state)
  • Improved performance of transact! (~20%) and initial database population (init-db, db-from-reader, ~800%)


  • Externs provided via deps.cljs — no need to manually specify externs when using datascript dependency


  • Ability to pass inputs (predicates/functions bindings) down to rules (issues #28 #29)


  • Javascript version is now packaged as a proper CommonJS/RequireJS module (include via script tag still supported) (issue #39)
  • Published to npm:
  • [ BREAKING ] Javascript namespace is renamed from datascript.js to datascript


  • Reference transaction id inside transaction by using :db/current-tx instead of entity id (issue #32)
  • You can get id of transaction from TxReport: (get-in tx-report [:tempids :db/current-tx])
  • Ability to pass arbitrary metadata along with transaction (third argument to transact!) and read it in listener callback (:tx-meta key of TxReport) (issue #32)


  • Added :db.fn/cas transaction function (issue #20, thx @montyxcantsin)
  • Added get-some, get-else, misssing? query functions (issue #21, thx @montyxcantsin)
  • Fixed touch breaking entity cache (issue #17)
  • Added ground fn (issue #25)
  • Fixed query predicate/fn calls without free variables
  • Retract incoming entity references on :db.fn/retractEntity (issue #18)
  • You can now use reverse relation name when transacting entity as a map


Cosmetic changes to better mimic Datomic API. Useful for sharing code between Datomic and DataScript:

  • Added tempid, resolve-tempid, db, transact, transact-async, index-range, squuid, squuid-time-millis
  • [ BREAKING ] renamed transact to with, with to db-with


  • Optimized speed of DB’s equiv and hash, Datom’s hash
  • Entity’s touch call accessible through datascript namespace
  • Accept sets in entity maps as values for :db.cardinality/many attributes


Proper entities implementation:

  • Entities are now lazy and implement usual Map protocols
  • [ BREAKING ] When accessing attribute of :db/valueType :db.type/ref, its value will be automatically expanded to entites, allowing for recursive exploration of entities graphs (e.g. (-> (d/entity db 42) :parent :parent :children))
  • Entities support backwards navigation (e.g. (:person/_friends (d/entity db 42)))


  • Externs file now can be referred as :externs [datascript/externs.js"]


Big performance improvements:

  • New B-tree based indexes
  • New set-at-a-time, hash-join powered query and rules engine
  • Queries now up to 10× times faster
  • You can specify DB for rule call (like ($db follows ?e1 ?e2))
  • Datoms are required to have integer id and keyword attributes, but no restriction on types of values


  • Clojure reader support (pr/read) for DB and Datom


  • datoms and seek-datoms API calls
  • referencing other entities’ tempids in transaction data (issue #10)


  • Transactor functions via :db.fn/call (thx @thegeez)
  • Vanilla JS API bindings
  • [ BREAKING ] Schema keywords namespaced on a par with Datomic schema


  • entity added

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close