2014-02-22 18:30:11 +00:00
**[API docs][]** | ** [CHANGELOG][]** | [other Clojure libs][] | [Twitter][] | [contact/contributing ](#contact--contributing ) | current ([semantic][]) version:
2012-07-01 17:13:32 +00:00
2012-07-06 12:53:02 +00:00
```clojure
2013-12-06 18:55:00 +00:00
[com.taoensso/nippy "2.5.2"] ; Stable
2014-02-23 18:42:25 +00:00
[com.taoensso/nippy "2.6.0-beta1"] ; For early adopters
2012-07-06 12:53:02 +00:00
```
2014-01-22 10:02:34 +00:00
v2.6 will be a backwards-compatible release with: improved performance (incl. frozen data size), a new low-level DataInput/DataOuput API, improved support for headerless freezing, and 1-to-1 binary-value representation guarantees. See the [Changelog ](https://github.com/ptaoussanis/nippy/blob/master/CHANGELOG.md ) for details.
2012-11-04 16:31:57 +00:00
# Nippy, a Clojure serialization library
2012-07-06 12:53:02 +00:00
Clojure's [rich data types ](http://clojure.org/datatypes ) are *awesome* . And its [reader ](http://clojure.org/reader ) allows you to take your data just about anywhere. But the reader can be painfully slow when you've got a lot of data to crunch (like when you're serializing to a database).
2013-06-14 11:59:07 +00:00
Nippy is an attempt to provide a reliable, high-performance **drop-in alternative to the reader** . It's used, among others, as the [Carmine Redis client ](https://github.com/ptaoussanis/carmine ) and [Faraday DynamoDB client ](https://github.com/ptaoussanis/faraday ) serializer.
2012-07-06 12:53:02 +00:00
2013-06-01 12:14:21 +00:00
## What's in the box™?
* Small, uncomplicated **all-Clojure** library.
* **Great performance**.
2013-07-29 08:59:24 +00:00
* Comprehesive **support for all standard data types** .
* **Easily extendable to custom data types**. (v2.1+)
2013-10-24 07:01:35 +00:00
* Java's **Serializable** fallback when available. (v2.5+)
2013-07-29 08:59:24 +00:00
* **Reader-fallback** for all other types (including Clojure 1.4+ tagged literals).
2013-06-01 12:14:21 +00:00
* **Full test coverage** for every supported type.
2013-06-13 04:54:08 +00:00
* Fully pluggable **compression** , including built-in high-performance [Snappy ](http://code.google.com/p/snappy/ ) compressor.
2013-06-17 14:59:52 +00:00
* Fully pluggable **encryption** , including built-in high-strength AES128 enabled with a single `:password [:salted "my-password"]` option. (v2+)
* Utils for **easy integration into 3rd-party tools/libraries** . (v2+)
2012-07-06 12:53:02 +00:00
2013-10-17 10:55:44 +00:00
## Optional plugins
2013-10-19 08:37:10 +00:00
* [LZ4 compressor ](https://github.com/mpenet/nippy-lz4 ) by [mpenet ](https://github.com/mpenet ) (v2+).
2013-10-17 10:55:44 +00:00
2013-06-01 12:14:21 +00:00
## Getting started
2012-07-06 12:53:02 +00:00
2013-06-01 12:14:21 +00:00
### Dependencies
2012-07-06 12:53:02 +00:00
2014-02-22 18:30:11 +00:00
Add the necessary dependency to your [Leiningen][] `project.clj` and `require` the library in your ns:
2012-07-06 12:53:02 +00:00
```clojure
2013-12-06 18:55:00 +00:00
[com.taoensso/nippy "2.5.2"] ; project.clj
2013-06-01 12:14:21 +00:00
(ns my-app (:require [taoensso.nippy :as nippy])) ; ns
2012-07-06 12:53:02 +00:00
```
2013-06-01 12:14:21 +00:00
### De/serializing
2012-07-06 12:53:02 +00:00
2012-07-06 19:12:59 +00:00
As an example of what Nippy can do, let's take a look at its own reference stress data:
```clojure
nippy/stress-data
=>
2012-07-07 12:08:42 +00:00
{:bytes (byte-array [(byte 1) (byte 2) (byte 3)])
2012-07-06 19:12:59 +00:00
:nil nil
:boolean true
:char-utf8 \ಬ
:string-utf8 "ಬಾ ಇಲ್ಲಿ ಸಂಭವಿಸ"
:string-long (apply str (range 1000))
:keyword :keyword
2012-07-08 06:00:34 +00:00
:ns-keyword ::keyword
2012-07-06 19:12:59 +00:00
2013-04-14 07:44:06 +00:00
:queue (-> (PersistentQueue/EMPTY) (conj :a :b :c :d :e :f :g))
:queue-empty (PersistentQueue/EMPTY)
:sorted-set (sorted-set 1 2 3 4 5)
:sorted-map (sorted-map :b 2 :a 1 :d 4 :c 3)
2012-07-06 19:12:59 +00:00
:list (list 1 2 3 4 5 (list 6 7 8 (list 9 10)))
:list-quoted '(1 2 3 4 5 (6 7 8 (9 10)))
:list-empty (list)
:vector [1 2 3 4 5 [6 7 8 [9 10]]]
:vector-empty []
:map {:a 1 :b 2 :c 3 :d {:e 4 :f {:g 5 :h 6 :i 7}}}
:map-empty {}
:set #{1 2 3 4 5 #{6 7 8 #{9 10}}}
:set-empty #{}
:meta (with-meta {:a :A} {:metakey :metaval})
2013-10-31 06:16:26 +00:00
:lazy-seq (repeatedly 1000 rand)
2012-07-06 19:12:59 +00:00
:byte (byte 16)
:short (short 42)
:integer (int 3)
:long (long 3)
:bigint (bigint 31415926535897932384626433832795)
:float (float 3.14)
:double (double 3.14)
:bigdec (bigdec 3.1415926535897932384626433832795)
2012-07-08 05:49:22 +00:00
:ratio 22/7
2013-10-23 18:53:41 +00:00
:uuid (java.util.UUID/randomUUID)
2013-10-24 06:33:54 +00:00
:date (java.util.Date.)
2013-10-24 06:50:55 +00:00
:stress-record (->StressRecord "data")
;; Serializable
:throwable (Throwable. "Yolo")
:exception (try (/ 1 0) (catch Exception e e))
:ex-info (ex-info "ExInfo" {:data "data"})}
2012-07-06 19:12:59 +00:00
```
Serialize it:
```clojure
2013-06-13 04:54:08 +00:00
(def frozen-stress-data (nippy/freeze nippy/stress-data))
2012-07-06 19:12:59 +00:00
=> #< byte [ ] [ B @ 3253bcf3 >
```
Deserialize it:
```clojure
2013-06-13 04:54:08 +00:00
(nippy/thaw frozen-stress-data)
2012-07-07 12:08:42 +00:00
=> {:bytes (byte-array [(byte 1) (byte 2) (byte 3)])
2012-07-06 19:12:59 +00:00
:nil nil
:boolean true
< ... > }
```
Couldn't be simpler!
2012-07-06 12:53:02 +00:00
2014-01-22 07:14:26 +00:00
See also the lower-level `freeze-to-out!` and `thaw-from-in!` fns for operating on `DataOutput` and `DataInput` types directly.
2013-06-12 08:19:09 +00:00
### Encryption (currently in **ALPHA**)
2013-06-17 14:59:52 +00:00
Nippy v2+ also gives you **dead simple data encryption** . Add a single option to your usual freeze/thaw calls like so:
2013-06-12 08:19:09 +00:00
```clojure
2013-06-13 04:54:08 +00:00
(nippy/freeze nippy/stress-data {:password [:salted "my-password"]}) ; Encrypt
(nippy/thaw < encrypted-data > {:password [:salted "my-password"]}) ; Decrypt
2013-06-12 08:19:09 +00:00
```
2013-06-27 12:29:26 +00:00
There's two default forms of encryption on offer: `:salted` and `:cached` . Each of these makes carefully-chosen trade-offs and is suited to one of two common use cases. See the `aes128-encryptor` [docstring ](http://ptaoussanis.github.io/nippy/taoensso.nippy.encryption.html ) for a detailed explanation of why/when you'd want one or the other.
2013-06-12 08:19:09 +00:00
2013-07-29 08:59:24 +00:00
### Custom types (v2.1+, ALPHA - subject to change)
```clojure
(defrecord MyType [data])
(nippy/extend-freeze MyType 1 ; A unique type id ∈[1, 128]
2014-01-22 07:14:26 +00:00
[x data-output]
(.writeUTF data-output (:data x)))
2013-07-29 08:59:24 +00:00
(nippy/extend-thaw 1 ; Same type id
2014-01-22 07:14:26 +00:00
[data-input]
(->MyType (.readUTF data-input)))
2013-07-29 08:59:24 +00:00
(nippy/thaw (nippy/freeze (->MyType "Joe"))) => #taoensso .nippy.MyType{:data "Joe"}
```
2012-07-06 12:53:02 +00:00
## Performance
2013-06-24 08:16:22 +00:00

2012-07-06 12:53:02 +00:00
[Detailed benchmark information ](https://docs.google.com/spreadsheet/ccc?key=0AuSXb68FH4uhdE5kTTlocGZKSXppWG9sRzA5Y2pMVkE&pli=1#gid=0 ) is available on Google Docs.
2013-07-09 07:48:22 +00:00
## This project supports the CDS and  goals
2013-06-01 12:14:21 +00:00
2014-02-22 18:30:11 +00:00
* [CDS][], the **Clojure Documentation Site** , is a **contributer-friendly** community project aimed at producing top-notch, **beginner-friendly** Clojure tutorials and documentation. Awesome resource.
2013-06-01 12:14:21 +00:00
2014-02-22 18:30:11 +00:00
* [ClojureWerkz][] is a growing collection of open-source, **batteries-included Clojure libraries** that emphasise modern targets, great documentation, and thorough testing. They've got a ton of great stuff, check 'em out!
2013-06-01 12:14:21 +00:00
2013-06-22 10:40:14 +00:00
## Contact & contributing
2012-11-05 17:49:37 +00:00
2014-02-22 18:30:11 +00:00
Please use the project's GitHub [issues page][] for project questions/comments/suggestions/whatever ** (pull requests welcome!)**. Am very open to ideas if you have any!
2012-07-06 12:53:02 +00:00
2014-02-22 18:30:11 +00:00
Otherwise reach me (Peter Taoussanis) at [taoensso.com][] or on [Twitter][]. Cheers!
2012-07-06 12:53:02 +00:00
## License
2014-02-22 18:30:11 +00:00
Copyright © 2012-2014 Peter Taoussanis. Distributed under the [Eclipse Public License][], the same as Clojure.
[API docs]: < http: / / ptaoussanis . github . io / nippy / >
[CHANGELOG]: < https: / / github . com / ptaoussanis / nippy / blob / master / CHANGELOG . md >
[other Clojure libs]: < https: / / www . taoensso . com / clojure-libraries >
[Twitter]: < https: / / twitter . com / ptaoussanis >
[semantic]: < http: / / semver . org / >
[Leiningen]: < http: / / leiningen . org / >
[CDS]: < http: / / clojure-doc . org / >
[ClojureWerkz]: < http: / / clojurewerkz . org / >
[issues page]: < https: / / github . com / ptaoussanis / nippy / issues >
[commit history]: < https: / / github . com / ptaoussanis / nippy / commits / master >
[taoensso.com]: < https: / / www . taoensso . com >
2014-02-23 18:42:25 +00:00
[Eclipse Public License]: < https: / / raw2 . github . com / ptaoussanis / nippy / master / LICENSE >