diff --git a/core/http/src/handlers.rs b/core/http/src/handlers.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/http/src/lib.rs b/core/http/src/lib.rs
index 7d12d9af8195bf5e19d10c7b592b359ccd014149..1d8e24d1c71a2f52a2a6c5619060251ba16678af 100644
--- a/core/http/src/lib.rs
+++ b/core/http/src/lib.rs
@@ -1,14 +1,74 @@
-pub fn add(left: usize, right: usize) -> usize {
-    left + right
+use std::{
+    fs,
+    io::{BufRead, BufReader, Write},
+    net::{TcpListener, TcpStream},
+    thread::available_parallelism,
+};
+
+use threading::ThreadPool;
+
+mod handlers;
+mod routing;
+mod threading;
+
+pub struct Config {
+    address: TcpListener,
+    workers: usize,
+    threadpool: ThreadPool,
 }
 
-#[cfg(test)]
-mod tests {
-    use super::*;
+impl Config {
+    pub fn mount(self, mountpoint: &str, routes: Vec<routing::Route>) {}
+    pub fn launch(self) {
+        for stream in self.address.incoming() {
+            let stream = stream.unwrap();
+            self.threadpool.execute(|| handle_connection(stream))
+        }
+    }
+}
+
+fn handle_connection(mut stream: TcpStream) {
+    let buf_reader = BufReader::new(&mut stream);
+    let http_request: Vec<_> = buf_reader
+        .lines()
+        .map(|result| result.unwrap())
+        .take_while(|line| !line.is_empty())
+        .collect();
 
-    #[test]
-    fn it_works() {
-        let result = add(2, 2);
-        assert_eq!(result, 4);
+    let status_line = "HTTP/1.1 200 OK";
+    let contents = fs::read_to_string("hello.html").unwrap();
+    let length = contents.len();
+
+    let response = format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}");
+
+    stream.write_all(response.as_bytes()).unwrap();
+}
+
+pub fn build(ip: &str) -> Config {
+    let listener = TcpListener::bind(ip).unwrap();
+    let ip = ip.splitn(2, ":").collect::<Vec<&str>>();
+    if ip.len() != 2 {
+        panic!("Invalid IP Address");
+    }
+    let port = ip[1];
+    let ip = ip[0];
+    let workers = available_parallelism().unwrap().get();
+    let threadpool = ThreadPool::new(workers);
+    println!(
+        "\x1b[34mâš™ Configuration\x1b[0m
+  >> \x1b[34mIp\x1b[0m: {ip}
+  >> \x1b[34mPort\x1b[0m: {port}
+  >> \x1b[34mWorkers\x1b[0m: {workers}
+\n
+Server has launched from {ip}:{port}.
+"
+    );
+    Config {
+        address: listener,
+        workers,
+        threadpool,
     }
 }
+
+#[cfg(test)]
+mod tests {}
diff --git a/core/http/src/routing.rs b/core/http/src/routing.rs
new file mode 100644
index 0000000000000000000000000000000000000000..6ae9a7398c015629ecf7c07d90206e0302747856
--- /dev/null
+++ b/core/http/src/routing.rs
@@ -0,0 +1,2 @@
+pub struct Route;
+pub struct RoutInfo;
diff --git a/core/http/src/threading.rs b/core/http/src/threading.rs
new file mode 100644
index 0000000000000000000000000000000000000000..b59bec8320b39123b7c486cd2c9d6b1373e11a97
--- /dev/null
+++ b/core/http/src/threading.rs
@@ -0,0 +1,90 @@
+use std::{
+    sync::{mpsc, Arc, Mutex},
+    thread,
+};
+
+pub struct ThreadPool {
+    workers: Vec<Worker>,
+    sender: Option<mpsc::Sender<Job>>,
+}
+
+type Job = Box<dyn FnOnce() + Send + 'static>;
+
+impl ThreadPool {
+    /// Create a new ThreadPool.
+    ///
+    /// The size is the number of threads in the pool.
+    ///
+    /// # Panics
+    ///
+    /// The `new` function will panic if the size is zero.
+    pub fn new(size: usize) -> ThreadPool {
+        assert!(size > 0);
+
+        let (sender, receiver) = mpsc::channel();
+
+        let receiver = Arc::new(Mutex::new(receiver));
+
+        let mut workers = Vec::with_capacity(size);
+
+        for id in 0..size {
+            workers.push(Worker::new(id, Arc::clone(&receiver)));
+        }
+        ThreadPool {
+            workers,
+            sender: Some(sender),
+        }
+    }
+
+    pub fn execute<F>(&self, f: F)
+    where
+        F: FnOnce() + Send + 'static,
+    {
+        let job = Box::new(f);
+
+        self.sender.as_ref().unwrap().send(job).unwrap();
+    }
+}
+
+impl Drop for ThreadPool {
+    fn drop(&mut self) {
+        drop(self.sender.take());
+
+        for worker in &mut self.workers {
+            println!("Shutting down worker {}", worker.id);
+
+            if let Some(thread) = worker.thread.take() {
+                thread.join().unwrap();
+            }
+        }
+    }
+}
+struct Worker {
+    id: usize,
+    thread: Option<thread::JoinHandle<()>>,
+}
+
+impl Worker {
+    fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
+        let thread = thread::spawn(move || loop {
+            let message = receiver.lock().unwrap().recv();
+
+            match message {
+                Ok(job) => {
+                    println!("Worker {id} got a job; executing.");
+
+                    job();
+                }
+                Err(_) => {
+                    println!("Worker {id} disconnected; shutting down.");
+                    break;
+                }
+            }
+        });
+
+        Worker {
+            id,
+            thread: Some(thread),
+        }
+    }
+}
diff --git a/q b/q
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/site/Cargo.lock b/site/Cargo.lock
index d1bf5078f09d5e69784d6dfd70bfab679737d362..fac1130d38de5e4962dadd74bae9f23f1cf1e92b 100644
--- a/site/Cargo.lock
+++ b/site/Cargo.lock
@@ -2,6 +2,13 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "http"
+version = "0.1.0"
+
 [[package]]
 name = "site"
 version = "0.1.0"
+dependencies = [
+ "http",
+]
diff --git a/site/Cargo.toml b/site/Cargo.toml
index e6a315340d89f3e8aa591389c7be8147b0c83995..d4e9a4aa28539c317f6e90f0c703bdc4ce96d155 100644
--- a/site/Cargo.toml
+++ b/site/Cargo.toml
@@ -6,3 +6,4 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+http = { path = "../core/http" }
diff --git a/site/hello.html b/site/hello.html
new file mode 100644
index 0000000000000000000000000000000000000000..ff4f652fb0a10afb80abf769b19610998e15d290
--- /dev/null
+++ b/site/hello.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8" />
+    <title>Hello!</title>
+  </head>
+  <body>
+    <h1>Hello!</h1>
+    <p>Hi from Rust</p>
+  </body>
+</html>
diff --git a/site/src/main.rs b/site/src/main.rs
index e7a11a969c037e00a796aafeff6258501ec15e9a..435d748cd9a50dabeeef5a540582d5d5b13b71ba 100644
--- a/site/src/main.rs
+++ b/site/src/main.rs
@@ -1,3 +1,3 @@
 fn main() {
-    println!("Hello, world!");
+    http::build("192.168.179.2:8000").launch();
 }