diff --git a/src/main.rs b/src/main.rs
index 47afd019..50517850 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,6 +16,7 @@ mod embedded;
 mod exercise;
 mod init;
 mod run;
+mod state;
 mod tui;
 mod verify;
 
diff --git a/src/state.rs b/src/state.rs
new file mode 100644
index 00000000..e3e32990
--- /dev/null
+++ b/src/state.rs
@@ -0,0 +1,32 @@
+use anyhow::{Context, Result};
+use serde::{Deserialize, Serialize};
+use std::{fs, io, path::PathBuf};
+
+#[derive(Serialize, Deserialize)]
+pub struct ExerciseState {
+    pub path: PathBuf,
+    pub done: bool,
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct State {
+    pub progress: Vec<ExerciseState>,
+}
+
+impl State {
+    pub fn read() -> Result<Self> {
+        let file_content =
+            fs::read(".rustlings.json").context("Failed to read the file `.rustlings.json`")?;
+
+        serde_json::de::from_slice(&file_content)
+            .context("Failed to deserialize the file `.rustlings.json`")
+    }
+
+    pub fn write(&self) -> io::Result<()> {
+        // TODO: Capacity
+        let mut buf = Vec::with_capacity(1 << 12);
+        serde_json::ser::to_writer(&mut buf, self).context("Failed to serialize the state");
+        dbg!(buf.len());
+        Ok(())
+    }
+}