diff --git a/.ci/boost.sh b/.ci/boost.sh
deleted file mode 100755
index fa62525fd3edfb08159cfca01a689e691ff4c7b9..0000000000000000000000000000000000000000
--- a/.ci/boost.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-
-set -evx
-
-sudo wget -O boost_1_66_0.tar.gz http://sourceforge.net/projects/boost/files/boost/1.66.0/boost_1_66_0.tar.gz/download
-sudo tar xzf boost_1_66_0.tar.gz
-
-cd boost_1_66_0/
-sudo ./bootstrap.sh --with-libraries=random,thread,system --prefix=/usr/local
-sudo ./b2 -d0 variant=debug link=shared
-sudo ./b2 -d0 install 
-
diff --git a/.ci/gtest.sh b/.ci/gtest.sh
deleted file mode 100755
index 8dd7084c1957d8f62c5a83973d14c2675feb0607..0000000000000000000000000000000000000000
--- a/.ci/gtest.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env bash
-
-set -evx
-
-sudo apt-get -qq update
-sudo apt-get install -y libgtest-dev
-wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz
-tar xf release-1.8.0.tar.gz
-cd googletest-release-1.8.0
-
-cmake -DBUILD_SHARED_LIBS=ON .
-make
-sudo cp -a googletest/include/gtest /usr/include
-sudo cp -a googlemock/gtest/*.so /usr/lib/
-
-sudo ldconfig -v | grep gtest
-
-cd $TRAVIS_BUILD_DIR
-
diff --git a/.gitignore b/.gitignore
index 2f134baacee11810b04b75d9f336b545f2548e15..b7e32f925d07589309668308c7ce742614ff613c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,6 @@ compile_commands.json
 
 # Synapse data
 data/
+
+# Deps
+.third-party
diff --git a/.travis.yml b/.travis.yml
index fe2cf1db684bc1ca23e55cdba7a3f9d6b44b689c..cc87bfe279b8807c63f0a2d42edeea63fe90df9f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -57,9 +57,6 @@ matrix:
             - "g++-7"
 
 install:
-  - if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew upgrade boost; fi
-  - if [ $TRAVIS_OS_NAME == linux ]; then ./.ci/gtest.sh; fi
-  - if [ $TRAVIS_OS_NAME == linux ]; then ./.ci/boost.sh; fi
   - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:george-edison55/cmake-3.x; fi
   - if [ $TRAVIS_OS_NAME == linux ]; then sudo apt-get update -qq; fi
   - if [ $TRAVIS_OS_NAME == linux ]; then sudo apt-get install -qq -y cmake; fi
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d509ab315c8456a3402edd80391d3187920b1366..911d8df6ed9ad530223fb20ccf60074f3b49fe04 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,26 +40,47 @@ if(NOT APPLE AND NOT MSVC)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
 endif()
 
+#
+# OpenSSL
+#
+find_package(OpenSSL REQUIRED)
+include_directories(${OPENSSL_INCLUDE_DIR})
+
+#
+# Boost 1.66
+#
+# If we can't find an already installed version we will
+# download it and build it from source.
+#
 set(Boost_USE_STATIC_LIBS OFF)
 set(Boost_USE_MULTITHREADED ON)
-find_package(Boost 1.66 REQUIRED)
+find_package(Boost 1.66)
 find_package(Boost 1.66 COMPONENTS system random thread)
 
-find_package(OpenSSL REQUIRED)
+if(NOT Boost_FOUND)
+    message(STATUS "Fetching and building Boost 1.66")
+    include(${CMAKE_SOURCE_DIR}/cmake/Boost.cmake)
+endif()
 
 include_directories(${Boost_INCLUDE_DIRS})
-include_directories(${OPENSSL_INCLUDE_DIR})
-include_directories(src)
 
+#
+# matrix-structs
+#
 add_subdirectory(libs/matrix-structs)
 include_directories(${matrix_structs_SOURCE_DIR}/include)
 include_directories(${matrix_structs_SOURCE_DIR}/deps)
 
+include_directories(src)
 set(SRC src/client.cpp src/utils.cpp)
 
 add_library(matrix_client ${SRC})
 target_link_libraries(matrix_client matrix_structs ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES})
 
+if(NOT Boost_FOUND)
+    add_dependencies(matrix_client Boost)
+endif()
+
 if (BUILD_LIB_EXAMPLES)
     add_executable(room_feed examples/room_feed.cpp)
     target_link_libraries(room_feed matrix_client matrix_structs)
@@ -68,7 +89,13 @@ endif()
 if (BUILD_LIB_TESTS)
     enable_testing()
 
-    find_package(GTest REQUIRED)
+    find_package(GTest)
+
+    if (NOT GTest_FOUND)
+        message(STATUS "Fetching and building GTest 1.8")
+        include(${CMAKE_SOURCE_DIR}/cmake/GoogleTest.cmake)
+    endif()
+
     include_directories(${GTEST_INCLUDE_DIRS})
 
     add_executable(client_api tests/client_api.cpp)
@@ -86,6 +113,11 @@ if (BUILD_LIB_TESTS)
     add_executable(connection tests/connection.cpp)
     target_link_libraries(connection matrix_client ${GTEST_BOTH_LIBRARIES})
 
+    if (NOT GTest_FOUND)
+        add_dependencies(client_api GTest)
+        add_dependencies(connection GTest)
+    endif()
+
     add_test(BasicConnectivity connection)
     add_test(ClientAPI client_api)
 endif()
diff --git a/cmake/Boost.cmake b/cmake/Boost.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..84aa4a7d663bb35ff66518bf7b4b720bf2ce9ff7
--- /dev/null
+++ b/cmake/Boost.cmake
@@ -0,0 +1,31 @@
+include(ExternalProject)
+
+#
+# Download & install Boost from source.
+#
+
+set(THIRD_PARTY_ROOT ${CMAKE_SOURCE_DIR}/.third-party)
+set(BUNDLED_BOOST_ROOT ${THIRD_PARTY_ROOT}/boost_1_66_0)
+
+ExternalProject_Add(
+  Boost
+
+  URL https://sourceforge.net/projects/boost/files/boost/1.66.0/boost_1_66_0.tar.bz2/download
+  URL_HASH SHA1=b6b284acde2ad7ed49b44e856955d7b1ea4e9459
+  DOWNLOAD_DIR ${THIRD_PARTY_ROOT}/downloads
+  DOWNLOAD_NO_PROGRESS 0
+
+  BUILD_IN_SOURCE 1
+  SOURCE_DIR ${BUNDLED_BOOST_ROOT}
+  CONFIGURE_COMMAND ${BUNDLED_BOOST_ROOT}/bootstrap.sh
+    --with-libraries=random,thread,system
+    --prefix=${BUNDLED_BOOST_ROOT}
+  BUILD_COMMAND ${BUNDLED_BOOST_ROOT}/b2 -d0 variant=release link=static threading=multi
+  INSTALL_COMMAND ${BUNDLED_BOOST_ROOT}/b2 -d0 install
+)
+
+set(Boost_INCLUDE_DIRS ${BUNDLED_BOOST_ROOT})
+set(Boost_LIBRARIES boost_random boost_system boost_thread)
+
+include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
+link_directories(${Boost_INCLUDE_DIRS}/stage/lib)
diff --git a/cmake/GoogleTest.cmake b/cmake/GoogleTest.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..d8e295a3c507ace01d8550acbb161db66c8e9028
--- /dev/null
+++ b/cmake/GoogleTest.cmake
@@ -0,0 +1,28 @@
+include(ExternalProject)
+
+#
+# Download & install Google Test from source.
+#
+
+set(THIRD_PARTY_ROOT ${CMAKE_SOURCE_DIR}/.third-party)
+set(BUNDLED_GTEST_ROOT ${THIRD_PARTY_ROOT}/gtest_1_8_0)
+
+ExternalProject_Add(
+  GTest
+
+  URL https://github.com/google/googletest/archive/release-1.8.0.tar.gz
+  URL_HASH SHA1=e7e646a6204638fe8e87e165292b8dd9cd4c36ed
+  DOWNLOAD_DIR ${THIRD_PARTY_ROOT}/downloads
+  DOWNLOAD_NO_PROGRESS 0
+
+  BUILD_IN_SOURCE 1
+  SOURCE_DIR ${BUNDLED_GTEST_ROOT}
+  CONFIGURE_COMMAND ${CMAKE_COMMAND} ${BUNDLED_GTEST_ROOT}
+  BUILD_COMMAND make
+  INSTALL_COMMAND ""
+)
+
+set(GTEST_BOTH_LIBRARIES gtest gtest_main)
+
+include_directories(SYSTEM ${BUNDLED_GTEST_ROOT}/googletest/include)
+link_directories(${BUNDLED_GTEST_ROOT}/googlemock/gtest)