diff --git a/src/lib.rs b/src/lib.rs
index 26cb6505f0715e0b53800fd011be5f3a08d27f17..d384507b3f4e2159bf5c86a41948d4061d515628 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,4 +13,5 @@ extern crate rand;
 
 pub mod cli;
 pub mod routing;
-pub mod scripting;
\ No newline at end of file
+pub mod scripting;
+pub mod server;
diff --git a/src/main.rs b/src/main.rs
index 13e981d28cee3881a790339766f6c4c399fcbeba..856fa7d684b67eecd7323b3a90cf39d7435875e6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,98 +8,10 @@ extern crate docopt;
 extern crate swerve;
 extern crate rhai;
 
-use rhai::Engine;
-
-use std::{path, process, io};
-use std::fs::{self, File};
+use std::process;
 use docopt::Docopt;
-use rocket::response::NamedFile;
-use rocket::http::ContentType;
-use rocket::{Response, Request};
 use swerve::cli;
-use swerve::routing;
-use std::io::BufReader;
-use std::path::{Path, PathBuf};
-use rocket::response::Responder;
-
-struct TypedFile {
-    file: File,
-    content_type: Option<ContentType>,
-    path: PathBuf,
-}
-
-impl TypedFile {
-    pub fn open<P: AsRef<Path>>(path: P, content_type: Option<rocket::http::ContentType>) -> TypedFile {
-        let file = File::open(path.as_ref()).unwrap();
-        TypedFile { file, content_type, path: (*path.as_ref()).to_path_buf() }
-    }
-}
-
-impl rocket::response::Responder<'static> for TypedFile {
-    fn respond_to(self, _: &Request) -> Result<Response<'static>, rocket::http::Status> {
-        let mut response = Response::new();
-        if let Some(content_type) = self.content_type {
-            response.set_header(content_type);
-        } else {
-            response.set_header(ContentType::from_extension(&self.path.extension().unwrap().to_string_lossy()).unwrap());
-        }
-        response.set_streamed_body(BufReader::new(self.file));
-        Ok(response)
-    }
-}
-
-#[get("/")]
-fn serve_root(args: rocket::State<cli::Args>) -> Option<TypedFile> {
-    serve_files(None, args)
-}
-
-#[get("/<file..>")]
-fn serve_files(file: Option<path::PathBuf>, args: rocket::State<cli::Args>) -> Option<TypedFile> {
-    let stub = match file {
-        Some(path) => path,
-        None => path::PathBuf::from(""),
-    };
-
-    let path = args.get_dir().join(stub);
-
-    let meta = match fs::metadata(&path) {
-        Ok(metadata) => metadata,
-        _ => return None,
-    };
-
-    if meta.is_dir() && !args.flag_no_index {
-        Some(TypedFile::open(path.join("index.html"), None))
-    } else {
-        if &path.extension().unwrap().to_string_lossy() == "wasm" {
-           Some( TypedFile::open(path, Some(ContentType::new("application", "wasm"))))
-        } else {
-            Some(TypedFile::open(path, None))
-        }
-    }
-}
-
-fn config_from_args(args: cli::Args, config: cli::SwerveConfig) -> rocket::Config {
-    let mut builder = rocket::Config::build(rocket::config::Environment::Development);
-    if let Some(threads) = args.flag_threads {
-        builder = builder.workers(threads);
-    } else {
-        builder = builder.workers(config.server.threads);
-    }
-
-    if let Some(port) = args.flag_port {
-        builder = builder.port(port);
-    } else {
-        builder = builder.port(config.server.port);
-    }
-
-    if let Some(address) = args.flag_address {
-        builder = builder.address(address);
-    } else {
-        builder = builder.address(config.server.address);
-    }
-
-    builder.finalize().unwrap()
-}
+use swerve::server;
 
 fn main() {
     let args: cli::Args = Docopt::new(cli::USAGE)
@@ -133,38 +45,6 @@ fn main() {
         std::process::exit(2);
     });
 
