diff --git a/.gitignore b/.gitignore
index ae498e7c2f49685b94bc63487808b0de8f1bd381..511c1e5cef32e9c4c582be959bb8b7130c58a619 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,4 @@ tmp
 
 # Autogenerated docs
 docs/api/runtime*.md
+docs/api/doc
diff --git a/xtask/src/gen_doc.rs b/xtask/src/gen_doc.rs
index 90252b01368c31d44408ec7e5307e7a708d241ab..5e4b4b23898522ce26c57be25f12abca7c2289fe 100644
--- a/xtask/src/gen_doc.rs
+++ b/xtask/src/gen_doc.rs
@@ -21,6 +21,7 @@ use scale_info::form::PortableForm;
 use serde::Serialize;
 use std::collections::HashMap;
 use std::path::Path;
+use std::process::Command;
 use std::{
     fs::File,
     io::{Read, Write},
@@ -319,6 +320,24 @@ pub(super) fn gen_doc() -> Result<()> {
     file.write_all(error_doc.as_bytes())
         .with_context(|| format!("Failed to write to file '{}'", ERRORS_DOC_FILEPATH))?;
 
+    // Generate docs from rust code
+    Command::new("cargo")
+        .args([
+            "doc",
+            "--workspace",
+            "--no-deps",
+            "--document-private-items",
+            "--features=runtime-benchmarks",
+        ])
+        .status()
+        .expect("cargo doc failed to execute");
+
+    // Organise folder for deployment
+    Command::new("cp")
+        .args(["-r", "./target/doc", "./docs/api/"])
+        .status()
+        .expect("failed to build docs folder");
+
     Ok(())
 }