diff --git a/hp.asd b/hp.asd
index 8e99742..6099a5d 100644
--- a/hp.asd
+++ b/hp.asd
@@ -4,5 +4,7 @@
   :defsystem-depends-on ("wild-package-inferred-system")
   :class "winfer:wild-package-inferred-system"
   :pathname "src"
-  :depends-on ("hp/main")
+  :depends-on ("hp/app")
   :in-order-to ((test-op (test-op "hp-tests"))))
+
+(register-system-packages "lack-middleware-accesslog" '(:lack.middleware.accesslog))
diff --git a/public/js/alpine.min.js b/public/js/alpine.js
similarity index 100%
rename from public/js/alpine.min.js
rename to public/js/alpine.js
diff --git a/public/js/htmx.min.js b/public/js/htmx.js
similarity index 100%
rename from public/js/htmx.min.js
rename to public/js/htmx.js
diff --git a/public/style/main.css b/public/style/main.css
index 0b01ec3..059805d 100644
--- a/public/style/main.css
+++ b/public/style/main.css
@@ -1,6 +1,5 @@
 @charset "utf-8";
 
 body {
-	height: 100svh;
-	width: 100%;
+	display: block;
 }
\ No newline at end of file
diff --git a/qlfile b/qlfile
index 9af0d3f..cd41e75 100644
--- a/qlfile
+++ b/qlfile
@@ -1,8 +1,5 @@
 ql wild-package-inferred-system
 ql fiveam
-ql alexandria
-ql lack
-ql clack
 ql cl-jingle
 git piccolo https://github.com/skyizwhite/piccolo.git
 git ningle-fbr https://github.com/skyizwhite/ningle-fbr.git
diff --git a/qlfile.lock b/qlfile.lock
index 1176ebe..d7ab4a7 100644
--- a/qlfile.lock
+++ b/qlfile.lock
@@ -10,18 +10,6 @@
  (:class qlot/source/ql:source-ql
   :initargs (:%version :latest)
   :version "ql-2023-10-21"))
