diff --git a/.gitignore b/.gitignore
index 14621f0..87cbec8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,7 +16,8 @@
 *.out
 
 # Dependency directories (remove the comment below to include it)
-# vendor/
+!vendor/modules.txt
+vendor/**/*
 
 # Go workspace file
 go.work
diff --git a/flake.nix b/flake.nix
index 6f9fbf8..75560a1 100644
--- a/flake.nix
+++ b/flake.nix
@@ -8,26 +8,50 @@
     utils.lib.eachDefaultSystem (system:
       let
         pkgs = import nixpkgs { inherit system; };
+        name = "recored-ui";
+        version = "v1.0.0";
       in
       {
-        packages = rec {
-          recored-ui = with pkgs; stdenv.mkDerivation rec {
-            name = "recored-ui";
+        defaultPackage = with pkgs; let
+          web = buildNpmPackage {
+            inherit version;
+            pname = name;
+            src = "${self}/web";
+            npmDepsHash = "sha256-e4AYJa0PXhuBRytH4860v6t3DEcQ5awR24HeXRD5pew=";
+          };
+          app = buildGoModule {
+            pname = name;
+            inherit version;
+
             src = self;
-            buildInputs = [
-              go
-              nodejs
+
+            ldflags = [
+              "-s"
+              "-w"
             ];
-            buildPhase = ''
-              cd web && npm i && npm run build && cd ..
-              go get . && go generate ./... && go build . -o recored-ui -ldflags "-s -w"
+
+            configurePhase = ''
+              cp -r ${web}/lib/node_modules/web/dist server
+              export HOME=/tmp/build
             '';
+
             installPhase = ''
               mkdir -p $out/bin
               cp recored-ui $out/bin
             '';
+
+            doCheck = false;
+            deleteVendor = true;
+            proxyVendor = true;
           };
-          default = recored-ui;
+        in
+        stdenv.mkDerivation {
+          name = "${name}-${version}";
+          src = self;
+          installPhase = ''
+            mkdir -p $out/bin
+            cp ${app}/bin/recored-ui $out/bin
+          '';
         };
 
         devShell = with pkgs; mkShell {
@@ -68,7 +92,7 @@
                 environment = {
                   RECORED_MYSQL_DSN = cfg.mysql-dsn;
                 };
-                serviceconfig.ExecStart = "${pkgs.recored-ui}/bin/recored-ui server";
+                serviceconfig.ExecStart = "${defaultPackage}/bin/recored-ui server";
               };
             };
           };
diff --git a/vendor/modules.txt b/vendor/modules.txt
deleted file mode 100644
index a4a60db..0000000
--- a/vendor/modules.txt
+++ /dev/null
@@ -1,413 +0,0 @@
-# github.com/BurntSushi/toml v1.3.2
-## explicit; go 1.16
-github.com/BurntSushi/toml
-github.com/BurntSushi/toml/internal
-# github.com/KyleBanks/depth v1.2.1
-## explicit
-github.com/KyleBanks/depth
-# github.com/apparentlymart/go-cidr v1.1.0
-## explicit
-github.com/apparentlymart/go-cidr/cidr
-# github.com/beorn7/perks v1.0.1
-## explicit; go 1.11
-github.com/beorn7/perks/quantile
-# github.com/bytedance/sonic v1.11.3
-## explicit; go 1.16
-github.com/bytedance/sonic
-github.com/bytedance/sonic/ast
-github.com/bytedance/sonic/decoder
-github.com/bytedance/sonic/encoder
-github.com/bytedance/sonic/internal/abi
-github.com/bytedance/sonic/internal/caching
-github.com/bytedance/sonic/internal/cpu
-github.com/bytedance/sonic/internal/decoder
-github.com/bytedance/sonic/internal/encoder
-github.com/bytedance/sonic/internal/jit
-github.com/bytedance/sonic/internal/native
-github.com/bytedance/sonic/internal/native/avx
-github.com/bytedance/sonic/internal/native/avx2
-github.com/bytedance/sonic/internal/native/neon
-github.com/bytedance/sonic/internal/native/sse
-github.com/bytedance/sonic/internal/native/types
-github.com/bytedance/sonic/internal/resolver
-github.com/bytedance/sonic/internal/rt
-github.com/bytedance/sonic/loader
-github.com/bytedance/sonic/option
-github.com/bytedance/sonic/unquote
-github.com/bytedance/sonic/utf8
-# github.com/cespare/xxhash/v2 v2.2.0
-## explicit; go 1.11
-github.com/cespare/xxhash/v2
-# github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d
-## explicit; go 1.16
-github.com/chenzhuoyu/base64x
-# github.com/chenzhuoyu/iasm v0.9.1
-## explicit; go 1.16
-github.com/chenzhuoyu/iasm/expr
-github.com/chenzhuoyu/iasm/x86_64
-# github.com/cloud66-oss/coredns_mysql v0.0.0-20231116193749-de52e2924a6f
-## explicit; go 1.16
-github.com/cloud66-oss/coredns_mysql
-# github.com/coredns/caddy v1.1.0
-## explicit; go 1.13
-github.com/coredns/caddy
-github.com/coredns/caddy/caddyfile
-# github.com/coredns/coredns v1.8.4
-## explicit; go 1.16
-github.com/coredns/coredns/core/dnsserver
-github.com/coredns/coredns/pb
-github.com/coredns/coredns/plugin
-github.com/coredns/coredns/plugin/etcd/msg
-github.com/coredns/coredns/plugin/metrics/vars
-github.com/coredns/coredns/plugin/pkg/cidr
-github.com/coredns/coredns/plugin/pkg/dnsutil
-github.com/coredns/coredns/plugin/pkg/doh
-github.com/coredns/coredns/plugin/pkg/edns
-github.com/coredns/coredns/plugin/pkg/log
-github.com/coredns/coredns/plugin/pkg/nonwriter
-github.com/coredns/coredns/plugin/pkg/parse
-github.com/coredns/coredns/plugin/pkg/rcode
-github.com/coredns/coredns/plugin/pkg/response
-github.com/coredns/coredns/plugin/pkg/reuseport
-github.com/coredns/coredns/plugin/pkg/trace
-github.com/coredns/coredns/plugin/pkg/transport
-github.com/coredns/coredns/request
-# github.com/cpuguy83/go-md2man/v2 v2.0.2
-## explicit; go 1.11
-github.com/cpuguy83/go-md2man/v2/md2man
-# github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
-## explicit
-github.com/flynn/go-shlex
-# github.com/gabriel-vasile/mimetype v1.4.3
-## explicit; go 1.20
-github.com/gabriel-vasile/mimetype
-github.com/gabriel-vasile/mimetype/internal/charset
-github.com/gabriel-vasile/mimetype/internal/json
-github.com/gabriel-vasile/mimetype/internal/magic
-# github.com/gin-contrib/sse v0.1.0
-## explicit; go 1.12
-github.com/gin-contrib/sse
-# github.com/gin-gonic/gin v1.9.1
-## explicit; go 1.20
-github.com/gin-gonic/gin
-github.com/gin-gonic/gin/binding
-github.com/gin-gonic/gin/internal/bytesconv
-github.com/gin-gonic/gin/internal/json
-github.com/gin-gonic/gin/render
-# github.com/go-openapi/jsonpointer v0.21.0
-## explicit; go 1.20
-github.com/go-openapi/jsonpointer
-# github.com/go-openapi/jsonreference v0.21.0
-## explicit; go 1.20
-github.com/go-openapi/jsonreference
-github.com/go-openapi/jsonreference/internal
-# github.com/go-openapi/spec v0.21.0
-## explicit; go 1.20
-github.com/go-openapi/spec
-# github.com/go-openapi/swag v0.23.0
-## explicit; go 1.20
-github.com/go-openapi/swag
-# github.com/go-playground/locales v0.14.1
-## explicit; go 1.17
-github.com/go-playground/locales
-github.com/go-playground/locales/currency
-# github.com/go-playground/universal-translator v0.18.1
-## explicit; go 1.18
-github.com/go-playground/universal-translator
-# github.com/go-playground/validator/v10 v10.19.0
-## explicit; go 1.18
-github.com/go-playground/validator/v10
-# github.com/go-sql-driver/mysql v1.7.0
-## explicit; go 1.13
-github.com/go-sql-driver/mysql
-# github.com/goccy/go-json v0.10.2
-## explicit; go 1.12
-github.com/goccy/go-json
-github.com/goccy/go-json/internal/decoder
-github.com/goccy/go-json/internal/encoder
-github.com/goccy/go-json/internal/encoder/vm
-github.com/goccy/go-json/internal/encoder/vm_color
-github.com/goccy/go-json/internal/encoder/vm_color_indent
-github.com/goccy/go-json/internal/encoder/vm_indent
-github.com/goccy/go-json/internal/errors
-github.com/goccy/go-json/internal/runtime
-# github.com/golang/protobuf v1.5.3
-## explicit; go 1.9
-github.com/golang/protobuf/proto
-github.com/golang/protobuf/ptypes
-github.com/golang/protobuf/ptypes/any
-github.com/golang/protobuf/ptypes/duration
-github.com/golang/protobuf/ptypes/timestamp
-# github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645
-## explicit
-github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc
-# github.com/huandu/go-clone v1.7.2
-## explicit; go 1.13
-github.com/huandu/go-clone
-# github.com/huandu/go-clone/generic v1.7.2
-## explicit; go 1.18
-github.com/huandu/go-clone/generic
-# github.com/jinzhu/inflection v1.0.0
-## explicit
-github.com/jinzhu/inflection
-# github.com/jinzhu/now v1.1.5
-## explicit; go 1.12
-github.com/jinzhu/now
-# github.com/josharian/intern v1.0.0
-## explicit; go 1.5
-github.com/josharian/intern
-# github.com/json-iterator/go v1.1.12
-## explicit; go 1.12
-github.com/json-iterator/go
-# github.com/klauspost/cpuid/v2 v2.2.7
-## explicit; go 1.15
-github.com/klauspost/cpuid/v2
-# github.com/leodido/go-urn v1.4.0
-## explicit; go 1.18
-github.com/leodido/go-urn
-github.com/leodido/go-urn/scim/schema
-# github.com/mailru/easyjson v0.7.7
-## explicit; go 1.12
-github.com/mailru/easyjson/buffer
-github.com/mailru/easyjson/jlexer
-github.com/mailru/easyjson/jwriter
-# github.com/mattn/go-isatty v0.0.20
-## explicit; go 1.15
-github.com/mattn/go-isatty
-# github.com/miekg/dns v1.1.42
-## explicit; go 1.14
-github.com/miekg/dns
-# github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
-## explicit
-github.com/modern-go/concurrent
-# github.com/modern-go/reflect2 v1.0.2
-## explicit; go 1.12
-github.com/modern-go/reflect2
-# github.com/opentracing/opentracing-go v1.2.0
-## explicit; go 1.14
-github.com/opentracing/opentracing-go
-github.com/opentracing/opentracing-go/ext
-github.com/opentracing/opentracing-go/log
-# github.com/pelletier/go-toml/v2 v2.2.1
-## explicit; go 1.16
-github.com/pelletier/go-toml/v2
-github.com/pelletier/go-toml/v2/internal/characters
-github.com/pelletier/go-toml/v2/internal/danger
-github.com/pelletier/go-toml/v2/internal/tracker
-github.com/pelletier/go-toml/v2/unstable
-# github.com/prometheus/client_golang v1.19.0
-## explicit; go 1.20
-github.com/prometheus/client_golang/prometheus
-github.com/prometheus/client_golang/prometheus/internal
-github.com/prometheus/client_golang/prometheus/promauto
-github.com/prometheus/client_golang/prometheus/promhttp
-github.com/prometheus/client_golang/prometheus/push
-# github.com/prometheus/client_model v0.5.0
-## explicit; go 1.19
-github.com/prometheus/client_model/go
-# github.com/prometheus/common v0.48.0
-## explicit; go 1.20
-github.com/prometheus/common/expfmt
-github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg
-github.com/prometheus/common/model
-# github.com/prometheus/procfs v0.12.0
-## explicit; go 1.19
-github.com/prometheus/procfs
-github.com/prometheus/procfs/internal/fs
-github.com/prometheus/procfs/internal/util
-# github.com/russross/blackfriday/v2 v2.1.0
-## explicit
-github.com/russross/blackfriday/v2
-# github.com/sirupsen/logrus v1.9.3
-## explicit; go 1.13
-github.com/sirupsen/logrus
-# github.com/swaggo/files v1.0.1
-## explicit; go 1.16
-github.com/swaggo/files
-# github.com/swaggo/gin-swagger v1.6.0
-## explicit; go 1.17
-github.com/swaggo/gin-swagger
-# github.com/swaggo/swag v1.16.3
-## explicit; go 1.18
-github.com/swaggo/swag
-# github.com/twitchyliquid64/golang-asm v0.15.1
-## explicit; go 1.13
-github.com/twitchyliquid64/golang-asm/asm/arch
-github.com/twitchyliquid64/golang-asm/bio
-github.com/twitchyliquid64/golang-asm/dwarf
-github.com/twitchyliquid64/golang-asm/goobj
-github.com/twitchyliquid64/golang-asm/obj
-github.com/twitchyliquid64/golang-asm/obj/arm
-github.com/twitchyliquid64/golang-asm/obj/arm64
-github.com/twitchyliquid64/golang-asm/obj/mips
-github.com/twitchyliquid64/golang-asm/obj/ppc64
-github.com/twitchyliquid64/golang-asm/obj/riscv
-github.com/twitchyliquid64/golang-asm/obj/s390x
-github.com/twitchyliquid64/golang-asm/obj/wasm
-github.com/twitchyliquid64/golang-asm/obj/x86
-github.com/twitchyliquid64/golang-asm/objabi
-github.com/twitchyliquid64/golang-asm/src
-github.com/twitchyliquid64/golang-asm/sys
-github.com/twitchyliquid64/golang-asm/unsafeheader
-# github.com/ugorji/go/codec v1.2.12
-## explicit; go 1.11
-github.com/ugorji/go/codec
-# github.com/urfave/cli/v2 v2.27.1
-## explicit; go 1.18
-github.com/urfave/cli/v2
-github.com/urfave/cli/v2/altsrc
-# github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673
-## explicit
-github.com/xrash/smetrics
-# github.com/zsais/go-gin-prometheus v0.1.0
-## explicit
-github.com/zsais/go-gin-prometheus
-# golang.org/x/arch v0.7.0
-## explicit; go 1.18
-golang.org/x/arch/x86/x86asm
-# golang.org/x/crypto v0.22.0
-## explicit; go 1.18
-golang.org/x/crypto/sha3
-# golang.org/x/net v0.24.0
-## explicit; go 1.18
-golang.org/x/net/bpf
-golang.org/x/net/context
-golang.org/x/net/html
-golang.org/x/net/html/atom
-golang.org/x/net/http/httpguts
-golang.org/x/net/http2
-golang.org/x/net/http2/h2c
-golang.org/x/net/http2/hpack
-golang.org/x/net/idna
-golang.org/x/net/internal/iana
-golang.org/x/net/internal/socket
-golang.org/x/net/internal/timeseries
-golang.org/x/net/ipv4
-golang.org/x/net/ipv6
-golang.org/x/net/trace
-golang.org/x/net/webdav
-golang.org/x/net/webdav/internal/xml
-# golang.org/x/sys v0.19.0
-## explicit; go 1.18
-golang.org/x/sys/cpu
-golang.org/x/sys/unix
-golang.org/x/sys/windows
-# golang.org/x/text v0.14.0
-## explicit; go 1.18
-golang.org/x/text/internal/language
-golang.org/x/text/internal/language/compact
-golang.org/x/text/internal/tag
-golang.org/x/text/language
-golang.org/x/text/secure/bidirule
-golang.org/x/text/transform
-golang.org/x/text/unicode/bidi
-golang.org/x/text/unicode/norm
-# golang.org/x/tools v0.20.0
-## explicit; go 1.19
-golang.org/x/tools/go/ast/astutil
-golang.org/x/tools/go/buildutil
-golang.org/x/tools/go/internal/cgo
-golang.org/x/tools/go/loader
-golang.org/x/tools/internal/versions
-# google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384
-## explicit; go 1.11
-google.golang.org/genproto/googleapis/rpc/status
-# google.golang.org/grpc v1.38.0
-## explicit; go 1.11
-google.golang.org/grpc
-google.golang.org/grpc/attributes
-google.golang.org/grpc/backoff
-google.golang.org/grpc/balancer
-google.golang.org/grpc/balancer/base
-google.golang.org/grpc/balancer/grpclb/state
-google.golang.org/grpc/balancer/roundrobin
-google.golang.org/grpc/binarylog/grpc_binarylog_v1
-google.golang.org/grpc/codes
-google.golang.org/grpc/connectivity
-google.golang.org/grpc/credentials
-google.golang.org/grpc/encoding
-google.golang.org/grpc/encoding/proto
-google.golang.org/grpc/grpclog
-google.golang.org/grpc/internal
-google.golang.org/grpc/internal/backoff
-google.golang.org/grpc/internal/balancerload
-google.golang.org/grpc/internal/binarylog
-google.golang.org/grpc/internal/buffer
-google.golang.org/grpc/internal/channelz
-google.golang.org/grpc/internal/credentials
-google.golang.org/grpc/internal/envconfig
-google.golang.org/grpc/internal/grpclog
-google.golang.org/grpc/internal/grpcrand
-google.golang.org/grpc/internal/grpcsync
-google.golang.org/grpc/internal/grpcutil
-google.golang.org/grpc/internal/metadata
-google.golang.org/grpc/internal/resolver
-google.golang.org/grpc/internal/resolver/dns
-google.golang.org/grpc/internal/resolver/passthrough
-google.golang.org/grpc/internal/resolver/unix
-google.golang.org/grpc/internal/serviceconfig
-google.golang.org/grpc/internal/status
-google.golang.org/grpc/internal/syscall
-google.golang.org/grpc/internal/transport
-google.golang.org/grpc/internal/transport/networktype
-google.golang.org/grpc/keepalive
-google.golang.org/grpc/metadata
-google.golang.org/grpc/peer
-google.golang.org/grpc/resolver
-google.golang.org/grpc/serviceconfig
-google.golang.org/grpc/stats
-google.golang.org/grpc/status
-google.golang.org/grpc/tap
-# google.golang.org/protobuf v1.33.0
-## explicit; go 1.17
-google.golang.org/protobuf/encoding/protodelim
-google.golang.org/protobuf/encoding/prototext
-google.golang.org/protobuf/encoding/protowire
-google.golang.org/protobuf/internal/descfmt
-google.golang.org/protobuf/internal/descopts
-google.golang.org/protobuf/internal/detrand
-google.golang.org/protobuf/internal/editiondefaults
-google.golang.org/protobuf/internal/encoding/defval
-google.golang.org/protobuf/internal/encoding/messageset
-google.golang.org/protobuf/internal/encoding/tag
-google.golang.org/protobuf/internal/encoding/text
-google.golang.org/protobuf/internal/errors
-google.golang.org/protobuf/internal/filedesc
-google.golang.org/protobuf/internal/filetype
-google.golang.org/protobuf/internal/flags
-google.golang.org/protobuf/internal/genid
-google.golang.org/protobuf/internal/impl
-google.golang.org/protobuf/internal/order
-google.golang.org/protobuf/internal/pragma
-google.golang.org/protobuf/internal/set
-google.golang.org/protobuf/internal/strs
-google.golang.org/protobuf/internal/version
-google.golang.org/protobuf/proto
-google.golang.org/protobuf/reflect/protodesc
-google.golang.org/protobuf/reflect/protoreflect
-google.golang.org/protobuf/reflect/protoregistry
-google.golang.org/protobuf/runtime/protoiface
-google.golang.org/protobuf/runtime/protoimpl
-google.golang.org/protobuf/types/descriptorpb
-google.golang.org/protobuf/types/gofeaturespb
-google.golang.org/protobuf/types/known/anypb
-google.golang.org/protobuf/types/known/durationpb
-google.golang.org/protobuf/types/known/timestamppb
-# gopkg.in/yaml.v3 v3.0.1
-## explicit
-gopkg.in/yaml.v3
-# gorm.io/driver/mysql v1.5.6
-## explicit; go 1.14
-gorm.io/driver/mysql
-# gorm.io/gorm v1.25.7
-## explicit; go 1.18
-gorm.io/gorm
-gorm.io/gorm/callbacks
-gorm.io/gorm/clause
-gorm.io/gorm/logger
-gorm.io/gorm/migrator
-gorm.io/gorm/schema
-gorm.io/gorm/utils
-# gorm.io/plugin/prometheus v0.1.0
-## explicit; go 1.14
-gorm.io/plugin/prometheus