diff --git a/pycgtool/parsers/json.py b/pycgtool/parsers/json.py
new file mode 100644
index 0000000000000000000000000000000000000000..ca6efe87bb716f4dc5d3edd5d4ce588c58525b2c
--- /dev/null
+++ b/pycgtool/parsers/json.py
@@ -0,0 +1,38 @@
+import json
+
+
+class DuplicateSectionError(Exception):
+    """
+    Exception used to indicate that a section has appeared twice in a file.
+    """
+    def __repr__(self):
+        return "Section {0} appears twice in file {1}.".format(*self.args)
+
+
+class Record(dict):
+    def __setattr__(self, key, value):
+        self[key] = value
+
+    def __getattr__(self, item):
+        return self[item]
+
+
+class CFG:
+    def __init__(self, filename):
+        with open(filename) as f:
+            try:
+                self._json = json.load(f, object_hook=Record)
+            except ValueError:
+                raise DuplicateSectionError()
+
+    def __getitem__(self, item):
+        return Record(self._json[item])
+
+    def __contains__(self, item):
+        return item in self._json
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        pass
diff --git a/test/data/twice.json b/test/data/twice.json
new file mode 100644
index 0000000000000000000000000000000000000000..8f67decb328f6dd50f7f1501b3d2a17f1801f777
--- /dev/null
+++ b/test/data/twice.json
@@ -0,0 +1,15 @@
+{"SOL":{
+   "beads":[
+        {"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]}
+   ],
+   "bonds":[
+   ]
+}}
+
+{"SOL":{
+   "beads":[
+        {"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]}
+   ],
+   "bonds":[
+   ]
+}}
diff --git a/test/data/water.json b/test/data/water.json
new file mode 100644
index 0000000000000000000000000000000000000000..b9597be13b2d3f2195d24548d86c62d59ffac6b4
--- /dev/null
+++ b/test/data/water.json
@@ -0,0 +1,7 @@
+{"SOL":{
+   "beads":[
+        {"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]}
+   ],
+   "bonds":[
+   ]
+}}
diff --git a/test/test_parsers_json.py b/test/test_parsers_json.py
new file mode 100644
index 0000000000000000000000000000000000000000..c7aebaff5200ed9da05fe72790da3d2473220998
--- /dev/null
+++ b/test/test_parsers_json.py
@@ -0,0 +1,33 @@
+import unittest
+
+from pycgtool.parsers.json import CFG, DuplicateSectionError
+
+
+class TestParsersJson(unittest.TestCase):
+    def test_cfg_with(self):
+        with CFG("test/data/water.json"):
+            pass
+
+    def test_cfg_get_section(self):
+        with CFG("test/data/water.json") as cfg:
+            self.assertTrue("SOL" in cfg)
+            self.assertEqual(1, len(cfg["SOL"].beads))
+            bead = cfg["SOL"].beads[0]
+            self.assertEqual("W", bead.name)
+            self.assertEqual("P4", bead.type)
+            self.assertEqual(["OW", "HW1", "HW2"], bead.atoms)
+            self.assertEqual(0, len(cfg["SOL"].bonds))
+
+    def test_cfg_duplicate_error(self):
+        with self.assertRaises(DuplicateSectionError):
+            CFG("test/data/twice.json")
+
+    @unittest.expectedFailure
+    def test_include_file(self):
+        with CFG("test/data/martini.json") as cfg:
+            self.assertTrue("DOPC" in cfg)
+            self.assertTrue("GLY" in cfg)
+
+
+if __name__ == '__main__':
+    unittest.main()