diff --git a/Cargo.lock b/Cargo.lock
index f823a3b..86dbd0c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -519,6 +519,7 @@ dependencies = [
  "serde_json",
  "tera",
  "toml",
+ "xml-builder",
 ]
 
 [[package]]
@@ -1432,6 +1433,12 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "xml-builder"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efc4f1a86af7800dfc4056c7833648ea4515ae21502060b5c98114d828f5333b"
+
 [[package]]
 name = "zerocopy"
 version = "0.7.32"
diff --git a/Cargo.toml b/Cargo.toml
index 1379000..a11a235 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,3 +15,4 @@ chrono = "0.4"
 derive_more = "0.99"
 scraper = "0.19"
 serde_json = "1.0"
+xml-builder = "0.5"
diff --git a/src/config.rs b/src/config.rs
index febcd58..63cf390 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -7,8 +7,21 @@ pub struct Config {
     pub src_dir: String,
     pub templates_dir: String,
     pub emoji_config: Option<EmojiConfig>,
+    pub syndication: Option<Syndication>,
+}
+#[derive(Deserialize, Serialize, Debug)]
+pub struct Syndication {
+    pub title: String,
+    pub link: String,
+    pub icon: Option<String>,
+    pub subtitle: Option<String>,
+    pub atom: Option<AtomConfig>,
 }
 
+#[derive(Deserialize, Serialize, Debug)]
+pub struct AtomConfig {
+    pub enabled: bool,
+}
 #[derive(Deserialize, Serialize, Debug)]
 pub struct EmojiConfig {
     pub emoji_web_directory: String,
@@ -22,6 +35,7 @@ impl Default for Config {
             src_dir: "md_src".to_string(),
             templates_dir: "templates".to_string(),
             emoji_config: None,
+            syndication: None,
         }
     }
 }
diff --git a/src/lib.rs b/src/lib.rs
index 73b69b1..ea00765 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,5 @@
 #![feature(str_split_remainder)]
+
 use chrono::prelude::*;
 use derive_more::Constructor;
 use markdown::{to_html_with_options, CompileOptions, Options};
diff --git a/src/main.rs b/src/main.rs
index f697889..42336ea 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,9 @@
+#![feature(ascii_char)]
 use std::fs::read_to_string;
 pub mod config;
 pub mod emoji;
 pub mod index;
+pub mod syndication;
 use mlem::*;
 use std::env;
 
@@ -45,6 +47,7 @@ fn generate() {
             format!("{}.html", file.file_name.to_str().unwrap()),
         ));
     }
+
     let index = index::generate(post_index, &config.templates_dir);
 
     std::fs::write(format!("{}/index.html", config.output_dir), index)
diff --git a/src/syndication/atom.rs b/src/syndication/atom.rs
new file mode 100644
index 0000000..0b54153
--- /dev/null
+++ b/src/syndication/atom.rs
@@ -0,0 +1,62 @@
+use xml_builder::{XMLBuilder, XMLElement, XMLVersion};
+
+pub fn generate(
+    config: crate::config::Syndication,
+    post_index: &Vec<crate::index::BlogPost>,
+) -> String {
+    let mut xml = XMLBuilder::new()
+        .version(XMLVersion::XML1_1)
+        .encoding("UTF-8".into())
+        .build();
+
+    let mut feed = XMLElement::new("feed");
+    feed.add_attribute("xmlns", "http://www.w3.org/2005/Atom");
+
+    let mut id = XMLElement::new("id");
+    id.add_text(config.link).unwrap();
+    feed.add_child(id).unwrap();
+
+    let mut title = XMLElement::new("title");
+    title.add_text(config.title).unwrap();
+    feed.add_child(title).unwrap();
+
+    let mut updated = XMLElement::new("updated");
+    let last_update = chrono::DateTime::from_timestamp(last_update(post_index), 0).unwrap();
+    updated.add_text(last_update.to_rfc3339()).unwrap();
+    feed.add_child(updated).unwrap();
+
+    if config.subtitle.is_some() {
+        let mut subtitle = XMLElement::new("subtitle");
+        subtitle.add_text(config.subtitle.unwrap()).unwrap();
+        feed.add_child(subtitle).unwrap();
+    }
+
+    if config.icon.is_some() {
+        let mut icon = XMLElement::new("icon");
+        icon.add_text(config.icon.unwrap()).unwrap();
+        feed.add_child(icon).unwrap();
+    }
+
+    xml.set_root_element(feed);
+    let mut writer: Vec<u8> = Vec::new();
+    xml.generate(&mut writer).unwrap();
+
+    let mut output_xml = String::new();
+
+    for e in writer {
+        output_xml += &e.as_ascii().unwrap().to_string();
+    }
+
+    output_xml
+}
+
+fn last_update(post_index: &Vec<crate::index::BlogPost>) -> i64 {
+    let mut last_timestamp: i64 = i64::MIN;
+
+    for post in post_index {
+        if post.sort_date > last_timestamp {
+            last_timestamp = post.sort_date;
+        }
+    }
+    last_timestamp
+}
diff --git a/src/syndication/mod.rs b/src/syndication/mod.rs
new file mode 100644
index 0000000..856b895
--- /dev/null
+++ b/src/syndication/mod.rs
@@ -0,0 +1 @@
+pub mod atom;