diff --git a/CHANGELOG.md b/CHANGELOG.md
index d78e50d8ebdf89c71512502b8f602d827a0e8875..909a9d8c9518595f465ede7446a6d768146a26e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,5 +4,6 @@ here's only the changelog for the version in development
 # v2.0
 
 * fixed a bug with serializing uint32a
+* added support for arbitrarily large integers
 * major refactor
     * backwards compatible 100%
diff --git a/docs/specification.rst b/docs/specification.rst
index 5fc538db0da4161e0362c8d9c0856e882501ce1c..bde7dc73e0d3cba025630da628e3026c84f4fbd5 100644
--- a/docs/specification.rst
+++ b/docs/specification.rst
@@ -63,3 +63,5 @@ Type Value consists of:
   and then follow that many pairs of Values (key: value)
 * If value is 22, then it's True
 * If value is 23, then it's False
+* If value is 24, then next what comes is count of bytes, and then bytes follow. This is to be
+    interpreted as a signed integer
diff --git a/minijson.pyx b/minijson.pyx
index 378752ecf200f9bf6e9640d677227a3c3768ad71..6dc239e46432ded169057fb1bc066f34b83f6887 100644
--- a/minijson.pyx
+++ b/minijson.pyx
@@ -274,6 +274,10 @@ cpdef tuple parse(bytes data, int starting_position):
             return 1, True
         elif value_type == 23:
             return 1, False
+        elif value_type == 24:
+            length = data[starting_position+1]
+            byte_data = data[starting_position+2:starting_position+2+length]
+            return length+2, int.from_bytes(byte_data, 'big', signed=True)
         else:
             raise DecodingError('Unknown sequence type %s!' % (value_type, ))
     except (IndexError, struct.error) as e:
@@ -302,6 +306,7 @@ cpdef int dump(object data, cio: io.BytesIO) except -1:
     cdef:
         str field_name
         int length
+        bytes b_data
     if data is None:
         cio.write(b'\x08')
         return 1
@@ -364,7 +369,15 @@ cpdef int dump(object data, cio: io.BytesIO) except -1:
             cio.write(STRUCT_L.pack(data))
             return 5
         else:
-            raise EncodingError('Too large integer %s' % (data, ))
+            length = 5
+            while True:
+                try:
+                    b_data = data.to_bytes(length, 'big', signed=True)
+                    break
+                except OverflowError:
+                    length += 1
+            cio.write(bytearray([0x18, length]))
+            cio.write(b_data)
     elif isinstance(data, float):
         if float_encoding_mode == 0:
             cio.write(b'\x09')
diff --git a/setup.cfg b/setup.cfg
index 5fd7992f4c290a0cd504b285a199ba14e07025c9..6594f71adcf8f0818cb4c79dd2efcca9f6893da4 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,6 @@
 # coding: utf-8
 [metadata]
+version = 2.0
 name = minijson
 long-description = file: README.md
 long-description-content-type = text/markdown; charset=UTF-8
diff --git a/setup.py b/setup.py
index 483866977b8af3bd199ef42152708a4ad8ec5f50..71dc8e980a8c0f3fb1c179195451be6a80cfc98c 100644
--- a/setup.py
+++ b/setup.py
@@ -1,9 +1,8 @@
 import os
-from distutils.extension import Extension
 
 from Cython.Build import cythonize
 from Cython.Compiler.Options import get_directive_defaults
-from distutils.core import setup
+from setuptools import setup, Extension
 
 directive_defaults = get_directive_defaults()
 directive_defaults['language_level'] = '3'
@@ -15,10 +14,6 @@ if 'DEBUG' in os.environ:
     directive_defaults['binding'] = True
     macros = [('CYTHON_TRACE', '1')]
 
-extensions = [Extension("minijson", ["minijson.pyx"],
-                        define_macros=macros),
-              ]
 
-setup(version='2.0',
-      ext_modules=cythonize(extensions),
-      )
+setup(ext_modules=cythonize([Extension("minijson", ["minijson.pyx"],
+                        define_macros=macros)]))
diff --git a/tests/test_minijson.py b/tests/test_minijson.py
index e50c4a662e803b157d02898f68bbcb74f49d6580..0a312c3466ef98719b7f09005f7066911061203a 100644
--- a/tests/test_minijson.py
+++ b/tests/test_minijson.py
@@ -97,12 +97,10 @@ class TestMiniJSON(unittest.TestCase):
         self.assertSameAfterDumpsAndLoads(-0x7FFF)
         self.assertSameAfterDumpsAndLoads(-0xFFFF)
         self.assertSameAfterDumpsAndLoads(0x1FFFF)
-        b = dumps(0xFFFFFFFF)
-        print('Serialized to %s' % (b, ))
-        c = loads(b)
-        self.assertEqual(0xFFFFFFFF, c)
+        self.assertSameAfterDumpsAndLoads(0xFFFFFFFF)
         self.assertSameAfterDumpsAndLoads(0x1FFFFFF)
-        self.assertRaises(EncodingError, lambda: dumps(0xFFFFFFFFF))
+        self.assertSameAfterDumpsAndLoads(0xFFFFFFFFF)
+        self.assertSameAfterDumpsAndLoads(0xFFFFFFFFFFFFF)
 
     def test_dumps(self):
         v = {"name": "land", "operator_id": "dupa", "parameters":