diff --git a/README.md b/README.md
index 27584c82c..678898a20 100644
--- a/README.md
+++ b/README.md
@@ -12,3 +12,9 @@ git clone https://github.com/espressif/esp32-arduino-lib-builder
 cd esp32-arduino-lib-builder
 ./build.sh
 ```
+
+### Recreate esp32-arduino libs in given version
+Create version-v#.#.#.sh based on `framework-arduinoespressif32/tools/sdk/versions.txt`
+```bash
+./build.sh -I v4.4.2 -r -t esp32s2
+```
diff --git a/build.sh b/build.sh
index 29790fcfa..e2f5b86f0 100755
--- a/build.sh
+++ b/build.sh
@@ -15,6 +15,7 @@ BUILD_TYPE="all"
 SKIP_ENV=0
 COPY_OUT=0
 DEPLOY_OUT=0
+RECREATE=0
 
 function print_help() {
     echo "Usage: build.sh [-s] [-A <arduino_branch>] [-I <idf_branch>] [-i <idf_commit>] [-c <path>] [-t <target>] [-b <build|menuconfig|idf_libs|copy_bootloader|mem_variant>] [config ...]"
@@ -26,12 +27,16 @@ function print_help() {
     echo "       -c     Set the arduino-esp32 folder to copy the result to. ex. '$HOME/Arduino/hardware/espressif/esp32'"
     echo "       -t     Set the build target(chip). ex. 'esp32s3'"
     echo "       -b     Set the build type. ex. 'build' to build the project and prepare for uploading to a board"
+    echo "       -r     Recreate arduino-esp32 libs in give version"
     echo "       ...    Specify additional configs to be applied. ex. 'qio 80m' to compile for QIO Flash@80MHz. Requires -b"
     exit 1
 }
 
-while getopts ":A:I:i:c:t:b:sd" opt; do
+while getopts ":A:I:i:c:t:b:sdr" opt; do
     case ${opt} in
+        r )
+            export RECREATE=1
+            ;;
         s )
             SKIP_ENV=1
             ;;
@@ -78,6 +83,11 @@ done
 shift $((OPTIND -1))
 CONFIGS=$@
 
+if [ $RECREATE -eq 1 -a -z "$IDF_BRANCH" ]; then
+    echo "RECREATE requires IDF_BRANCH"
+    exit 1
+fi
+
 if [ $SKIP_ENV -eq 0 ]; then
     echo "* Installing/Updating ESP-IDF and all components..."
     # update components from git
diff --git a/tools/git-update.sh b/tools/git-update.sh
new file mode 100755
index 000000000..6f23ce352
--- /dev/null
+++ b/tools/git-update.sh
@@ -0,0 +1,24 @@
+set -e
+
+SUBMODULE=0
+
+while getopts "s" opt; do
+    case ${opt} in
+        s)
+            SUBMODULE=1
+            ;;
+    esac
+done
+shift $((OPTIND-1))
+
+DIR=$1
+URL=$2
+VERSION=$3
+
+[ -d "$DIR" ] || git clone $URL "$DIR"
+git -C "$DIR" fetch
+[ -n "$VERSION" ] && git -C "$DIR" checkout $VERSION
+git -C "$DIR" symbolic-ref -q HEAD && git -C "$DIR" pull --ff-only
+[ $SUBMODULE -eq 1 ] && git -C "$DIR" submodule update --init --recursive
+
+exit 0
diff --git a/tools/update-components.sh b/tools/update-components.sh
index 41149c000..b95eb2499 100755
--- a/tools/update-components.sh
+++ b/tools/update-components.sh
@@ -1,5 +1,7 @@
 #/bin/bash
 
+set -e
+
 source ./tools/config.sh
 
 CAMERA_REPO_URL="https://github.com/espressif/esp32-camera.git"
@@ -10,142 +12,81 @@ DSP_REPO_URL="https://github.com/espressif/esp-dsp.git"
 LITTLEFS_REPO_URL="https://github.com/joltwallet/esp_littlefs.git"
 TINYUSB_REPO_URL="https://github.com/hathach/tinyusb.git"
 
+if [ -n "$RECREATE" ]; then
+	VERSION="./tools/version-$IDF_BRANCH.sh"
+	if [ ! -f "$VERSION" ]; then
+		echo "$VERSION does not exists"
+		exit 1
+	fi
+	source $VERSION
+fi
+
 #
 # CLONE/UPDATE ARDUINO
 #
-
-if [ ! -d "$AR_COMPS/arduino" ]; then
-	git clone $AR_REPO_URL "$AR_COMPS/arduino"
-fi
-
-if [ -z $AR_BRANCH ]; then
-	if [ -z $GITHUB_HEAD_REF ]; then
-		current_branch=`git branch --show-current`
-	else
-		current_branch="$GITHUB_HEAD_REF"
+if [ -z "AR_REPO_VERSION" ]; then
+	if [ ! -d "$AR_COMPS/arduino" ]; then
+		git clone $AR_REPO_URL "$AR_COMPS/arduino"
 	fi
-	echo "Current Branch: $current_branch"
-	if [[ "$current_branch" != "master" && `git_branch_exists "$AR_COMPS/arduino" "$current_branch"` == "1" ]]; then
-		export AR_BRANCH="$current_branch"
-	else
-		if [ -z "$IDF_COMMIT" ]; then #commit was not specified at build time
-			AR_BRANCH_NAME="idf-$IDF_BRANCH"
+
+	if [ -z $AR_BRANCH ]; then
+		if [ -z $GITHUB_HEAD_REF ]; then
+			current_branch=`git branch --show-current`
 		else
-			AR_BRANCH_NAME="idf-$IDF_COMMIT"
+			current_branch="$GITHUB_HEAD_REF"
 		fi
-		has_ar_branch=`git_branch_exists "$AR_COMPS/arduino" "$AR_BRANCH_NAME"`
-		if [ "$has_ar_branch" == "1" ]; then
-			export AR_BRANCH="$AR_BRANCH_NAME"
+		echo "Current Branch: $current_branch"
+		if [[ "$current_branch" != "master" && `git_branch_exists "$AR_COMPS/arduino" "$current_branch"` == "1" ]]; then
+			export AR_BRANCH="$current_branch"
 		else
-			has_ar_branch=`git_branch_exists "$AR_COMPS/arduino" "$AR_PR_TARGET_BRANCH"`
+			if [ -z "$IDF_COMMIT" ]; then #commit was not specified at build time
+				AR_BRANCH_NAME="idf-$IDF_BRANCH"
+			else
+				AR_BRANCH_NAME="idf-$IDF_COMMIT"
+			fi
+			has_ar_branch=`git_branch_exists "$AR_COMPS/arduino" "$AR_BRANCH_NAME"`
 			if [ "$has_ar_branch" == "1" ]; then
-				export AR_BRANCH="$AR_PR_TARGET_BRANCH"
+				export AR_BRANCH="$AR_BRANCH_NAME"
+			else
+				has_ar_branch=`git_branch_exists "$AR_COMPS/arduino" "$AR_PR_TARGET_BRANCH"`
+				if [ "$has_ar_branch" == "1" ]; then
+					export AR_BRANCH="$AR_PR_TARGET_BRANCH"
+				fi
 			fi
 		fi
 	fi
-fi
 
-if [ "$AR_BRANCH" ]; then
-	git -C "$AR_COMPS/arduino" checkout "$AR_BRANCH" && \
-	git -C "$AR_COMPS/arduino" fetch && \
-	git -C "$AR_COMPS/arduino" pull --ff-only
+	if [ "$AR_BRANCH" ]; then
+		git -C "$AR_COMPS/arduino" checkout "$AR_BRANCH"
+		git -C "$AR_COMPS/arduino" fetch
+		git -C "$AR_COMPS/arduino" pull --ff-only
+	fi
+else
+	./tools/git-update.sh "$AR_COMPS/arduino" $AR_REPO_URL $AR_REPO_VERSION
 fi
-if [ $? -ne 0 ]; then exit 1; fi
 
-#
 # CLONE/UPDATE ESP32-CAMERA
-#
+./tools/git-update.sh "$AR_COMPS/esp32-camera" $CAMERA_REPO_URL $CAMERA_REPO_VERSION
 
-if [ ! -d "$AR_COMPS/esp32-camera" ]; then
-	git clone $CAMERA_REPO_URL "$AR_COMPS/esp32-camera"
-else
-	git -C "$AR_COMPS/esp32-camera" fetch && \
-	git -C "$AR_COMPS/esp32-camera" pull --ff-only
-fi
 #this is a temp measure to fix build issue in recent IDF master
 if [ -f "$AR_COMPS/esp32-camera/idf_component.yml" ]; then
 	rm -rf "$AR_COMPS/esp32-camera/idf_component.yml"
 fi
-if [ $? -ne 0 ]; then exit 1; fi
 
-#
 # CLONE/UPDATE ESP-DL
-#
+./tools/git-update.sh "$AR_COMPS/esp-dl" $DL_REPO_URL $DL_REPO_VERSION
 
-if [ ! -d "$AR_COMPS/esp-dl" ]; then
-	git clone $DL_REPO_URL "$AR_COMPS/esp-dl"
-else
-	git -C "$AR_COMPS/esp-dl" fetch && \
-	git -C "$AR_COMPS/esp-dl" pull --ff-only
-fi
-if [ $? -ne 0 ]; then exit 1; fi
-
-#
 # CLONE/UPDATE ESP-SR
-#
+./tools/git-update.sh "$AR_COMPS/esp-sr" $SR_REPO_URL $SR_REPO_VERSION
 
-if [ ! -d "$AR_COMPS/esp-sr" ]; then
-	git clone $SR_REPO_URL "$AR_COMPS/esp-sr"
-else
-	git -C "$AR_COMPS/esp-sr" fetch && \
-	git -C "$AR_COMPS/esp-sr" pull --ff-only
-fi
-if [ $? -ne 0 ]; then exit 1; fi
-
-#
 # CLONE/UPDATE ESP-LITTLEFS
-#
-
-if [ ! -d "$AR_COMPS/esp_littlefs" ]; then
-	git clone $LITTLEFS_REPO_URL "$AR_COMPS/esp_littlefs" && \
-    git -C "$AR_COMPS/esp_littlefs" submodule update --init --recursive
-else
-	git -C "$AR_COMPS/esp_littlefs" fetch && \
-	git -C "$AR_COMPS/esp_littlefs" pull --ff-only && \
-    git -C "$AR_COMPS/esp_littlefs" submodule update --init --recursive
-fi
-if [ $? -ne 0 ]; then exit 1; fi
+./tools/git-update.sh -s "$AR_COMPS/esp_littlefs" $LITTLEFS_REPO_URL $LITTLEFS_REPO_VERSION
 
-#
 # CLONE/UPDATE ESP-RAINMAKER
-#
-
-if [ ! -d "$AR_COMPS/esp-rainmaker" ]; then
-    git clone $RMAKER_REPO_URL "$AR_COMPS/esp-rainmaker" && \
-    git -C "$AR_COMPS/esp-rainmaker" submodule update --init --recursive
-    # git -C "$AR_COMPS/esp-rainmaker" checkout f1b82c71c4536ab816d17df016d8afe106bd60e3
-else
-	git -C "$AR_COMPS/esp-rainmaker" fetch && \
-	git -C "$AR_COMPS/esp-rainmaker" pull --ff-only && \
-    git -C "$AR_COMPS/esp-rainmaker" submodule update --init --recursive
-fi
-if [ $? -ne 0 ]; then exit 1; fi
+./tools/git-update.sh -s "$AR_COMPS/esp-rainmaker" $RMAKER_REPO_URL $RMAKER_REPO_VERSION
 
-#
 # CLONE/UPDATE ESP-DSP
-#
-
-if [ ! -d "$AR_COMPS/esp-dsp" ]; then
-	git clone $DSP_REPO_URL "$AR_COMPS/esp-dsp"
-	# cml=`cat "$AR_COMPS/esp-dsp/CMakeLists.txt"`
-	# echo "if(IDF_TARGET STREQUAL \"esp32\" OR IDF_TARGET STREQUAL \"esp32s2\" OR IDF_TARGET STREQUAL \"esp32s3\")" > "$AR_COMPS/esp-dsp/CMakeLists.txt"
-	# echo "$cml" >> "$AR_COMPS/esp-dsp/CMakeLists.txt"
-	# echo "endif()" >> "$AR_COMPS/esp-dsp/CMakeLists.txt"
-else
-	git -C "$AR_COMPS/esp-dsp" fetch && \
-	git -C "$AR_COMPS/esp-dsp" pull --ff-only
-fi
-if [ $? -ne 0 ]; then exit 1; fi
+./tools/git-update.sh "$AR_COMPS/esp-dsp" $DSP_REPO_URL $DSP_REPO_VERSION
 
-#
 # CLONE/UPDATE TINYUSB
-#
-
-if [ ! -d "$AR_COMPS/arduino_tinyusb/tinyusb" ]; then
-	git clone $TINYUSB_REPO_URL "$AR_COMPS/arduino_tinyusb/tinyusb"
-else
-	git -C "$AR_COMPS/arduino_tinyusb/tinyusb" fetch && \
-	git -C "$AR_COMPS/arduino_tinyusb/tinyusb" pull --ff-only
-fi
-if [ $? -ne 0 ]; then exit 1; fi
-
+./tools/git-update.sh "$AR_COMPS/arduino_tinyusb/tinyusb" $TINYUSB_REPO_URL $TINYUSB_REPO_VERSION
diff --git a/tools/version-v4.4.2.sh b/tools/version-v4.4.2.sh
new file mode 100644
index 000000000..826344860
--- /dev/null
+++ b/tools/version-v4.4.2.sh
@@ -0,0 +1,8 @@
+AR_REPO_VERSION=55d608e3
+CAMERA_REPO_VERSION=5611989
+DL_REPO_VERSION=f3006d7
+SR_REPO_VERSION=b578f17
+RMAKER_REPO_VERSION=3736c12
+DSP_REPO_VERSION=401faf8
+LITTLEFS_REPO_VERSION=485a037
+TINYUSB_REPO_VERSION=111515a29