diff --git a/index.php b/index.php
index 431a44f39118628b7aaa7737fb394b2fa31c2a68..ee5a905f0d1b96f01a4fe55bbd7afa24cb0c2bb3 100644
--- a/index.php
+++ b/index.php
@@ -1,5 +1,6 @@
 <?php
 
+use app\App;
 use app\base\BaseController;
 
 spl_autoload_register(function ($className) {
@@ -12,3 +13,5 @@ spl_autoload_register(function ($className) {
   $class = __DIR__ . "/src/" . "{$className}.php";
   include_once($class);
 });
+
+$app = new App();
diff --git a/src/App.php b/src/App.php
new file mode 100644
index 0000000000000000000000000000000000000000..98d70b07b2ee61ff68dfac60b10f9b277daac578
--- /dev/null
+++ b/src/App.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace app;
+
+use app\Router;
+use app\base\BaseController;
+use app\controllers\MainController;
+use app\repositories\UserRepository;
+use app\services\UserService;
+
+class App
+{
+  protected $router;
+
+  function __construct()
+  {
+    $this->router = new Router();
+    $this->init_router();
+    $this->router->dispatch();
+  }
+
+  function init_router()
+  {
+    $this->router->addRoute('/', MainController::getInstance());
+    // $this->router->addRoute('/', new BaseController(new UserService(new UserRepository())));
+  }
+}
diff --git a/src/Request.php b/src/Request.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca8c5c38d347cdd9d88e2b5450e433b1e4af3764
--- /dev/null
+++ b/src/Request.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace app;
+
+class Request
+{
+  public static function getURL()
+  {
+    return parse_url($_SERVER['REQUEST_URI'])['path'];
+  }
+
+  public static function getMethod()
+  {
+    return $_SERVER['REQUEST_METHOD'];
+  }
+
+  public static function getParams()
+  {
+    $params = $_SERVER['REQUEST_URI'];
+    $params = explode("?", $params);
+    $params = array_slice($params, 1);
+    if (empty($params)) {
+      return [];
+    }
+    return $params;
+  }
+}
diff --git a/src/Router.php b/src/Router.php
new file mode 100644
index 0000000000000000000000000000000000000000..731f441d4854377221c5a6fbf6a2b483e991a05d
--- /dev/null
+++ b/src/Router.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace app;
+
+use app\controllers;
+use app\Request as AppRequest;
+
+class Router
+{
+  protected $routes = [];
+
+  function addRoute(string $route, $controller)
+  {
+    $this->routes[$route] = $controller;
+  }
+
+  public function dispatch()
+  {
+    $uri = AppRequest::getURL();
+    $method = AppRequest::getMethod();
+    $params = AppRequest::getParams();
+
+    if (isset($this->routes[$uri])) {
+      return $this->routes[$uri]->handle($method, $params);
+    }
+  }
+}
+
+// $r = new Router();
+
+// $r->dispatch();
diff --git a/src/base/BaseController.php b/src/base/BaseController.php
index 44cd8a5bc802171e8012cef506648b2d698337c7..5de245a9a40595ef70b43f18ac0a809ef9fa2c3a 100644
--- a/src/base/BaseController.php
+++ b/src/base/BaseController.php
@@ -43,7 +43,19 @@ abstract class BaseController
 
   public function handle($method, $urlParams)
   {
-    $lowMethod = strtolower($method);
-    echo $this->$lowMethod($urlParams);
+    $to_lower_method = strtolower($method);
+    echo $this->$to_lower_method($urlParams);
+  }
+
+  protected static function render($data, $view, $layout)
+  {
+    extract($data);
+    ob_start();
+    include_once __DIR__ . "/../../views/{$view}.php";
+    $content = ob_get_clean();
+
+    $data["__content"] = $content;
+    extract($data);
+    include_once __DIR__ . "/../../views/{$layout}.php";
   }
 }
diff --git a/src/controllers/MainController.php b/src/controllers/MainController.php
new file mode 100644
index 0000000000000000000000000000000000000000..5afc1913ea99b5ddc36089f4633da23471f50e76
--- /dev/null
+++ b/src/controllers/MainController.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace app\controllers;
+
+use app\base\BaseController;
+use app\exceptions\MethodNotAllowedException;
+use Exception;
+
+class MainController extends BaseController
+{
+
+  protected function __construct()
+  {
+    parent::__construct(null);
+  }
+
+  protected function get($urlParams)
+  {
+    try {
+      // parent::get($urlParams);
+
+      // echo "params is ";
+      // var_dump($urlParams);
+      parent::render($urlParams, "home", "layouts/base");
+    } catch (Exception $e) {
+      echo $e;
+    }
+  }
+  protected function post($urlParams)
+  {
+    try {
+      parent::put($urlParams);
+    } catch (Exception $e) {
+      echo $e;
+    }
+  }
+  protected function put($urlParams)
+  {
+    try {
+      parent::put($urlParams);
+    } catch (Exception $e) {
+      echo $e;
+    }
+  }
+  protected function delete($urlParams)
+  {
+    try {
+      parent::delete($urlParams);
+    } catch (Exception $e) {
+      echo $e;
+    }
+  }
+}
diff --git a/views/home.php b/views/home.php
new file mode 100644
index 0000000000000000000000000000000000000000..86f9f5469140d769dca1e39c60942157332f801e
--- /dev/null
+++ b/views/home.php
@@ -0,0 +1,5 @@
+<div>
+  <h1>
+    HOME
+  </h1>
+</div>
\ No newline at end of file
diff --git a/views/layouts/base.php b/views/layouts/base.php
index a81436628ee704d656ba217b034c1adbf3dc4835..3c98aee1fe0e8bc5ba8a52f530c17d56f2f5cf72 100644
--- a/views/layouts/base.php
+++ b/views/layouts/base.php
@@ -1 +1,26 @@
-<?php
\ No newline at end of file
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <!-- <link rel="stylesheet" href="public/css/lib.css">
+  <link rel="stylesheet" href="public/css/shared.css">
+  <link rel="stylesheet" href="public/css/home.css"> -->
+  <!-- <title>Document</title> -->
+</head>
+
+<body>
+  <nav>
+
+  </nav>
+
+  <main>
+    <h1>hai!!!</h1>
+    <?= $__content ?>
+  </main>
+
+</body>
+
+</html>
\ No newline at end of file