-("alexandria" .
- (:class qlot/source/ql:source-ql
-  :initargs (:%version :latest)
-  :version "ql-2023-10-21"))
-("lack" .
- (:class qlot/source/ql:source-ql
-  :initargs (:%version :latest)
-  :version "ql-2023-10-21"))
-("clack" .
- (:class qlot/source/ql:source-ql
-  :initargs (:%version :latest)
-  :version "ql-2023-10-21"))
 ("cl-jingle" .
  (:class qlot/source/ql:source-ql
   :initargs (:%version :latest)
@@ -29,8 +17,8 @@
 ("piccolo" .
  (:class qlot/source/git:source-git
   :initargs (:remote-url "https://github.com/skyizwhite/piccolo.git")
-  :version "git-2ae90c290e86a81f608ce0bced119896cc12b6bf"))
+  :version "git-4fd887fc1bff812f10e57aca8011166f0b6a8c6d"))
 ("ningle-fbr" .
  (:class qlot/source/git:source-git
   :initargs (:remote-url "https://github.com/skyizwhite/ningle-fbr.git")
-  :version "git-68c3e0494da254fb39e6b5d0f4b54343f72dd13c"))
+  :version "git-438030b0b89dc706c37932616e6bf82d0416ea26"))
diff --git a/src/app.lisp b/src/app.lisp
index 28b33f4..a46a420 100644
--- a/src/app.lisp
+++ b/src/app.lisp
@@ -1,42 +1,38 @@
-(uiop:define-package #:hp/app
+(defpackage #:hp
+  (:nicknames #:hp/app)
   (:use #:cl)
   (:local-nicknames (#:jg #:jingle))
   (:local-nicknames (#:fbr #:ningle-fbr))
   (:local-nicknames (#:pi #:piccolo))
-  (:local-nicknames (#:cmp #:hp/components/*))
-  (:import-from #:lack)
-  (:export #:*app*
-           #:update-routes))
-(in-package #:hp/app)
+  (:local-nicknames (#:view #:hp/view))
+  (:local-nicknames (#:cmp #:hp/components/**/*))
+  (:import-from #:lack.middleware.accesslog
+                #:*lack-middleware-accesslog*)
+  (:export #:start
+           #:stop
+           #:update))
+(in-package #:hp)
 
-(defparameter *raw-app* (jg:make-app))
+(defparameter *app* (jg:make-app :address "localhost"
+                                 :port 3000))
 
 (defmethod jg:not-found ((app jg:app))
-  (jg:with-html-response
-    (jg:set-response-status 404)
-    (pi:element-string (cmp:not-found-page))))
+  (view:render-page (cmp:not-found-page)
+                     :status :not-found
+                     :title "404 Not Found"
+                     :description "お探しのページは見つかりませんでした。"))
 
-(defun update-routes ()
-  (fbr:enable-file-based-routing *raw-app*
-                                 :system "hp"
-                                 :directory "src/routes"))
+(defun update ()
+  (jg:clear-middlewares *app*)
+  (jg:install-middleware *app* *lack-middleware-accesslog*)
+  (jg:static-path *app* "/public/" "public/")
+  (fbr:assign-routes *app*
+                     :system "hp"
+                     :directory "src/routes"))
+(update)
 
-(update-routes)
+(defun start ()
+  (jg:start *app*))
 
-(defun exist-public-file-p (path)
-  (let ((pathname (probe-file (concatenate 'string "public" path))))
-    (and pathname
-         (pathname-name pathname))))
-
-(defparameter *app*
-  (lack:builder :accesslog
-                (:static
-                 :path (lambda (path)
-                         (if (exist-public-file-p path) 
-                             path
-                             nil))
-                 :root (asdf:system-relative-pathname :hp "public/"))
-                *raw-app*))
-
-; for clackup cmd
-*app*
+(defun stop ()
+  (jg:stop *app*))
diff --git a/src/components/global/document.lisp b/src/components/global/document.lisp
new file mode 100644
index 0000000..d899cef
--- /dev/null
+++ b/src/components/global/document.lisp
@@ -0,0 +1,12 @@
+(defpackage #:hp/components/global/document
+  (:use #:cl)
+  (:local-nicknames (#:pi #:piccolo))
+  (:export #:document))
+(in-package #:hp/components/global/document)
+
+(pi:define-element document (metadata)
+  (pi:h
+    (html :lang "ja"
+      metadata
+      (body :hx-ext "head-support"
+        pi:children))))
diff --git a/src/components/global/layout.lisp b/src/components/global/layout.lisp
new file mode 100644
index 0000000..908468a
--- /dev/null
+++ b/src/components/global/layout.lisp
@@ -0,0 +1,9 @@
+(defpackage #:hp/components/global/layout
+  (:use #:cl)
+  (:local-nicknames (#:pi #:piccolo))
+  (:export #:layout))
+(in-package #:hp/components/global/layout)
+
+(pi:define-element layout ()
+  (pi:h
+    (main pi:children)))
diff --git a/src/components/global/metadata.lisp b/src/components/global/metadata.lisp
new file mode 100644
index 0000000..2d349b0
--- /dev/null
+++ b/src/components/global/metadata.lisp
@@ -0,0 +1,18 @@
+(defpackage #:hp/components/global/metadata
+  (:use #:cl)
+  (:local-nicknames (#:pi #:piccolo))
+  (:export #:metadata))
+(in-package #:hp/components/global/metadata)
+
+(pi:define-element metadata (title description)
+  (pi:h
+    (head
+      (meta :charset "UTF-8")
+      (title (format nil "~@[~a | ~]skyizwhite.dev" title))
+      (meta
+        :name "description"
+        :content (or description "pakuの個人サイト"))
+      (script :src "/public/js/htmx.js")
+      (script :src "/public/js/htmx-ext/head-support.js")
+      (script :src "/public/js/alpine.js" :defer t)
+      (link :rel "stylesheet" :type "text/css" :href "/public/style/main.css"))))
diff --git a/src/components/global/not-found.lisp b/src/components/global/not-found.lisp
new file mode 100644
index 0000000..3ec74e9
--- /dev/null
+++ b/src/components/global/not-found.lisp
@@ -0,0 +1,10 @@
+(defpackage #:hp/components/global/not-found
+  (:use #:cl)
+  (:local-nicknames (#:pi #:piccolo))
+  (:export #:not-found-page))
+(in-package #:hp/components/global/not-found)
+
+(pi:define-element not-found-page ()
+  (pi:h
+    (section
+      (h1 "404 Not Found"))))
diff --git a/src/components/layout.lisp b/src/components/layout.lisp
deleted file mode 100644
index 2c0f372..0000000
--- a/src/components/layout.lisp
+++ /dev/null
@@ -1,18 +0,0 @@
-(uiop:define-package #:hp/components/layout
-  (:use #:cl)
-  (:local-nicknames (#:pi #:piccolo))
-  (:export #:layout))
-(in-package #:hp/components/layout)
-
-(pi:define-element layout ()
-  (pi:h
-    (html
-      (head
-        (title "skyizwhite.dev")
-        (script :src "/js/htmx.min.js")
-        (script :src "/js/htmx-ext/head-support.js")
-        (script :src "/js/alpine.min.js" :defer t)
-        (link :rel "stylesheet" :href "/style/main.css" type="text/css"))
-      (body :hx-ext "head-support"
-        (main
-          pi:children)))))
diff --git a/src/components/not-found.lisp b/src/components/not-found.lisp
deleted file mode 100644
index 42d9b37..0000000
--- a/src/components/not-found.lisp
+++ /dev/null
@@ -1,13 +0,0 @@
-(uiop:define-package #:hp/components/not-found
-  (:use #:cl)
-  (:local-nicknames (#:pi #:piccolo))
-  (:import-from #:hp/components/layout
-                #:layout)
-  (:export #:not-found-page))
-(in-package #:hp/components/not-found)
-
-(pi:define-element not-found-page ()
-  (pi:h
-    (layout
-      (section
-        (h1 "404 Not Found")))))
diff --git a/src/main.lisp b/src/main.lisp
deleted file mode 100644
index d083199..0000000
--- a/src/main.lisp
+++ /dev/null
@@ -1,27 +0,0 @@
-(uiop:define-package :hp
-  (:nicknames #:hp/main)
-  (:use #:cl)
-  (:import-from #:clack)
-  (:import-from #:hp/app
-                #:*app*
-                #:update-routes)
-  (:export #:start-server
-           #:stop-server
-           #:update-routes))
-(in-package :hp)
-
-(defparameter *server* nil)
-
-(defun start-server ()
-  (if *server*
-      (format t "Server is already running.~%")
-      (setf *server* (clack:clackup *app*
-                                    :address "localhost"
-                                    :port 3000))))
-
-(defun stop-server ()
-  (if *server*
-      (prog1 
-          (clack:stop *server*)
-        (setf *server* nil))
-      (format t "No servers running.~%")))
diff --git a/src/routes/about.lisp b/src/routes/about.lisp
new file mode 100644
index 0000000..480b84a
--- /dev/null
+++ b/src/routes/about.lisp
@@ -0,0 +1,21 @@
+(defpackage #:hp/routes/about
+  (:use #:cl)
+  (:local-nicknames (#:pi #:piccolo))
+  (:local-nicknames (#:view #:hp/view))
+  (:export #:on-get))
+(in-package #:hp/routes/about)
+
+;;; View
+
+(pi:define-element page ()
+  (pi:h
+    (section
+      (h1 "About"))))
+
+;;; Controller
+
+(defun on-get (params)
+  (declare (ignore params))
+  (view:render-page (page)
+                     :title "about"
+                     :description "pakuの自己紹介"))
diff --git a/src/routes/index.lisp b/src/routes/index.lisp
index 8c69922..77cb87b 100644
--- a/src/routes/index.lisp
+++ b/src/routes/index.lisp
@@ -1,8 +1,7 @@
-(uiop:define-package #:hp/routes/index
+(defpackage #:hp/routes/index
   (:use #:cl)
   (:local-nicknames (#:pi #:piccolo))
-  (:local-nicknames (#:jg #:jingle))
-  (:local-nicknames (#:cmp #:hp/components/*))
+  (:local-nicknames (#:view #:hp/view))
   (:export #:on-get))
 (in-package #:hp/routes/index)
 
@@ -10,11 +9,13 @@
 
 (pi:define-element page ()
   (pi:h
-    (div)))
+    (section
+      (h1 "Hello, World!")
+      (a :href "/about" :hx-boost "true"
+        "About"))))
 
 ;;; Controller
 
 (defun on-get (params)
   (declare (ignore params))
-  (jg:with-html-response
-    (pi:element-string (page))))
+  (view:render-page (page)))
diff --git a/src/view.lisp b/src/view.lisp
new file mode 100644
index 0000000..6b35c39
--- /dev/null
+++ b/src/view.lisp
@@ -0,0 +1,18 @@
+(defpackage #:hp/view
+  (:use #:cl)
+  (:local-nicknames (#:jg #:jingle))
+  (:local-nicknames (#:pi #:piccolo))
+  (:local-nicknames (#:cmp #:hp/components/**/*))
+  (:export #:render-page))
+(in-package #:hp/view)
+
+(defun render-page (page &key status title description)
+  (jg:with-html-response
+    (and status (jg:set-response-status status))
+    (pi:elem-str
+     (let ((md (cmp:metadata :title title :description description))
+           (body (cmp:layout page)))
+       (if (jg:get-request-header "HX-Boosted")
+           (pi:h (<> md body))
+           (pi:h (cmp:document :metadata md
+                   body)))))))
diff --git a/tests/example.lisp b/tests/example.lisp
index 90aae3e..faf4574 100644
--- a/tests/example.lisp
+++ b/tests/example.lisp
@@ -1,4 +1,4 @@
-(uiop:define-package #:hp-tests/example
+(defpackage #:hp-tests/example
   (:use #:cl
         #:fiveam))
 (in-package #:hp-tests/example)