-    let server_config = config_from_args(args.clone(), swerve_config.clone());
-    // printq!("{:?}", swerve_config);
-    printq!("");
-
-    let mut server = rocket::custom(server_config, false)
-        .manage(args.clone())
-        .manage(swerve_config);
-
-    if let Some(ref upload_path) = args.flag_upload_path {
-        printq!("[SETUP] Accepting uploads at {}", upload_path);
-        server = server.mount(upload_path, routes![swerve::routing::mock_upload::to_file]);
-    } else if args.flag_upload {
-        printq!("[SETUP] Accepting uploads at /upload");
-        server = server.mount("/upload", routes![swerve::routing::mock_upload::to_file]);
-    }
-    server = server.mount("/", routes![
-		serve_root,
-		serve_files,
-		routing::scripting::route_script
-	]);
-
-    if !args.flag_quiet {
-        server = server.attach(rocket::fairing::AdHoc::on_launch(move |rckt| {
-            let config = rckt.config();
-            println!("[SETUP] Swerve is configured with {} worker threads", config.workers);
-            println!("[SETUP] Swerving files from http://{}:{}\n", config.address, config.port);
-        }))
-        .attach(rocket::fairing::AdHoc::on_response(|req, _res| {
-            println!("[REQUEST] {} {}", req.method(), req.uri());
-        }));
-    }
-    {
-        server.launch();
-    }
+	let server = server::create_server(args.clone(), swerve_config.clone());
+	server.launch();
 }
\ No newline at end of file
diff --git a/src/routing/core.rs b/src/routing/core.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a847d1dae81df0f8bd6342ebe0c12ec47bf94fea
--- /dev/null
+++ b/src/routing/core.rs
@@ -0,0 +1,35 @@
+use cli;
+use std::fs;
+use std::path;
+use rocket::{self, http::ContentType};
+use routing::request::TypedFile;
+
+#[get("/")]
+fn serve_root(args: rocket::State<cli::Args>) -> Option<TypedFile> {
+    serve_files(None, args)
+}
+
+#[get("/<file..>")]
+fn serve_files(file: Option<path::PathBuf>, args: rocket::State<cli::Args>) -> Option<TypedFile> {
+    let stub = match file {
+        Some(path) => path,
+        None => path::PathBuf::from(""),
+    };
+
+    let path = args.get_dir().join(stub);
+
+    let meta = match fs::metadata(&path) {
+        Ok(metadata) => metadata,
+        _ => return None,
+    };
+
+    if meta.is_dir() && !args.flag_no_index {
+        Some(TypedFile::open(path.join("index.html"), None))
+    } else {
+        if &path.extension().unwrap().to_string_lossy() == "wasm" {
+           Some( TypedFile::open(path, Some(ContentType::new("application", "wasm"))))
+        } else {
+            Some(TypedFile::open(path, None))
+        }
+    }
+}
diff --git a/src/routing/mod.rs b/src/routing/mod.rs
index b7054b18f5f05411ac7ed75c68e51f918937b6ec..d3fa15ff5030dccc4162756be7c3e0f264472775 100644
--- a/src/routing/mod.rs
+++ b/src/routing/mod.rs
@@ -1,3 +1,4 @@
 pub mod mock_upload;
 pub mod request;
-pub mod scripting;
\ No newline at end of file
+pub mod scripting;
+pub mod core;
diff --git a/src/routing/request.rs b/src/routing/request.rs
index 0ebd52b826307a61b380ed6d630983a8a6d084a4..643abe5ddd56afc24fc01c5970e9bc72b5ea768c 100644
--- a/src/routing/request.rs
+++ b/src/routing/request.rs
@@ -1,6 +1,10 @@
+use rocket::{self, Outcome, http, Response};
 use rocket::request::{FromRequest, Request};
-use rocket::{Outcome, http};
+use rocket::http::ContentType;
 use hyper::header::Headers;
+use std::path::{Path, PathBuf};
+use std::io::BufReader;
+use std::fs::File;
 
 #[derive(Debug)]
 pub struct ConvertedHeaders {
@@ -26,4 +30,30 @@ impl <'a, 'req>FromRequest<'a, 'req> for ConvertedHeaders {
             inner: hyper_headers
         })
     }
