diff --git a/.github/workflows/per-starter-release.yml b/.github/workflows/per-starter-release.yml
new file mode 100644
index 0000000..39d31e2
--- /dev/null
+++ b/.github/workflows/per-starter-release.yml
@@ -0,0 +1,42 @@
+# .github/workflows/release-template.yml
+
+name: Release All Starters
+
+on:
+ workflow_dispatch: # Allows manual trigger
+ push:
+ tags:
+ - 'v*.*.*' # Triggers on tags like v1.0.0
+
+jobs:
+ build-and-release:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Get version from tag
+ id: get_version
+ run: |
+ TAG="${GITHUB_REF##*/}"
+ VERSION="${TAG#v}"
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
+
+ - name: Zip all starter directories
+ run: |
+ mkdir -p dist
+ for dir in angular astro-shadcn bolt-expo bolt-qwik bolt-remotion bolt-vite-react-ts bootstrap-5 egg express-simple graphql gsap-next gsap-nuxt gsap-react gsap-svelte gsap-sveltekit gsap-vue hono-nodejs-starter js nextjs nextjs-shadcn node nodemon quasar react-ts react rxjs slidev static sveltekit tres tutorialkit typescript vite-shadcn vue web-platform; do
+ if [ -d "$dir" ]; then
+ zip -r "dist/$dir-${{ steps.get_version.outputs.version }}.zip" "$dir" -x "$dir/node_modules/*"
+ fi
+ done
+
+ - name: Create GitHub Release
+ uses: softprops/action-gh-release@v1
+ with:
+ tag_name: ${{ github.ref_name }}
+ name: "Starters v${{ steps.get_version.outputs.version }}"
+ files: dist/*.zip
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/bolt-expo/app/(tabs)/_layout.tsx b/bolt-expo/app/(tabs)/_layout.tsx
new file mode 100644
index 0000000..71449ef
--- /dev/null
+++ b/bolt-expo/app/(tabs)/_layout.tsx
@@ -0,0 +1,16 @@
+import { Tabs } from 'expo-router';
+import { Home } from 'lucide-react-native';
+
+export default function TabLayout() {
+ return (
+
+ ,
+ }}
+ />
+
+ );
+}
diff --git a/bolt-expo/app/(tabs)/index.tsx b/bolt-expo/app/(tabs)/index.tsx
new file mode 100644
index 0000000..08c1c64
--- /dev/null
+++ b/bolt-expo/app/(tabs)/index.tsx
@@ -0,0 +1,23 @@
+import { View, Text, StyleSheet } from 'react-native';
+
+export default function HomeScreen() {
+ return (
+
+ Start prompting now to make changes
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ padding: 16,
+ },
+ message: {
+ fontSize: 20,
+ fontWeight: '600',
+ textAlign: 'center',
+ },
+});
diff --git a/bolt-expo/app/_layout.tsx b/bolt-expo/app/_layout.tsx
index 92d66ca..d4e24b0 100644
--- a/bolt-expo/app/_layout.tsx
+++ b/bolt-expo/app/_layout.tsx
@@ -9,6 +9,7 @@ export default function RootLayout() {
return (
<>
+
diff --git a/bolt-expo/app/index.tsx b/bolt-expo/app/index.tsx
new file mode 100644
index 0000000..372bb7f
--- /dev/null
+++ b/bolt-expo/app/index.tsx
@@ -0,0 +1,23 @@
+import { useEffect } from 'react';
+import { View, StyleSheet } from 'react-native';
+import { useRouter } from 'expo-router';
+
+export default function Index() {
+ const router = useRouter();
+
+ useEffect(() => {
+ setTimeout(() => {
+ //@ts-ignore
+ router.replace('/(tabs)');
+ }, 0);
+ }, []);
+
+ // Return an empty view while we're redirecting
+ return ;
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+});
\ No newline at end of file