Skip to content
RDF for Clojure, integrates with Commons RDF, Jena, RDF4J
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Build Status

Clojars Project

This is an early attempt to create Clojure RDF library with bindings for Apache Commons RDF and native Clojure data structures.

Note that this project is currently experimental and may change at any time (or not at all). Please feel free to contribute by raising issues or pull requests!

Similar to Commons RDF, this library focus on creating and inspecting objects corresponding to RDF concepts like triple, graph and IRI, Literal and Blank node; as well as and interoperability between the RDF implementations.

This library does not currently expose more specific features of the underlying RDF frameworks (e.g. SPARQL queries in Apache Jena or a remote repository connection in Eclipse RDF4J), but the way rdf-clj has been implemented with Clojure protocols should mean that it is relatively easy to "mix and match", if needed.


Install using Leiningen

lein install

To run the tests:

lein test

Use from your Leiningen project:

[rdf-clj "0.1.0"]


  • Copyright © 2015-2016 Stian Soiland-Reyes
  • Copyright © 2015-2016 University of Manchester

Distributed under Apache License 2.0. See the file LICENSE for details.



The main functionality of rdf-clj is exposed from the top-level rdf namespace, so many users of this library may only need to require rdf:

(ns example1
  (:require [rdf :refer :all]))

The below shows how to use graph, triple and add-triple:

example1=> (def g (graph))

example1=> (type g)

example1=> (def t (triple (blanknode) (iri "") (literal "Hello world", "en")))

example1=> t
{:subject {:blanknode #uuid "5cb6182d-2791-47f6-9937-89c088490c99"},
 :predicate {:iri ""},
 :object {:literal "Hello world", :language "en"}}

example1=> (def g (add-triple g t))

example1=> g
#{ {:subject {:blanknode #uuid "5cb6182d-2791-47f6-9937-89c088490c99"},
    :predicate {:iri ""},
    :object {:literal "Hello world", :language "en"}} }

example1=> (triple-count g)

example1=> (subject (first g))
{:blanknode #uuid "5cb6182d-2791-47f6-9937-89c088490c99"}

example1=> (blanknode? (subject (first g)))

example1=> (literal-lang (object (first g)))

Analogue to conj, graph modification methods like add-triple return a new, mutated graph; the graph is by default backed by an immutable set. Note that Commons RDF implementations and a transient Clojure colleciton will do direct modifications.

RDF implementions

You can choose which RDF implementation to create instances of by using the with-rdf macro. For instance, to use the Commons RDF Simple implementation:

example1=> (with-rdf :simple
      #_=>   (triple (blanknode) (iri "") (literal "Hello")))
#object[org.apache.commons.rdf.simple.TripleImpl 0x4f6ab4db
  "_:a09268fb-e527-3d15-9087-021d45505fc0 <> \"Hello\" ."]

Currently supported implementations:

Note that for :jena, :rdf4j and :jsonld you will also need to add a dependency for the Commons RDF integration module, for instance for Leiningen, add one of:

[org.apache.commons/commons-rdf-jena "0.3.0-incubating"]
[org.apache.commons/commons-rdf-rdf4j "0.3.0-incubating"]
[org.apache.commons/commons-rdf-jsonld-java "0.3.0-incubating"]

If your application desires to be flexible with which implementations to support, see the rdf.commonsrdf/rdf-impls method, which finds Commons RDF implementations on the classpath using an ServiceLoader approach.


The rdf functionality is implemented through a series of protocols (rdf.protocols), with implementations provided for Commons RDF (rdf.commonsrdf and Clojure seqs (rdf.seq).

The protocol rdf.protocols/RDF defines factory methods like graph, iri and literal. The first argument of these methods is the implementation to use, e.g. an instance of org.apache.commons.rdf.api.RDF or {} to use Clojure maps.

You can’t perform that action at this time.