-}
\ No newline at end of file
+}
+
+pub struct TypedFile {
+    file: File,
+    content_type: Option<ContentType>,
+    path: PathBuf,
+}
+
+impl TypedFile {
+    pub fn open<P: AsRef<Path>>(path: P, content_type: Option<rocket::http::ContentType>) -> TypedFile {
+        let file = File::open(path.as_ref()).unwrap();
+        TypedFile { file, content_type, path: (*path.as_ref()).to_path_buf() }
+    }
+}
+
+impl rocket::response::Responder<'static> for TypedFile {
+    fn respond_to(self, _: &Request) -> Result<Response<'static>, rocket::http::Status> {
+        let mut response = Response::new();
+        if let Some(content_type) = self.content_type {
+            response.set_header(content_type);
+        } else {
+            response.set_header(ContentType::from_extension(&self.path.extension().unwrap().to_string_lossy()).unwrap());
+        }
+        response.set_streamed_body(BufReader::new(self.file));
+        Ok(response)
+    }
+}
diff --git a/src/server/mod.rs b/src/server/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..1604eface9ba9609f408325378e3fa55eac7927d
--- /dev/null
+++ b/src/server/mod.rs
@@ -0,0 +1,3 @@
+mod server;
+
+pub use self::server::create_server;
\ No newline at end of file
diff --git a/src/server/server.rs b/src/server/server.rs
new file mode 100644
index 0000000000000000000000000000000000000000..37a1b9453d9ddb28ee397b4b369509eb4c239f63
--- /dev/null
+++ b/src/server/server.rs
@@ -0,0 +1,63 @@
+use rocket::{self, Rocket, Config};
+use cli::{Args, SwerveConfig};
+use routing;
+
+pub fn create_server(args: Args, config: SwerveConfig) -> Rocket {
+	let server_config = server_config_from_input(args.clone(), config.clone());
+	let mut server = Rocket::custom(server_config, false)
+		.manage(args.clone())
+		.manage(config.clone());
+
+	let quiet = args.flag_quiet;
+
+    if let Some(ref upload_path) = args.flag_upload_path {
+        if !quiet { println!("[SETUP] Accepting uploads at {}", upload_path) }
+        server = server.mount(upload_path, routes![routing::mock_upload::to_file]);
+    } else if args.flag_upload {
+        if !quiet { println!("[SETUP] Accepting uploads at /upload") }
+        server = server.mount("/upload", routes![routing::mock_upload::to_file]);
+    }
+
+	server = server.mount("/", routes![
+		routing::core::serve_root,
+		routing::core::serve_files,
+		routing::scripting::route_script
+	]);
+
+
+	if !quiet {
+		server = server.attach(rocket::fairing::AdHoc::on_launch(move |rckt| {
+			let conf = rckt.config();
+			println!("[SETUP] Swerve is configured with {} worker threads", conf.workers);
+			println!("[SETUP] Swerving files from http://{}:{}\n", conf.address, conf.port);
+		}))
+		.attach(rocket::fairing::AdHoc::on_response(|req, _res| {
+			println!("[REQUEST] {} {}", req.method(), req.uri());
+		}));
+	}
+
+	server
+}
+
+fn server_config_from_input(args: Args, config: SwerveConfig) -> Config {
+    let mut builder = Config::build(rocket::config::Environment::Development);
+    if let Some(threads) = args.flag_threads {
+        builder = builder.workers(threads);
+    } else {
+        builder = builder.workers(config.server.threads);
+    }
+
+    if let Some(port) = args.flag_port {
+        builder = builder.port(port);
+    } else {
+        builder = builder.port(config.server.port);
+    }
+
+    if let Some(address) = args.flag_address {
+        builder = builder.address(address);
+    } else {
+        builder = builder.address(config.server.address);
+    }
+
+    builder.finalize().unwrap()
+}
\ No newline at end of file