diff --git a/src/embedded.rs b/src/embedded.rs
index 8f6c14e..25dbe64 100644
--- a/src/embedded.rs
+++ b/src/embedded.rs
@@ -52,7 +52,9 @@ impl EmbeddedFlatDir {
             }
         }
 
-        self.readme.write_to_disk(WriteStrategy::Overwrite)
+        self.readme.write_to_disk(WriteStrategy::Overwrite)?;
+
+        Ok(())
     }
 }
 
@@ -63,16 +65,31 @@ struct ExercisesDir {
 }
 
 pub struct EmbeddedFiles {
-    info_toml_content: &'static str,
+    pub info_toml_content: &'static str,
     exercises_dir: ExercisesDir,
 }
 
 impl EmbeddedFiles {
     pub fn init_exercises_dir(&self) -> io::Result<()> {
         create_dir("exercises")?;
+
         self.exercises_dir
             .readme
-            .write_to_disk(WriteStrategy::Overwrite)
+            .write_to_disk(WriteStrategy::IfNotExists)?;
+
+        for file in self.exercises_dir.files {
+            file.write_to_disk(WriteStrategy::IfNotExists)?;
+        }
+
+        for dir in self.exercises_dir.dirs {
+            dir.init_on_disk()?;
+
+            for file in dir.content {
+                file.write_to_disk(WriteStrategy::IfNotExists)?;
+            }
+        }
+
+        Ok(())
     }
 
     pub fn write_exercise_to_disk(&self, path: &Path, strategy: WriteStrategy) -> io::Result<()> {
diff --git a/src/exercise.rs b/src/exercise.rs
index 16e4a41..7c2e5fd 100644
--- a/src/exercise.rs
+++ b/src/exercise.rs
@@ -36,7 +36,7 @@ fn temp_file() -> String {
         .filter(|c| c.is_alphanumeric())
         .collect();
 
-    format!("temp_{}_{thread_id}", process::id())
+    format!("./temp_{}_{thread_id}", process::id())
 }
 
 // The mode of the exercise.
diff --git a/src/main.rs b/src/main.rs
index 90d0109..822cd1a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,14 +5,14 @@ use crate::verify::verify;
 use anyhow::Result;
 use clap::{Parser, Subcommand};
 use console::Emoji;
+use embedded::EMBEDDED_FILES;
 use notify_debouncer_mini::notify::{self, RecursiveMode};
 use notify_debouncer_mini::{new_debouncer, DebouncedEventKind};
 use shlex::Shlex;
 use std::ffi::OsStr;
-use std::fs;
-use std::io::{self, prelude::*};
+use std::io::{self, prelude::*, stdin, stdout};
 use std::path::Path;
-use std::process::Command;
+use std::process::{exit, Command};
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::mpsc::{channel, RecvTimeoutError};
 use std::sync::{Arc, Mutex};
@@ -54,7 +54,7 @@ enum Subcommands {
         /// The name of the exercise
         name: String,
     },
-    /// Reset a single exercise using "git stash -- <filename>"
+    /// Reset a single exercise
     Reset {
         /// The name of the exercise
         name: String,
@@ -83,13 +83,45 @@ enum Subcommands {
         #[arg(short, long)]
         solved: bool,
     },
-    /// Enable rust-analyzer for exercises
-    Lsp,
 }
 
 fn main() -> Result<()> {
     let args = Args::parse();
 
+    let exercises = toml_edit::de::from_str::<ExerciseList>(EMBEDDED_FILES.info_toml_content)
+        .unwrap()
+        .exercises;
+
+    if !Path::new("exercises").is_dir() {
+        let mut stdout = stdout().lock();
+        write!(
+            stdout,
+            "The `exercises` directory wasn't found in the current directory.
+Do you want to initialize Rustlings in the current directory (y/n)? "
+        )?;
+        stdout.flush()?;
+        let mut answer = String::new();
+        stdin().read_line(&mut answer)?;
+        answer.make_ascii_lowercase();
+        if answer.trim() != "y" {
+            exit(1);
+        }
+
+        EMBEDDED_FILES.init_exercises_dir()?;
+        if let Err(e) = write_project_json(&exercises) {
+            writeln!(
+                stdout,
+                "Failed to write rust-project.json to disk for rust-analyzer: {e}"
+            )?;
+        } else {
+            writeln!(stdout, "Successfully generated rust-project.json")?;
+            writeln!(
+                stdout,
+                "rust-analyzer will now parse exercises, restart your language server or editor"
+            )?;
+        }
+    }
+
     if args.command.is_none() {
         println!("\n{WELCOME}\n");
     }
@@ -101,18 +133,6 @@ fn main() -> Result<()> {
         std::process::exit(1);
     }
 
-    let info_file = fs::read_to_string("info.toml").unwrap_or_else(|e| {
-        match e.kind() {
-            io::ErrorKind::NotFound => println!(
-                "The program must be run from the rustlings directory\nTry `cd rustlings/`!",
-            ),
-            _ => println!("Failed to read the info.toml file: {e}"),
-        }
-        std::process::exit(1);
-    });
-    let exercises = toml_edit::de::from_str::<ExerciseList>(&info_file)
-        .unwrap()
-        .exercises;
     let verbose = args.nocapture;
 
     let command = args.command.unwrap_or_else(|| {
@@ -205,7 +225,7 @@ fn main() -> Result<()> {
         Subcommands::Reset { name } => {
             let exercise = find_exercise(&name, &exercises);
 
-            reset(exercise).unwrap_or_else(|_| std::process::exit(1));
+            reset(exercise)?;
         }
 
         Subcommands::Hint { name } => {
@@ -219,15 +239,6 @@ fn main() -> Result<()> {
                 .unwrap_or_else(|_| std::process::exit(1));
         }
 
-        Subcommands::Lsp => {
-            if let Err(e) = write_project_json(exercises) {
-                println!("Failed to write rust-project.json to disk for rust-analyzer: {e}");
-            } else {
-                println!("Successfully generated rust-project.json");
-                println!("rust-analyzer will now parse exercises, restart your language server or editor");
-            }
-        }
-
         Subcommands::Watch { success_hints } => match watch(&exercises, verbose, success_hints) {
             Err(e) => {
                 println!("Error: Could not watch your progress. Error message was {e:?}.");
diff --git a/src/project.rs b/src/project.rs
index 0f56de9..bb6caa5 100644
--- a/src/project.rs
+++ b/src/project.rs
@@ -1,7 +1,7 @@
 use anyhow::{Context, Result};
 use serde::Serialize;
 use std::env;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 
 use crate::exercise::Exercise;
@@ -9,14 +9,14 @@ use crate::exercise::Exercise;
 /// Contains the structure of resulting rust-project.json file
 /// and functions to build the data required to create the file
 #[derive(Serialize)]
-struct RustAnalyzerProject {
+struct RustAnalyzerProject<'a> {
     sysroot_src: PathBuf,
-    crates: Vec<Crate>,
+    crates: Vec<Crate<'a>>,
 }
 
 #[derive(Serialize)]
-struct Crate {
-    root_module: PathBuf,
+struct Crate<'a> {
+    root_module: &'a Path,
     edition: &'static str,
     // Not used, but required in the JSON file.
     deps: Vec<()>,
@@ -25,12 +25,12 @@ struct Crate {
     cfg: [&'static str; 1],
 }
 
-impl RustAnalyzerProject {
-    fn build(exercises: Vec<Exercise>) -> Result<Self> {
+impl<'a> RustAnalyzerProject<'a> {
+    fn build(exercises: &'a [Exercise]) -> Result<Self> {
         let crates = exercises
-            .into_iter()
+            .iter()
             .map(|exercise| Crate {
-                root_module: exercise.path,
+                root_module: &exercise.path,
                 edition: "2021",
                 deps: Vec::new(),
                 // This allows rust_analyzer to work inside `#[test]` blocks
@@ -69,7 +69,7 @@ impl RustAnalyzerProject {
 }
 
 /// Write `rust-project.json` to disk.
-pub fn write_project_json(exercises: Vec<Exercise>) -> Result<()> {
+pub fn write_project_json(exercises: &[Exercise]) -> Result<()> {
     let content = RustAnalyzerProject::build(exercises)?;
 
     // Using the capacity 2^14 since the file length in bytes is higher than 2^13.
diff --git a/src/run.rs b/src/run.rs
index 6dd0388..792bd8f 100644
--- a/src/run.rs
+++ b/src/run.rs
@@ -1,6 +1,7 @@
-use std::process::Command;
+use std::io;
 use std::time::Duration;
 
+use crate::embedded::{WriteStrategy, EMBEDDED_FILES};
 use crate::exercise::{Exercise, Mode};
 use crate::verify::test;
 use indicatif::ProgressBar;
@@ -19,17 +20,8 @@ pub fn run(exercise: &Exercise, verbose: bool) -> Result<(), ()> {
 }
 
 // Resets the exercise by stashing the changes.
-pub fn reset(exercise: &Exercise) -> Result<(), ()> {
-    let command = Command::new("git")
-        .arg("stash")
-        .arg("--")
-        .arg(&exercise.path)
-        .spawn();
-
-    match command {
-        Ok(_) => Ok(()),
-        Err(_) => Err(()),
-    }
+pub fn reset(exercise: &Exercise) -> io::Result<()> {
+    EMBEDDED_FILES.write_exercise_to_disk(&exercise.path, WriteStrategy::Overwrite)
 }
 
 // Invoke the rust compiler on the path of the given exercise