diff --git a/.github/workflows/release_freebsd.yml b/.github/workflows/release_freebsd.yml
new file mode 100644
index 00000000..46afb326
--- /dev/null
+++ b/.github/workflows/release_freebsd.yml
@@ -0,0 +1,35 @@
+name: release_freebsd
+
+on:
+  release:
+    types: [ published ]
+
+jobs:
+  release_freebsd:
+    strategy:
+      matrix:
+        platform: [ ubuntu-latest ]
+        go-version: [ '1.21' ]
+    name: Release
+    runs-on: ${{ matrix.platform }}
+    steps:
+
+      - name: Setup Go
+        uses: actions/setup-go@v5
+        with:
+          go-version: ${{ matrix.go-version }}
+
+      - name: Checkout
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+
+      - name: Build
+        run: |
+          bash build.sh release freebsd
+
+      - name: Upload assets
+        uses: softprops/action-gh-release@v2
+        with:
+          tag_name: dev
+          files: build/compress/*
diff --git a/build.sh b/build.sh
index 6b28847c..a87eabf4 100644
--- a/build.sh
+++ b/build.sh
@@ -233,6 +233,29 @@ BuildReleaseAndroid() {
   done
 }
 
+BuildReleaseFreeBSD() {
+  rm -rf .git/
+  mkdir -p "build/freebsd"
+  OS_ARCHES=(amd64 arm64 i386)
+  GO_ARCHES=(amd64 arm64 386)
+  CGO_ARGS=(x86_64-unknown-freebsd14.1 aarch64-unknown-freebsd14.1 i386-unknown-freebsd14.1)
+  for i in "${!OS_ARCHES[@]}"; do
+    os_arch=${OS_ARCHES[$i]}
+    cgo_cc="clang --target=${CGO_ARGS[$i]} --sysroot=/opt/freebsd/${os_arch}"
+    echo building for freebsd-${os_arch}
+    sudo mkdir -p "/opt/freebsd/${os_arch}"
+    wget -q https://download.freebsd.org/releases/${os_arch}/14.1-RELEASE/base.txz
+    sudo tar -xf ./base.txz -C /opt/freebsd/${os_arch}
+    rm base.txz
+    export GOOS=freebsd
+    export GOARCH=${GO_ARCHES[$i]}
+    export CC=${cgo_cc}
+    export CGO_ENABLED=1
+    export CGO_LDFLAGS="-fuse-ld=lld"
+    go build -o ./build/$appName-freebsd-$os_arch -ldflags="$ldflags" -tags=jsoniter .
+  done
+}
+
 MakeRelease() {
   cd build
   mkdir compress
@@ -251,6 +274,11 @@ MakeRelease() {
     tar -czvf compress/"$i".tar.gz alist
     rm -f alist
   done
+  for i in $(find . -type f -name "$appName-freebsd-*"); do
+    cp "$i" alist
+    tar -czvf compress/"$i".tar.gz alist
+    rm -f alist
+  done
   for i in $(find . -type f -name "$appName-windows-*"); do
     cp "$i" alist.exe
     zip compress/$(echo $i | sed 's/\.[^.]*$//').zip alist.exe
@@ -288,6 +316,9 @@ elif [ "$1" = "release" ]; then
   elif [ "$2" = "android" ]; then
     BuildReleaseAndroid
     MakeRelease "md5-android.txt"
+  elif [ "$2" = "freebsd" ]; then
+    BuildReleaseFreeBSD
+    MakeRelease "md5-freebsd.txt"
   elif [ "$2" = "web" ]; then
     echo "web only"
   else