diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
 
 For a full list of changes, see the history on [GitHub](https://github.com/hapytex/css-selectors).
 
+## Version 0.3.0.0
+
+The css items are now an instance of `Binary` and can be serialized and deserialized; and compressed. One
+can use this to store the css selector to a file. The format is *not* a standardized one: it is just defined
+to store the selector effectively.
+
 ## Version 0.2.1.0
 
 Move from modules from `Css.*` to `Css3.*`, and implementations of `shrink` for the css selectors data types.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -129,6 +129,12 @@
 is often useful, since javascript itself has no syntax for css selectors, and
 often strings are used to represent these.
 
+## `Binary` instances
+
+The css-elements are all a member of the `Binary` typeclass, that converts the
+css selector to a compact binary format. This is *not* standard format. This is
+more to write a css-selector to a binary format and back.
+
 ## `Arbitrary` css selectors
 
 One can generate arbitrary CSS selectors (and their subcomponents). It is
diff --git a/css-selectors.cabal b/css-selectors.cabal
--- a/css-selectors.cabal
+++ b/css-selectors.cabal
@@ -1,5 +1,5 @@
 name:                css-selectors
-version:             0.2.1.0
+version:             0.3.0.0
 synopsis:            Parsing, rendering and manipulating css selectors in Haskell.
 description:
   A library for parsing, manipulating, and rendering css selectors (not css files,
@@ -43,13 +43,16 @@
       base >=4.7 && <5
     , aeson >=1.0 && <2
     , array >=0.5.3.0 && <0.5.4.0
+    , binary >=0.2 && <0.8.8.0
     , blaze-markup >=0.8 && <0.9
+    , bytestring >=0.9
     , data-default >=0.7 && <0.8
     , Decimal >=0.5.1 && <0.5.2
     , QuickCheck >=2.13 && <2.14
     , shakespeare >=2.0 && <3.0
     , template-haskell >=2.12.0 && <2.16.0
     , text >=1.1 && <1.3
+    , zlib >=0.5
   build-tools:
       alex
     , happy
@@ -61,6 +64,7 @@
   main-is:             Spec.hs
   build-depends:
       base
+    , binary >=0.2 && <0.8.8.0
     , css-selectors
     , text
     , test-framework
diff --git a/src/Css3/Selector/Core.hs b/src/Css3/Selector/Core.hs
--- a/src/Css3/Selector/Core.hs
+++ b/src/Css3/Selector/Core.hs
@@ -34,15 +34,21 @@
     , Hash(..), (.#)
     -- * Specificity
     , SelectorSpecificity(..), specificity, specificityValue
+    -- * Read and write binary content
+    , encode, decode, compressEncode, compressEncodeWith, decompressDecode
   ) where
 
 -- based on https://www.w3.org/TR/2018/REC-selectors-3-20181106/#w3cselgrammar
 
+import Codec.Compression.GZip(CompressParams, compress, compressWith, decompress)
+
 import Control.Applicative(liftA2)
 
 import Css3.Selector.Utils(encodeIdentifier, encodeText, toIdentifier)
 
 import Data.Aeson(Value(String), ToJSON(toJSON))
+import Data.Binary(Binary(put, get), Get, Put, decode, encode, getWord8, putWord8)
+import Data.ByteString.Lazy(ByteString)
 import Data.Data(Data)
 import Data.Default(Default(def))
 import Data.Function(on)
@@ -109,6 +115,32 @@
     normalize = id
     {-# MINIMAL toCssSelector, toSelectorGroup, specificity', toPattern #-}
 
+-- | Convert the given item to a compressed 'ByteString'. This can be used to write to and read from a file for example.
+-- The econding format is not an official format: it is constructed based on the structure of the Haskell types. That
+-- stream is then passed through a gzip implementation.
+compressEncode :: (Binary a, ToCssSelector a)
+  => a -- ^ The object to turn into a compressed 'ByteString'.
+  -> ByteString -- ^ A compressed binary representation of the given object.
+compressEncode = compress . encode
+
+-- | Convert the given item to a compressed 'ByteString'. This can be used to write to and read from a file for example.
+-- The econding format is not an official format: it is constructed based on the structure of the Haskell types. That
+-- stream is then passed through a gzip implementation.
+compressEncodeWith :: (Binary a, ToCssSelector a)
+  => CompressParams -- ^ The parameters that determine how to compress the 'ByteString'.
+  -> a -- ^ The object to turn into a compressed 'ByteString'.
+  -> ByteString -- ^ A compressed binary representation of the given object.
+compressEncodeWith level = compressWith level . encode
+
+-- | Convert the given item to a compressed 'ByteString'. This can be used to write to and read from a file for example.
+-- The econding format is not an official format: it is constructed based on the structure of the Haskell types. That
+-- stream is then passed through a gzip implementation.
+decompressDecode :: (Binary a, ToCssSelector a)
+  => ByteString -- ^ A compressed binary representation of a 'ToCssSelector' type.
+  -> a -- ^ The corresponding decompressed and decoded logic.
+decompressDecode = decode . decompress
+
+
 -- | Calculate the specificity of a 'ToCssSelector' type object. This is done by
 -- calculating the 'SelectorSpecificity' object, and then calculating the value
 -- of that object.
@@ -573,6 +605,108 @@
 
 instance Default AttributeCombinator where
     def = Exact
+
+-- Binary instance
+_putEnum :: Enum a => a -> Put
+_putEnum = putWord8 . fromIntegral . fromEnum
+
+_getEnum :: Enum a => Get a
+_getEnum = toEnum . fromIntegral <$> getWord8
+
+instance Binary SelectorSpecificity where
+  put (SelectorSpecificity a b c) = put a >> put b >> put c
+  get = SelectorSpecificity <$> get <*> get <*> get
+
+instance Binary Selector where
+  put (Selector c) = putWord8 0 >> put c
+  put (Combined c sc cs) = putWord8 1 >> put c >> put sc >> put cs
+  get = do
+    w <- getWord8
+    case w of
+      0 -> Selector <$> get
+      1 -> Combined <$> get <*> get <*> get
+      _ -> fail "An error occured while deserializing a Selector object"
+
+instance Binary SelectorCombinator where
+  put = _putEnum
+  get = _getEnum
+
+instance Binary SelectorSequence where
+  put (SimpleSelector ts) = putWord8 0 >> put ts
+  put (Filter ss sf) = putWord8 1 >> put ss >> put sf
+  get = do
+    w <- getWord8
+    case w of
+      0 -> SimpleSelector <$> get
+      1 -> Filter <$> get <*> get
+      _ -> fail "An error occured while deserializing a Selector object."
+
+instance Binary SelectorFilter where
+  put (SHash h) = putWord8 0 >> put h
+  put (SClass c) = putWord8 1 >> put c
+  put (SAttrib a) = putWord8 2 >> put a
+  get = do
+    w <- getWord8
+    case w of
+      0 -> SHash <$> get
+      1 -> SClass <$> get
+      2 -> SAttrib <$> get
+      _ -> fail "An error occurred when deserializing a SelectorFilter object."
+
+instance Binary Attrib where
+  put (Exist e) = putWord8 0 >> put e
+  put (Attrib an ac av) = putWord8 1 >> put an >> put ac >> put av
+  get = do
+    w <- getWord8
+    case w of
+      0 -> Exist <$> get
+      1 -> Attrib <$> get <*> get <*> get
+      _ -> fail "An error occured when deserializing an Attrib object."
+
+instance Binary Namespace where
+  put NAny = putWord8 0
+  put (Namespace t) = putWord8 1 >> put t
+  get = do
+    w <- getWord8
+    case w of
+      0 -> pure NAny
+      1 -> Namespace <$> get
+      _ -> fail "An error occurred when deserializing a Namespace object."
+
+instance Binary ElementName where
+  put EAny = putWord8 0
+  put (ElementName t) = putWord8 1 >> put t
+  get = do
+    w <- getWord8
+    case w of
+      0 -> pure EAny
+      1 -> ElementName <$> get
+      _ -> fail "An error occurred when deserializing an ElementName."
+
+instance Binary TypeSelector where
+  put (TypeSelector ns en) = put ns >> put en
+  get = TypeSelector <$> get <*> get
+
+instance Binary AttributeName where
+  put (AttributeName ns n) = put ns >> put n
+  get = AttributeName <$> get <*> get
+
+instance Binary AttributeCombinator where
+  put = _putEnum
+  get = _getEnum
+
+instance Binary Hash where
+  put (Hash h) = put h
+  get = Hash <$> get
+
+instance Binary Class where
+  put (Class h) = put h
+  get = Class <$> get
+
+instance Binary SelectorGroup where
+  put (SelectorGroup g) = put g
+  get = SelectorGroup <$> get
+
 
 -- Lift instances
 _apply :: Name -> [Q Exp] -> Q Exp
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,6 +1,10 @@
-import Css.Selector
-import Css.Selector.Utils(encodeString, readCssString)
+{-# LANGUAGE TypeApplications #-}
 
+import Css3.Selector
+import Css3.Selector.Utils(encodeString, readCssString)
+
+import Data.Binary(Binary, encode, decode)
+import Data.Function(on)
 import Data.Text(pack, unpack)
 
 import Test.Framework (defaultMain, testGroup)
@@ -18,17 +22,17 @@
     ],
     testGroup "Arbitrary css parsing" [
         testProperty "Encode-decode css identity" encodeDecodeCss,
-        testProperty "Encode-decode css identity: selector group" (encodeDecodeCss' :: SelectorGroup -> Bool),
-        testProperty "Encode-decode css identity: selector" (encodeDecodeCss' :: Selector -> Bool),
-        testProperty "Encode-decode css identity: selector sequence" (encodeDecodeCss' :: SelectorSequence -> Bool),
-        testProperty "Encode-decode css identity: selector filter" (encodeDecodeCss' :: SelectorFilter -> Bool),
-        testProperty "Encode-decode css identity: namespace" (encodeDecodeCss' :: Namespace -> Bool),
-        testProperty "Encode-decode css identity: element name" (encodeDecodeCss' :: ElementName -> Bool),
-        testProperty "Encode-decode css identity: type selector" (encodeDecodeCss' :: TypeSelector -> Bool),
-        testProperty "Encode-decode css identity: attribute" (encodeDecodeCss' :: Attrib -> Bool),
-        testProperty "Encode-decode css identity: attribute name" (encodeDecodeCss' :: AttributeName -> Bool),
-        testProperty "Encode-decode css identity: class" (encodeDecodeCss' :: Class -> Bool),
-        testProperty "Encode-decode css identity: hash" (encodeDecodeCss' :: Hash -> Bool)
+        testProperty "Encode-decode css identity: selector group" (encodeDecodeCss' @SelectorGroup),
+        testProperty "Encode-decode css identity: selector" (encodeDecodeCss' @Selector),
+        testProperty "Encode-decode css identity: selector sequence" (encodeDecodeCss' @SelectorSequence),
+        testProperty "Encode-decode css identity: selector filter" (encodeDecodeCss' @SelectorFilter),
+        testProperty "Encode-decode css identity: namespace" (encodeDecodeCss' @Namespace),
+        testProperty "Encode-decode css identity: element name" (encodeDecodeCss' @ElementName),
+        testProperty "Encode-decode css identity: type selector" (encodeDecodeCss' @TypeSelector),
+        testProperty "Encode-decode css identity: attribute" (encodeDecodeCss' @Attrib),
+        testProperty "Encode-decode css identity: attribute name" (encodeDecodeCss' @AttributeName),
+        testProperty "Encode-decode css identity: class" (encodeDecodeCss' @Class),
+        testProperty "Encode-decode css identity: hash" (encodeDecodeCss' @Hash)
     ],
     testGroup "SelectorSequences" [
         testProperty "Adding and removing filters" addRemFilters
@@ -40,7 +44,34 @@
     testGroup "Build an expression or pattern" [
         testProperty "Check build of pattern 1" buildPattern1,
         testProperty "Check build of pattern 2" buildPattern2
+    ],
+    testGroup "Convert to binary and back" [
+        testProperty "Binary identity: selector group" (binaryEquivalent @SelectorGroup),
+        testProperty "Binary identity: selector" (binaryEquivalent @Selector),
+        testProperty "Binary identity: selector sequence" (binaryEquivalent @SelectorSequence),
+        testProperty "Binary identity: selector filter" (binaryEquivalent @SelectorFilter),
+        testProperty "Binary identity: namespace" (binaryEquivalent @Namespace),
+        testProperty "Binary identity: element name" (binaryEquivalent @ElementName),
+        testProperty "Binary identity: type selector" (binaryEquivalent @TypeSelector),
+        testProperty "Binary identity: attribute" (binaryEquivalent @Attrib),
+        testProperty "Binary identity: attribute name" (binaryEquivalent @AttributeName),
+        testProperty "Binary identity: class" (binaryEquivalent @Class),
+        testProperty "Binary identity: hash" (binaryEquivalent @Hash)
+    ],
+    testGroup "Check binary equality" [
+        testProperty "Binary uniqness: selector group" (uniqnessEncoding @SelectorGroup),
+        testProperty "Binary uniqness: selector" (uniqnessEncoding @Selector),
+        testProperty "Binary uniqness: selector sequence" (uniqnessEncoding @SelectorSequence),
+        testProperty "Binary uniqness: selector filter" (uniqnessEncoding @SelectorFilter),
+        testProperty "Binary uniqness: namespace" (uniqnessEncoding @Namespace),
+        testProperty "Binary uniqness: element name" (uniqnessEncoding @ElementName),
+        testProperty "Binary uniqness: type selector" (uniqnessEncoding @TypeSelector),
+        testProperty "Binary uniqness: attribute" (uniqnessEncoding @Attrib),
+        testProperty "Binary uniqness: attribute name" (uniqnessEncoding @AttributeName),
+        testProperty "Binary uniqness: class" (uniqnessEncoding @Class),
+        testProperty "Binary uniqness: hash" (uniqnessEncoding @Hash)
     ]
+
   ]
 
 encodeDecode :: Char -> String -> Bool
@@ -51,6 +82,12 @@
 
 encodeDecodeCss :: SelectorGroup -> Bool
 encodeDecodeCss sg = sg == (parseCss . unpack . toCssSelector) sg
+
+binaryEquivalent :: (Binary a, Eq a, ToCssSelector a) => a -> Bool
+binaryEquivalent x = decode (encode x) == x
+
+uniqnessEncoding :: (Binary a, Eq a, ToCssSelector a) => a -> a -> Bool
+uniqnessEncoding ca cb = (encode ca == encode cb) == (ca == cb)
 
 encodeDecodeCss' :: ToCssSelector a => a -> Bool
 encodeDecodeCss' sg = (parseCss . unpack . toCssSelector . toSelectorGroup) sg == toSelectorGroup sg
