diff --git a/reconstruct/CMakeLists.txt b/reconstruct/CMakeLists.txt
index 2b463475ac1c58618dfb6f8ff928bad167f7309d..78ce7d52c79333e4b237c1fe7aa9b1c0a764bcd6 100644
--- a/reconstruct/CMakeLists.txt
+++ b/reconstruct/CMakeLists.txt
@@ -4,14 +4,14 @@ include_directories(${PROJECT_SOURCE_DIR}/reconstruct/include)
 
 
 set(REPSRC
-	../common/cpp/src/config.cpp
 	src/main.cpp
 )
 
 add_executable(ftl-reconstruct ${REPSRC})
 add_dependencies(ftl-reconstruct ftlnet)
+add_dependencies(ftl-reconstruct ftlcommon)
 
 #target_include_directories(cv-node PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(ftl-reconstruct Threads::Threads ZLIB::ZLIB ${OpenCV_LIBS} glog::glog ftlnet ftlrender)
+target_link_libraries(ftl-reconstruct ftlcommon Threads::Threads ZLIB::ZLIB ${OpenCV_LIBS} glog::glog ftlnet ftlrender)
 
 
diff --git a/reconstruct/src/main.cpp b/reconstruct/src/main.cpp
index 1885d8c397e9fa69456ffb2722dc5796d62bc490..02f915a938730181a6fe97e1097c5768c3169c82 100644
--- a/reconstruct/src/main.cpp
+++ b/reconstruct/src/main.cpp
@@ -6,13 +6,12 @@
 
 #include <glog/logging.h>
 #include <ftl/config.h>
+#include <ftl/configuration.hpp>
 #include <zlib.h>
 // #include <lz4.h>
 
 #include <string>
-#include <map>
 #include <vector>
-#include <fstream>
 #include <thread>
 #include <chrono>
 #include <mutex>
@@ -33,90 +32,17 @@
 
 using ftl::net::Universe;
 using ftl::Display;
+using ftl::config;
 using std::string;
 using std::vector;
-using std::map;
 using cv::Mat;
 using json = nlohmann::json;
-using std::ifstream;
 using std::this_thread::sleep_for;
 using std::chrono::milliseconds;
 using std::mutex;
 using std::unique_lock;
 
-// Store loaded configuration
-static json config;
-
-/**
- * Find and load a JSON configuration file
- */
-static bool findConfiguration(const string &file) {
-	ifstream i;
-	
-	if (file != "") i.open(file);
-	if (!i.is_open()) i.open("./config.json");
-	if (!i.is_open()) i.open(FTL_LOCAL_CONFIG_ROOT "/config.json");
-	if (!i.is_open()) i.open(FTL_GLOBAL_CONFIG_ROOT "/config.json");
-	if (!i.is_open()) return false;
-	i >> config;
-	config = config["representation"];
-	return true;
-}
-
-/**
- * Generate a map from command line option to value
- */
-map<string, string> read_options(char ***argv, int *argc) {
-	map<string, string> opts;
-
-	while (*argc > 0) {
-		string cmd((*argv)[0]);
-		if (cmd[0] != '-') break;
-
-		size_t p;
-		if ((p = cmd.find("=")) == string::npos) {
-			opts[cmd.substr(2)] = "true";
-		} else {
-			opts[cmd.substr(2, p-2)] = cmd.substr(p+1);
-		}
-
-		(*argc)--;
-		(*argv)++;
-	}
-
-	return opts;
-}
-
-/**
- * Put command line options into json config. If config element does not exist
- * or is of a different type then report an error.
- */
-static void process_options(const map<string, string> &opts) {
-	for (auto opt : opts) {
-		if (opt.first == "config") continue;
-
-		if (opt.first == "version") {
-			std::cout << "FTL Vision Node - v" << FTL_VERSION << std::endl;
-			std::cout << FTL_VERSION_LONG << std::endl;
-			exit(0);
-		}
-
-		try {
-			auto ptr = json::json_pointer("/"+opt.first);
-			// TODO(nick) Allow strings without quotes
-			auto v = json::parse(opt.second);
-			if (v.type() != config.at(ptr).type()) {
-				LOG(ERROR) << "Incorrect type for argument " << opt.first;
-				continue;
-			}
-			config.at(ptr) = v;
-		} catch(...) {
-			LOG(ERROR) << "Unrecognised option: " << opt.first;
-		}
-	}
-}
-
-static void run(const string &file) {
+static void run() {
 	Universe net(config["net"]);
 	Mat rgb, depth, Q;
 	mutex m;
@@ -188,16 +114,7 @@ static void run(const string &file) {
 }
 
 int main(int argc, char **argv) {
-	argc--;
-	argv++;
-
-	// Process Arguments
-	auto options = read_options(&argv, &argc);
-	if (!findConfiguration(options["config"])) {
-		LOG(FATAL) << "Could not find any configuration!";
-	}
-	process_options(options);
-
-	run((argc > 0) ? argv[0] : "");
+	ftl::configure(argc, argv, "representation"); // TODO(nick) change to "reconstruction"
+	run();
 }