diff --git a/apps/cli/package.json b/apps/cli/package.json
index debb49022..fb7bf06e5 100644
--- a/apps/cli/package.json
+++ b/apps/cli/package.json
@@ -1,90 +1,90 @@
{
- "name": "create-better-t-stack",
- "version": "2.44.0",
- "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
- "type": "module",
- "license": "MIT",
- "author": "Aman Varshney",
- "bin": {
- "create-better-t-stack": "dist/cli.js"
- },
- "files": [
- "templates",
- "dist"
- ],
- "keywords": [
- "better-t-stack",
- "typescript",
- "boilerplate",
- "starter",
- "cli",
- "turborepo",
- "trpc",
- "better-auth",
- "monorepo",
- "fullstack",
- "type-safety",
- "react",
- "react-native",
- "expo",
- "hono",
- "elysia",
- "drizzle",
- "prisma",
- "tanstack",
- "tailwind",
- "shadcn",
- "pwa",
- "tauri",
- "biome"
- ],
- "repository": {
- "type": "git",
- "url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git",
- "directory": "apps/cli"
- },
- "publishConfig": {
- "access": "public"
- },
- "homepage": "https://better-t-stack.dev/",
- "scripts": {
- "build": "tsdown",
- "dev": "tsdown --watch",
- "check-types": "tsc --noEmit",
- "check": "biome check --write .",
- "test": "bun run build && vitest run",
- "test:ui": "bun run build && vitest --ui",
- "test:with-build": "bun run build && WITH_BUILD=1 vitest --ui",
- "prepublishOnly": "npm run build"
- },
- "exports": {
- ".": {
- "types": "./dist/index.d.ts",
- "import": "./dist/index.js"
- }
- },
- "dependencies": {
- "@biomejs/js-api": "^3.0.0",
- "@biomejs/wasm-nodejs": "^2.2.4",
- "@clack/prompts": "^1.0.0-alpha.4",
- "consola": "^3.4.2",
- "execa": "^9.6.0",
- "fs-extra": "^11.3.1",
- "gradient-string": "^3.0.0",
- "handlebars": "^4.7.8",
- "jsonc-parser": "^3.3.1",
- "picocolors": "^1.1.1",
- "tinyglobby": "^0.2.15",
- "trpc-cli": "^0.10.2",
- "ts-morph": "^27.0.0",
- "zod": "^4.1.5"
- },
- "devDependencies": {
- "@types/fs-extra": "^11.0.4",
- "@types/node": "^24.3.1",
- "@vitest/ui": "^3.2.4",
- "tsdown": "^0.14.2",
- "typescript": "^5.9.2",
- "vitest": "^3.2.4"
- }
+ "name": "create-better-t-stack",
+ "version": "2.44.0",
+ "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
+ "type": "module",
+ "license": "MIT",
+ "author": "Aman Varshney",
+ "bin": {
+ "create-better-t-stack": "dist/cli.js"
+ },
+ "files": [
+ "templates",
+ "dist"
+ ],
+ "keywords": [
+ "better-t-stack",
+ "typescript",
+ "boilerplate",
+ "starter",
+ "cli",
+ "turborepo",
+ "trpc",
+ "better-auth",
+ "monorepo",
+ "fullstack",
+ "type-safety",
+ "react",
+ "react-native",
+ "expo",
+ "hono",
+ "elysia",
+ "drizzle",
+ "prisma",
+ "tanstack",
+ "tailwind",
+ "shadcn",
+ "pwa",
+ "tauri",
+ "biome"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git",
+ "directory": "apps/cli"
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "homepage": "https://better-t-stack.dev/",
+ "scripts": {
+ "build": "tsdown",
+ "dev": "tsdown --watch",
+ "check-types": "tsc --noEmit",
+ "check": "biome check --write .",
+ "test": "bun run build && vitest run",
+ "test:ui": "bun run build && vitest --ui",
+ "test:with-build": "bun run build && WITH_BUILD=1 vitest --ui",
+ "prepublishOnly": "npm run build"
+ },
+ "exports": {
+ ".": {
+ "types": "./dist/index.d.ts",
+ "import": "./dist/index.js"
+ }
+ },
+ "dependencies": {
+ "@biomejs/js-api": "^3.0.0",
+ "@biomejs/wasm-nodejs": "^2.2.4",
+ "@clack/prompts": "^1.0.0-alpha.4",
+ "consola": "^3.4.2",
+ "execa": "^9.6.0",
+ "fs-extra": "^11.3.1",
+ "gradient-string": "^3.0.0",
+ "handlebars": "^4.7.8",
+ "jsonc-parser": "^3.3.1",
+ "picocolors": "^1.1.1",
+ "tinyglobby": "^0.2.15",
+ "trpc-cli": "^0.10.2",
+ "ts-morph": "^27.0.0",
+ "zod": "^4.1.5"
+ },
+ "devDependencies": {
+ "@types/fs-extra": "^11.0.4",
+ "@types/node": "^24.3.1",
+ "@vitest/ui": "^3.2.4",
+ "tsdown": "^0.14.2",
+ "typescript": "^5.9.2",
+ "vitest": "^3.2.4"
+ }
}
diff --git a/apps/cli/src/helpers/core/template-manager.ts b/apps/cli/src/helpers/core/template-manager.ts
index b93075f43..c90e0eb3d 100644
--- a/apps/cli/src/helpers/core/template-manager.ts
+++ b/apps/cli/src/helpers/core/template-manager.ts
@@ -851,7 +851,7 @@ export async function handleExtras(projectDir: string, context: ProjectConfig) {
const pnpmWorkspaceSrc = path.join(extrasDir, "pnpm-workspace.yaml");
const pnpmWorkspaceDest = path.join(projectDir, "pnpm-workspace.yaml");
if (await fs.pathExists(pnpmWorkspaceSrc)) {
- await fs.copy(pnpmWorkspaceSrc, pnpmWorkspaceDest);
+ await processTemplate(pnpmWorkspaceSrc, pnpmWorkspaceDest, context);
}
}
diff --git a/apps/cli/src/utils/template-processor.ts b/apps/cli/src/utils/template-processor.ts
index 8505e9fe5..85df96aa2 100644
--- a/apps/cli/src/utils/template-processor.ts
+++ b/apps/cli/src/utils/template-processor.ts
@@ -5,6 +5,15 @@ import handlebars from "handlebars";
import type { ProjectConfig } from "../types";
import { formatFileWithBiome } from "./biome-formatter";
+const BINARY_EXTENSIONS = new Set([
+ ".png", ".ico", ".svg",
+]);
+
+function isBinaryFile(filePath: string): boolean {
+ const ext = path.extname(filePath).toLowerCase();
+ return BINARY_EXTENSIONS.has(ext);
+}
+
export async function processTemplate(
srcPath: string,
destPath: string,
@@ -13,6 +22,11 @@ export async function processTemplate(
try {
await fs.ensureDir(path.dirname(destPath));
+ if (isBinaryFile(srcPath) && !srcPath.endsWith(".hbs")) {
+ await fs.copy(srcPath, destPath);
+ return;
+ }
+
let content: string;
if (srcPath.endsWith(".hbs")) {
diff --git a/apps/cli/templates/auth/better-auth/native/native-base/lib/auth-client.ts.hbs b/apps/cli/templates/auth/better-auth/native/native-base/lib/auth-client.ts.hbs
index 8d1b7bd82..8b5584f8e 100644
--- a/apps/cli/templates/auth/better-auth/native/native-base/lib/auth-client.ts.hbs
+++ b/apps/cli/templates/auth/better-auth/native/native-base/lib/auth-client.ts.hbs
@@ -1,12 +1,13 @@
-import { createAuthClient } from "better-auth/react";
import { expoClient } from "@better-auth/expo/client";
+import { createAuthClient } from "better-auth/react";
import * as SecureStore from "expo-secure-store";
export const authClient = createAuthClient({
baseURL: process.env.EXPO_PUBLIC_SERVER_URL,
plugins: [
expoClient({
- storagePrefix: "my-better-t-app",
+ scheme: "mybettertapp",
+ storagePrefix: "{{projectName}}",
storage: SecureStore,
}),
],
diff --git a/apps/cli/templates/auth/better-auth/server/base/src/lib/auth.ts.hbs b/apps/cli/templates/auth/better-auth/server/base/src/lib/auth.ts.hbs
index 2d876f560..c4399812d 100644
--- a/apps/cli/templates/auth/better-auth/server/base/src/lib/auth.ts.hbs
+++ b/apps/cli/templates/auth/better-auth/server/base/src/lib/auth.ts.hbs
@@ -16,7 +16,7 @@ export const auth = betterAuth({
trustedOrigins: [
process.env.CORS_ORIGIN || "",
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
- "my-better-t-app://",
+ "mybettertapp://", "exp://"
{{/if}}
],
emailAndPassword: {
@@ -55,7 +55,7 @@ export const auth = betterAuth({
trustedOrigins: [
process.env.CORS_ORIGIN || "",
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
- "my-better-t-app://",
+ "mybettertapp://", "exp://"
{{/if}}
],
emailAndPassword: {
@@ -124,7 +124,7 @@ export const auth = betterAuth({
trustedOrigins: [
process.env.CORS_ORIGIN || "",
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
- "my-better-t-app://",
+ "mybettertapp://", "exp://"
{{/if}}
],
emailAndPassword: {
@@ -154,7 +154,7 @@ export const auth = betterAuth({
trustedOrigins: [
process.env.CORS_ORIGIN || "",
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
- "my-better-t-app://",
+ "mybettertapp://", "exp://"
{{/if}}
],
emailAndPassword: {
@@ -171,4 +171,4 @@ export const auth = betterAuth({
, plugins: [expo()]
{{/if}}
});
-{{/if}}
\ No newline at end of file
+{{/if}}
diff --git a/apps/cli/templates/backend/server/next/package.json.hbs b/apps/cli/templates/backend/server/next/package.json.hbs
index 885cb31da..7c9860590 100644
--- a/apps/cli/templates/backend/server/next/package.json.hbs
+++ b/apps/cli/templates/backend/server/next/package.json.hbs
@@ -9,8 +9,8 @@
},
"dependencies": {
"next": "15.5.0",
- "react": "^19.0.0",
- "react-dom": "^19.0.0",
+ "react": "19.1.0",
+ "react-dom": "19.1.0",
"dotenv": "^17.2.1"
},
{{#if (eq dbSetup 'supabase')}}
@@ -20,7 +20,7 @@
{{/if}}
"devDependencies": {
"@types/node": "^20",
- "@types/react": "^19",
+ "@types/react": "~19.1.10",
"zod": "^4.0.13",
"typescript": "^5"
}
diff --git a/apps/cli/templates/frontend/native/native-base/assets/favicon.png b/apps/cli/templates/frontend/native/native-base/assets/favicon.png
deleted file mode 100644
index 9dbf6dd6c..000000000
Binary files a/apps/cli/templates/frontend/native/native-base/assets/favicon.png and /dev/null differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/icon.png b/apps/cli/templates/frontend/native/native-base/assets/icon.png
deleted file mode 100644
index a0b1526fc..000000000
Binary files a/apps/cli/templates/frontend/native/native-base/assets/icon.png and /dev/null differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/images/android-icon-background.png b/apps/cli/templates/frontend/native/native-base/assets/images/android-icon-background.png
new file mode 100644
index 000000000..5ffefc5bb
Binary files /dev/null and b/apps/cli/templates/frontend/native/native-base/assets/images/android-icon-background.png differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/images/android-icon-foreground.png b/apps/cli/templates/frontend/native/native-base/assets/images/android-icon-foreground.png
new file mode 100644
index 000000000..3a9e5016d
Binary files /dev/null and b/apps/cli/templates/frontend/native/native-base/assets/images/android-icon-foreground.png differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/images/android-icon-monochrome.png b/apps/cli/templates/frontend/native/native-base/assets/images/android-icon-monochrome.png
new file mode 100644
index 000000000..77484ebdb
Binary files /dev/null and b/apps/cli/templates/frontend/native/native-base/assets/images/android-icon-monochrome.png differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/images/favicon.png b/apps/cli/templates/frontend/native/native-base/assets/images/favicon.png
new file mode 100644
index 000000000..408bd7466
Binary files /dev/null and b/apps/cli/templates/frontend/native/native-base/assets/images/favicon.png differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/images/icon.png b/apps/cli/templates/frontend/native/native-base/assets/images/icon.png
new file mode 100644
index 000000000..7165a53c7
Binary files /dev/null and b/apps/cli/templates/frontend/native/native-base/assets/images/icon.png differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/images/partial-react-logo.png b/apps/cli/templates/frontend/native/native-base/assets/images/partial-react-logo.png
new file mode 100644
index 000000000..66fd9570e
Binary files /dev/null and b/apps/cli/templates/frontend/native/native-base/assets/images/partial-react-logo.png differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/images/react-logo.png b/apps/cli/templates/frontend/native/native-base/assets/images/react-logo.png
new file mode 100644
index 000000000..9d72a9ffc
Binary files /dev/null and b/apps/cli/templates/frontend/native/native-base/assets/images/react-logo.png differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/images/react-logo@2x.png b/apps/cli/templates/frontend/native/native-base/assets/images/react-logo@2x.png
new file mode 100644
index 000000000..2229b130a
Binary files /dev/null and b/apps/cli/templates/frontend/native/native-base/assets/images/react-logo@2x.png differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/images/react-logo@3x.png b/apps/cli/templates/frontend/native/native-base/assets/images/react-logo@3x.png
new file mode 100644
index 000000000..a99b20322
Binary files /dev/null and b/apps/cli/templates/frontend/native/native-base/assets/images/react-logo@3x.png differ
diff --git a/apps/cli/templates/frontend/native/native-base/assets/adaptive-icon.png b/apps/cli/templates/frontend/native/native-base/assets/images/splash-icon.png
similarity index 100%
rename from apps/cli/templates/frontend/native/native-base/assets/adaptive-icon.png
rename to apps/cli/templates/frontend/native/native-base/assets/images/splash-icon.png
diff --git a/apps/cli/templates/frontend/native/native-base/assets/splash.png b/apps/cli/templates/frontend/native/native-base/assets/splash.png
deleted file mode 100644
index 0e89705a9..000000000
Binary files a/apps/cli/templates/frontend/native/native-base/assets/splash.png and /dev/null differ
diff --git a/apps/cli/templates/frontend/native/nativewind/app-env.d.ts b/apps/cli/templates/frontend/native/nativewind/app-env.d.ts
deleted file mode 100644
index 88dc403ea..000000000
--- a/apps/cli/templates/frontend/native/nativewind/app-env.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// @ts-ignore
-///
diff --git a/apps/cli/templates/frontend/native/nativewind/app.json b/apps/cli/templates/frontend/native/nativewind/app.json
deleted file mode 100644
index 3d89aa638..000000000
--- a/apps/cli/templates/frontend/native/nativewind/app.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "expo": {
- "name": "my-better-t-app",
- "slug": "my-better-t-app",
- "version": "1.0.0",
- "scheme": "my-better-t-app",
- "web": {
- "bundler": "metro",
- "output": "static",
- "favicon": "./assets/favicon.png"
- },
- "plugins": [
- "expo-router",
- "expo-secure-store",
- "expo-web-browser"
- ],
- "experiments": {
- "typedRoutes": true,
- "tsconfigPaths": true
- },
- "newArchEnabled": true,
- "orientation": "portrait",
- "icon": "./assets/icon.png",
- "userInterfaceStyle": "light",
- "splash": {
- "image": "./assets/splash.png",
- "resizeMode": "contain",
- "backgroundColor": "#ffffff"
- },
- "assetBundlePatterns": [
- "**/*"
- ],
- "ios": {
- "supportsTablet": true,
- "bundleIdentifier": "com.amanvarshney01.mybettertapp"
- },
- "android": {
- "adaptiveIcon": {
- "foregroundImage": "./assets/adaptive-icon.png",
- "backgroundColor": "#ffffff"
- },
- "package": "com.amanvarshney01.mybettertapp",
- "edgeToEdgeEnabled": true
- }
- }
-}
diff --git a/apps/cli/templates/frontend/native/nativewind/app.json.hbs b/apps/cli/templates/frontend/native/nativewind/app.json.hbs
new file mode 100644
index 000000000..86a6b10ab
--- /dev/null
+++ b/apps/cli/templates/frontend/native/nativewind/app.json.hbs
@@ -0,0 +1,49 @@
+{
+ "expo": {
+ "name": "{{projectName}}",
+ "slug": "{{projectName}}",
+ "version": "1.0.0",
+ "orientation": "portrait",
+ "icon": "./assets/images/icon.png",
+ "scheme": "mybettertapp",
+ "userInterfaceStyle": "automatic",
+ "newArchEnabled": true,
+ "ios": {
+ "supportsTablet": true
+ },
+ "android": {
+ "adaptiveIcon": {
+ "backgroundColor": "#E6F4FE",
+ "foregroundImage": "./assets/images/android-icon-foreground.png",
+ "backgroundImage": "./assets/images/android-icon-background.png",
+ "monochromeImage": "./assets/images/android-icon-monochrome.png"
+ },
+ "edgeToEdgeEnabled": true,
+ "predictiveBackGestureEnabled": false,
+ "package": "com.anonymous.mybettertapp"
+ },
+ "web": {
+ "output": "static",
+ "favicon": "./assets/images/favicon.png"
+ },
+ "plugins": [
+ "expo-router",
+ [
+ "expo-splash-screen",
+ {
+ "image": "./assets/images/splash-icon.png",
+ "imageWidth": 200,
+ "resizeMode": "contain",
+ "backgroundColor": "#ffffff",
+ "dark": {
+ "backgroundColor": "#000000"
+ }
+ }
+ ]
+ ],
+ "experiments": {
+ "typedRoutes": true,
+ "reactCompiler": true
+ }
+ }
+}
diff --git a/apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/_layout.tsx b/apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/_layout.tsx.hbs
similarity index 94%
rename from apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/_layout.tsx
rename to apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/_layout.tsx.hbs
index 617283cef..a1a1f04ad 100644
--- a/apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/_layout.tsx
+++ b/apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/_layout.tsx.hbs
@@ -7,7 +7,7 @@ export default function TabLayout() {
return (
,
}}
/>
(
diff --git a/apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx b/apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx
rename to apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs
diff --git a/apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx b/apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx
rename to apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs
diff --git a/apps/cli/templates/frontend/native/nativewind/app/+html.tsx b/apps/cli/templates/frontend/native/nativewind/app/+html.tsx
deleted file mode 100644
index 7dfb9333c..000000000
--- a/apps/cli/templates/frontend/native/nativewind/app/+html.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import { ScrollViewStyleReset } from 'expo-router/html';
-import { ReactNode } from 'react';
-
-// This file is web-only and used to configure the root HTML for every
-// web page during static rendering.
-// The contents of this function only run in Node.js environments and
-// do not have access to the DOM or browser APIs.
-export default function Root({ children }: { children: ReactNode }) {
- return (
-
-
-
-
-
- {/*
- This viewport disables scaling which makes the mobile website act more like a native app.
- However this does reduce built-in accessibility. If you want to enable scaling, use this instead:
-
- */}
-
- {/*
- Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
- However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
- */}
-
-
- {/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */}
-
- {/* Add any additional elements that you want globally available on web... */}
-
- {children}
-
- );
-}
-
-const responsiveBackground = `
-body {
- background-color: #fff;
-}
-@media (prefers-color-scheme: dark) {
- body {
- background-color: #000;
- }
-}`;
diff --git a/apps/cli/templates/frontend/native/nativewind/app/+not-found.tsx b/apps/cli/templates/frontend/native/nativewind/app/+not-found.tsx.hbs
similarity index 94%
rename from apps/cli/templates/frontend/native/nativewind/app/+not-found.tsx
rename to apps/cli/templates/frontend/native/nativewind/app/+not-found.tsx.hbs
index 50cd5ee12..8a9f34000 100644
--- a/apps/cli/templates/frontend/native/nativewind/app/+not-found.tsx
+++ b/apps/cli/templates/frontend/native/nativewind/app/+not-found.tsx.hbs
@@ -5,7 +5,7 @@ import { Text, View } from "react-native";
export default function NotFoundScreen() {
return (
<>
-
+
diff --git a/apps/cli/templates/frontend/native/nativewind/app/modal.tsx b/apps/cli/templates/frontend/native/nativewind/app/modal.tsx.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/nativewind/app/modal.tsx
rename to apps/cli/templates/frontend/native/nativewind/app/modal.tsx.hbs
diff --git a/apps/cli/templates/frontend/native/nativewind/babel.config.js b/apps/cli/templates/frontend/native/nativewind/babel.config.js
deleted file mode 100644
index 8f817528f..000000000
--- a/apps/cli/templates/frontend/native/nativewind/babel.config.js
+++ /dev/null
@@ -1,11 +0,0 @@
-module.exports = function (api) {
- api.cache(true);
- const plugins = [];
-
- plugins.push('react-native-reanimated/plugin');
-
- return {
- presets: [['babel-preset-expo', { jsxImportSource: 'nativewind' }], 'nativewind/babel'],
- plugins,
- };
-};
diff --git a/apps/cli/templates/frontend/native/nativewind/babel.config.js.hbs b/apps/cli/templates/frontend/native/nativewind/babel.config.js.hbs
new file mode 100644
index 000000000..d54d5e71b
--- /dev/null
+++ b/apps/cli/templates/frontend/native/nativewind/babel.config.js.hbs
@@ -0,0 +1,14 @@
+module.exports = (api) => {
+ api.cache(true);
+ const plugins = [];
+
+ plugins.push("react-native-worklets/plugin");
+
+ return {
+ presets: [
+ ["babel-preset-expo", { jsxImportSource: "nativewind" }],
+ "nativewind/babel",
+ ],
+ plugins,
+ };
+};
diff --git a/apps/cli/templates/frontend/native/nativewind/components/container.tsx b/apps/cli/templates/frontend/native/nativewind/components/container.tsx.hbs
similarity index 76%
rename from apps/cli/templates/frontend/native/nativewind/components/container.tsx
rename to apps/cli/templates/frontend/native/nativewind/components/container.tsx.hbs
index d1d5798d3..bf824f34c 100644
--- a/apps/cli/templates/frontend/native/nativewind/components/container.tsx
+++ b/apps/cli/templates/frontend/native/nativewind/components/container.tsx.hbs
@@ -1,5 +1,5 @@
import React from "react";
-import { SafeAreaView } from "react-native";
+import { SafeAreaView } from "react-native-safe-area-context";
export const Container = ({ children }: { children: React.ReactNode }) => {
return (
diff --git a/apps/cli/templates/frontend/native/nativewind/components/header-button.tsx b/apps/cli/templates/frontend/native/nativewind/components/header-button.tsx.hbs
similarity index 96%
rename from apps/cli/templates/frontend/native/nativewind/components/header-button.tsx
rename to apps/cli/templates/frontend/native/nativewind/components/header-button.tsx.hbs
index 51dcf38ea..bb3a21ad9 100644
--- a/apps/cli/templates/frontend/native/nativewind/components/header-button.tsx
+++ b/apps/cli/templates/frontend/native/nativewind/components/header-button.tsx.hbs
@@ -16,7 +16,7 @@ export const HeaderButton = forwardRef<
name="info-circle"
size={20}
className="text-secondary-foreground"
- style={{
+ style=\{{
opacity: pressed ? 0.7 : 1,
}}
/>
diff --git a/apps/cli/templates/frontend/native/nativewind/components/tabbar-icon.tsx b/apps/cli/templates/frontend/native/nativewind/components/tabbar-icon.tsx.hbs
similarity index 70%
rename from apps/cli/templates/frontend/native/nativewind/components/tabbar-icon.tsx
rename to apps/cli/templates/frontend/native/nativewind/components/tabbar-icon.tsx.hbs
index 3ea0888a1..ecf1944c1 100644
--- a/apps/cli/templates/frontend/native/nativewind/components/tabbar-icon.tsx
+++ b/apps/cli/templates/frontend/native/nativewind/components/tabbar-icon.tsx.hbs
@@ -4,5 +4,5 @@ export const TabBarIcon = (props: {
name: React.ComponentProps["name"];
color: string;
}) => {
- return ;
+ return ;
};
diff --git a/apps/cli/templates/frontend/native/nativewind/lib/android-navigation-bar.tsx b/apps/cli/templates/frontend/native/nativewind/lib/android-navigation-bar.tsx.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/nativewind/lib/android-navigation-bar.tsx
rename to apps/cli/templates/frontend/native/nativewind/lib/android-navigation-bar.tsx.hbs
diff --git a/apps/cli/templates/frontend/native/nativewind/lib/constants.ts b/apps/cli/templates/frontend/native/nativewind/lib/constants.ts.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/nativewind/lib/constants.ts
rename to apps/cli/templates/frontend/native/nativewind/lib/constants.ts.hbs
diff --git a/apps/cli/templates/frontend/native/nativewind/lib/use-color-scheme.ts b/apps/cli/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/nativewind/lib/use-color-scheme.ts
rename to apps/cli/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs
diff --git a/apps/cli/templates/frontend/native/nativewind/metro.config.js b/apps/cli/templates/frontend/native/nativewind/metro.config.js.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/nativewind/metro.config.js
rename to apps/cli/templates/frontend/native/nativewind/metro.config.js.hbs
diff --git a/apps/cli/templates/frontend/native/nativewind/package.json.hbs b/apps/cli/templates/frontend/native/nativewind/package.json.hbs
index 0778013ad..ad3c76773 100644
--- a/apps/cli/templates/frontend/native/nativewind/package.json.hbs
+++ b/apps/cli/templates/frontend/native/nativewind/package.json.hbs
@@ -10,39 +10,41 @@
"web": "expo start --web"
},
"dependencies": {
- "@expo/vector-icons": "^14.0.4",
+ "@expo/vector-icons": "^15.0.2",
"@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/drawer": "^7.1.1",
"@react-navigation/native": "^7.0.14",
"@tanstack/react-form": "^1.0.5",
- "@tanstack/react-query": "^5.69.2",
+ "@tanstack/react-query": "^5.85.5",
{{#if (includes examples "ai")}}
"@stardazed/streams-text-encoding": "^1.0.2",
"@ungap/structured-clone": "^1.3.0",
{{/if}}
- "expo": "^53.0.4",
- "expo-constants": "~17.1.4",
- "expo-crypto": "~14.1.5",
- "expo-linking": "~7.1.4",
- "expo-navigation-bar": "~4.2.3",
- "expo-router": "~5.0.3",
- "expo-secure-store": "~14.2.3",
- "expo-status-bar": "~2.2.3",
- "expo-system-ui": "~5.0.6",
- "expo-web-browser": "~14.1.6",
+ "expo": "^54.0.1",
+ "expo-constants": "~18.0.8",
+ "expo-crypto": "~15.0.6",
+ "expo-linking": "~8.0.7",
+ "expo-navigation-bar": "~5.0.8",
+ "expo-router": "~6.0.0",
+ "expo-secure-store": "~15.0.6",
+ "expo-splash-screen": "~31.0.8",
+ "expo-status-bar": "~3.0.7",
+ "expo-system-ui": "~6.0.7",
+ "expo-web-browser": "~15.0.6",
"nativewind": "^4.1.23",
- "react": "19.0.0",
- "react-dom": "19.0.0",
- "react-native": "0.79.1",
- "react-native-gesture-handler": "~2.24.0",
- "react-native-reanimated": "~3.17.4",
- "react-native-safe-area-context": "5.3.0",
- "react-native-screens": "~4.10.0",
- "react-native-web": "^0.20.0"
+ "react": "19.1.0",
+ "react-dom": "19.1.0",
+ "react-native": "0.81.4",
+ "react-native-gesture-handler": "~2.28.0",
+ "react-native-reanimated": "~4.1.0",
+ "react-native-safe-area-context": "~5.6.0",
+ "react-native-screens": "~4.16.0",
+ "react-native-web": "^0.21.0",
+ "react-native-worklets": "^0.5.1"
},
"devDependencies": {
"@babel/core": "^7.26.10",
- "@types/react": "~19.0.10",
+ "@types/react": "~19.1.10",
"tailwindcss": "^3.4.17",
"typescript": "~5.8.2"
},
diff --git a/apps/cli/templates/frontend/native/nativewind/tailwind.config.js b/apps/cli/templates/frontend/native/nativewind/tailwind.config.js
deleted file mode 100644
index 92da9bf82..000000000
--- a/apps/cli/templates/frontend/native/nativewind/tailwind.config.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const { hairlineWidth } = require("nativewind/theme");
-
-/** @type {import('tailwindcss').Config} */
-module.exports = {
- darkMode: "class",
- content: ["./app/**/*.{js,ts,tsx}", "./components/**/*.{js,ts,tsx}"],
-
- presets: [require("nativewind/preset")],
- theme: {
- extend: {
- colors: {
- background: "hsl(var(--background))",
- foreground: "hsl(var(--foreground))",
- card: {
- DEFAULT: "hsl(var(--card))",
- foreground: "hsl(var(--card-foreground))",
- },
- popover: {
- DEFAULT: "hsl(var(--popover))",
- foreground: "hsl(var(--popover-foreground))",
- },
- primary: {
- DEFAULT: "hsl(var(--primary))",
- foreground: "hsl(var(--primary-foreground))",
- },
- secondary: {
- DEFAULT: "hsl(var(--secondary))",
- foreground: "hsl(var(--secondary-foreground))",
- },
- muted: {
- DEFAULT: "hsl(var(--muted))",
- foreground: "hsl(var(--muted-foreground))",
- },
- accent: {
- DEFAULT: "hsl(var(--accent))",
- foreground: "hsl(var(--accent-foreground))",
- },
- destructive: {
- DEFAULT: "hsl(var(--destructive))",
- foreground: "hsl(var(--destructive-foreground))",
- },
- border: "hsl(var(--border))",
- input: "hsl(var(--input))",
- ring: "hsl(var(--ring))",
- radius: "var(--radius)",
- },
- borderRadius: {
- xl: "calc(var(--radius) + 4px)",
- lg: "var(--radius)",
- md: "calc(var(--radius) - 2px)",
- sm: "calc(var(--radius) - 4px)",
- },
- borderWidth: {
- hairline: hairlineWidth(),
- },
- },
- },
- plugins: [],
-};
diff --git a/apps/cli/templates/frontend/native/nativewind/tailwind.config.js.hbs b/apps/cli/templates/frontend/native/nativewind/tailwind.config.js.hbs
new file mode 100644
index 000000000..b6ea71147
--- /dev/null
+++ b/apps/cli/templates/frontend/native/nativewind/tailwind.config.js.hbs
@@ -0,0 +1,59 @@
+import { hairlineWidth } from "nativewind/theme";
+
+/** @type {import('tailwindcss').Config} */
+export const darkMode = "class";
+export const content = [
+ "./app/**/*.{js,ts,tsx}",
+ "./components/**/*.{js,ts,tsx}",
+];
+export const presets = [require("nativewind/preset")];
+export const theme = {
+ extend: {
+ colors: {
+ background: "hsl(var(--background))",
+ foreground: "hsl(var(--foreground))",
+ card: {
+ DEFAULT: "hsl(var(--card))",
+ foreground: "hsl(var(--card-foreground))",
+ },
+ popover: {
+ DEFAULT: "hsl(var(--popover))",
+ foreground: "hsl(var(--popover-foreground))",
+ },
+ primary: {
+ DEFAULT: "hsl(var(--primary))",
+ foreground: "hsl(var(--primary-foreground))",
+ },
+ secondary: {
+ DEFAULT: "hsl(var(--secondary))",
+ foreground: "hsl(var(--secondary-foreground))",
+ },
+ muted: {
+ DEFAULT: "hsl(var(--muted))",
+ foreground: "hsl(var(--muted-foreground))",
+ },
+ accent: {
+ DEFAULT: "hsl(var(--accent))",
+ foreground: "hsl(var(--accent-foreground))",
+ },
+ destructive: {
+ DEFAULT: "hsl(var(--destructive))",
+ foreground: "hsl(var(--destructive-foreground))",
+ },
+ border: "hsl(var(--border))",
+ input: "hsl(var(--input))",
+ ring: "hsl(var(--ring))",
+ radius: "var(--radius)",
+ },
+ borderRadius: {
+ xl: "calc(var(--radius) + 4px)",
+ lg: "var(--radius)",
+ md: "calc(var(--radius) - 2px)",
+ sm: "calc(var(--radius) - 4px)",
+ },
+ borderWidth: {
+ hairline: hairlineWidth(),
+ },
+ },
+};
+export const plugins = [];
diff --git a/apps/cli/templates/frontend/native/unistyles/app.json b/apps/cli/templates/frontend/native/unistyles/app.json
deleted file mode 100644
index d2856dc0d..000000000
--- a/apps/cli/templates/frontend/native/unistyles/app.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "expo": {
- "name": "my-better-t-app",
- "slug": "my-better-t-app",
- "version": "1.0.0",
- "newArchEnabled": true,
- "scheme": "my-better-t-app",
- "web": {
- "bundler": "metro",
- "output": "static",
- "favicon": "./assets/favicon.png"
- },
- "plugins": [
- "expo-router",
- "react-native-edge-to-edge",
- "expo-secure-store"
- ],
- "experiments": {
- "typedRoutes": true,
- "tsconfigPaths": true,
- "reactCompiler": true
- },
- "orientation": "portrait",
- "icon": "./assets/icon.png",
- "userInterfaceStyle": "automatic",
- "splash": {
- "image": "./assets/splash.png",
- "resizeMode": "contain",
- "backgroundColor": "#ffffff"
- },
- "assetBundlePatterns": ["**/*"],
- "ios": {
- "supportsTablet": true,
- "bundleIdentifier": "com.amanvarshney01.mybettertapp"
- },
- "android": {
- "adaptiveIcon": {
- "foregroundImage": "./assets/adaptive-icon.png",
- "backgroundColor": "#ffffff"
- },
- "package": "com.amanvarshney01.mybettertapp"
- }
- }
-}
diff --git a/apps/cli/templates/frontend/native/unistyles/app.json.hbs b/apps/cli/templates/frontend/native/unistyles/app.json.hbs
new file mode 100644
index 000000000..c0e566abb
--- /dev/null
+++ b/apps/cli/templates/frontend/native/unistyles/app.json.hbs
@@ -0,0 +1,49 @@
+{
+ "expo": {
+ "name": "{{projectName}}",
+ "slug": "{{projectName}}",
+ "version": "1.0.0",
+ "orientation": "portrait",
+ "icon": "./assets/images/icon.png",
+ "scheme": "mybettertapp",
+ "userInterfaceStyle": "automatic",
+ "newArchEnabled": true,
+ "ios": {
+ "supportsTablet": true
+ },
+ "android": {
+ "adaptiveIcon": {
+ "backgroundColor": "#E6F4FE",
+ "foregroundImage": "./assets/images/android-icon-foreground.png",
+ "backgroundImage": "./assets/images/android-icon-background.png",
+ "monochromeImage": "./assets/images/android-icon-monochrome.png"
+ },
+ "edgeToEdgeEnabled": true,
+ "predictiveBackGestureEnabled": false,
+ "package": "com.anonymous.mybettertapp6"
+ },
+ "web": {
+ "output": "static",
+ "favicon": "./assets/images/favicon.png"
+ },
+ "plugins": [
+ "expo-router",
+ [
+ "expo-splash-screen",
+ {
+ "image": "./assets/images/splash-icon.png",
+ "imageWidth": 200,
+ "resizeMode": "contain",
+ "backgroundColor": "#ffffff",
+ "dark": {
+ "backgroundColor": "#000000"
+ }
+ }
+ ]
+ ],
+ "experiments": {
+ "typedRoutes": true,
+ "reactCompiler": true
+ }
+ }
+}
diff --git a/apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx b/apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx.hbs
similarity index 93%
rename from apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx
rename to apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx.hbs
index 86f1e41c5..760a1c02f 100644
--- a/apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx
+++ b/apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx.hbs
@@ -8,7 +8,7 @@ export default function TabLayout() {
return (
,
}}
/>
(
diff --git a/apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/index.tsx b/apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/index.tsx.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/index.tsx
rename to apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/index.tsx.hbs
diff --git a/apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/two.tsx b/apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/two.tsx.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/two.tsx
rename to apps/cli/templates/frontend/native/unistyles/app/(drawer)/(tabs)/two.tsx.hbs
diff --git a/apps/cli/templates/frontend/native/unistyles/app/(drawer)/index.tsx.hbs b/apps/cli/templates/frontend/native/unistyles/app/(drawer)/index.tsx.hbs
index 0078fab03..1f59f7043 100644
--- a/apps/cli/templates/frontend/native/unistyles/app/(drawer)/index.tsx.hbs
+++ b/apps/cli/templates/frontend/native/unistyles/app/(drawer)/index.tsx.hbs
@@ -46,9 +46,7 @@ export default function Home() {
contentContainerStyle={styles.container}
showsVerticalScrollIndicator={false}
>
-
- BETTER T STACK
-
+ BETTER T STACK
System Status
diff --git a/apps/cli/templates/frontend/native/unistyles/app/+html.tsx b/apps/cli/templates/frontend/native/unistyles/app/+html.tsx
deleted file mode 100644
index c495253b9..000000000
--- a/apps/cli/templates/frontend/native/unistyles/app/+html.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { ScrollViewStyleReset } from 'expo-router/html';
-
-import '../unistyles';
-
-// This file is web-only and used to configure the root HTML for every
-// web page during static rendering.
-// The contents of this function only run in Node.js environments and
-// do not have access to the DOM or browser APIs.
-export default function Root({ children }: { children: React.ReactNode }) {
- return (
-
-
-
-
-
- {/*
- This viewport disables scaling which makes the mobile website act more like a native app.
- However this does reduce built-in accessibility. If you want to enable scaling, use this instead:
-
- */}
-
- {/*
- Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
- However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
- */}
-
-
- {/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */}
-
- {/* Add any additional elements that you want globally available on web... */}
-
- {children}
-
- );
-}
-
-const responsiveBackground = `
-body {
- background-color: #fff;
-}
-@media (prefers-color-scheme: dark) {
- body {
- background-color: #000;
- }
-}`;
diff --git a/apps/cli/templates/frontend/native/unistyles/app/+not-found.tsx b/apps/cli/templates/frontend/native/unistyles/app/+not-found.tsx.hbs
similarity index 96%
rename from apps/cli/templates/frontend/native/unistyles/app/+not-found.tsx
rename to apps/cli/templates/frontend/native/unistyles/app/+not-found.tsx.hbs
index ebe089e97..ab80f8c26 100644
--- a/apps/cli/templates/frontend/native/unistyles/app/+not-found.tsx
+++ b/apps/cli/templates/frontend/native/unistyles/app/+not-found.tsx.hbs
@@ -1,12 +1,12 @@
-import { Container } from "@/components/container";
import { Link, Stack } from "expo-router";
import { Text, View } from "react-native";
import { StyleSheet } from "react-native-unistyles";
+import { Container } from "@/components/container";
export default function NotFoundScreen() {
return (
<>
-
+
diff --git a/apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs b/apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs
index 0509a7a72..065cd7fff 100644
--- a/apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs
+++ b/apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs
@@ -22,14 +22,14 @@ import { QueryClientProvider } from "@tanstack/react-query";
import { Stack } from "expo-router";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { useUnistyles } from "react-native-unistyles";
+import { StatusBar } from "expo-status-bar";
export const unstable_settings = {
- // Ensure that reloading on `/modal` keeps a back button present.
initialRouteName: "(drawer)",
};
{{#if (eq backend "convex")}}
-const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL!, {
+const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL || "", {
unsavedChangesWarning: false,
});
{{/if}}
diff --git a/apps/cli/templates/frontend/native/unistyles/app/modal.tsx b/apps/cli/templates/frontend/native/unistyles/app/modal.tsx.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/unistyles/app/modal.tsx
rename to apps/cli/templates/frontend/native/unistyles/app/modal.tsx.hbs
diff --git a/apps/cli/templates/frontend/native/unistyles/babel.config.js b/apps/cli/templates/frontend/native/unistyles/babel.config.js
deleted file mode 100644
index 04a3dd337..000000000
--- a/apps/cli/templates/frontend/native/unistyles/babel.config.js
+++ /dev/null
@@ -1,21 +0,0 @@
-module.exports = function (api) {
- api.cache(true);
- const plugins = [];
-
- plugins.push([
- 'react-native-unistyles/plugin',
- {
- root: "src",
- autoProcessRoot: 'app',
- autoProcessImports: ['@/components']
- },
- ]);
-
- plugins.push('react-native-reanimated/plugin');
-
- return {
- presets: ['babel-preset-expo'],
-
- plugins,
- };
-};
diff --git a/apps/cli/templates/frontend/native/unistyles/babel.config.js.hbs b/apps/cli/templates/frontend/native/unistyles/babel.config.js.hbs
new file mode 100644
index 000000000..d31546b56
--- /dev/null
+++ b/apps/cli/templates/frontend/native/unistyles/babel.config.js.hbs
@@ -0,0 +1,21 @@
+module.exports = (api) => {
+ api.cache(true);
+ const plugins = [];
+
+ plugins.push([
+ "react-native-unistyles/plugin",
+ {
+ root: "src",
+ autoProcessRoot: "app",
+ autoProcessImports: ["@/components"],
+ },
+ ]);
+
+ plugins.push("react-native-worklets/plugin");
+
+ return {
+ presets: ["babel-preset-expo"],
+
+ plugins,
+ };
+};
diff --git a/apps/cli/templates/frontend/native/unistyles/breakpoints.ts b/apps/cli/templates/frontend/native/unistyles/breakpoints.ts.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/unistyles/breakpoints.ts
rename to apps/cli/templates/frontend/native/unistyles/breakpoints.ts.hbs
diff --git a/apps/cli/templates/frontend/native/unistyles/components/container.tsx b/apps/cli/templates/frontend/native/unistyles/components/container.tsx.hbs
similarity index 86%
rename from apps/cli/templates/frontend/native/unistyles/components/container.tsx
rename to apps/cli/templates/frontend/native/unistyles/components/container.tsx.hbs
index 06d670d49..84bc492dd 100644
--- a/apps/cli/templates/frontend/native/unistyles/components/container.tsx
+++ b/apps/cli/templates/frontend/native/unistyles/components/container.tsx.hbs
@@ -1,5 +1,5 @@
import React from "react";
-import { SafeAreaView } from "react-native";
+import { SafeAreaView } from "react-native-safe-area-context";
import { StyleSheet } from "react-native-unistyles";
export const Container = ({ children }: { children: React.ReactNode }) => {
diff --git a/apps/cli/templates/frontend/native/unistyles/components/header-button.tsx b/apps/cli/templates/frontend/native/unistyles/components/header-button.tsx.hbs
similarity index 97%
rename from apps/cli/templates/frontend/native/unistyles/components/header-button.tsx
rename to apps/cli/templates/frontend/native/unistyles/components/header-button.tsx.hbs
index d6e05d886..790ec03e3 100644
--- a/apps/cli/templates/frontend/native/unistyles/components/header-button.tsx
+++ b/apps/cli/templates/frontend/native/unistyles/components/header-button.tsx.hbs
@@ -14,7 +14,7 @@ export const HeaderButton = forwardRef<
name="info-circle"
size={20}
color={styles.icon.color}
- style={{
+ style=\{{
opacity: pressed ? 0.7 : 1,
}}
/>
diff --git a/apps/cli/templates/frontend/native/unistyles/components/tabbar-icon.tsx b/apps/cli/templates/frontend/native/unistyles/components/tabbar-icon.tsx.hbs
similarity index 70%
rename from apps/cli/templates/frontend/native/unistyles/components/tabbar-icon.tsx
rename to apps/cli/templates/frontend/native/unistyles/components/tabbar-icon.tsx.hbs
index 3ea0888a1..ecf1944c1 100644
--- a/apps/cli/templates/frontend/native/unistyles/components/tabbar-icon.tsx
+++ b/apps/cli/templates/frontend/native/unistyles/components/tabbar-icon.tsx.hbs
@@ -4,5 +4,5 @@ export const TabBarIcon = (props: {
name: React.ComponentProps["name"];
color: string;
}) => {
- return ;
+ return ;
};
diff --git a/apps/cli/templates/frontend/native/unistyles/expo-env.d.ts b/apps/cli/templates/frontend/native/unistyles/expo-env.d.ts
deleted file mode 100644
index 5411fdde4..000000000
--- a/apps/cli/templates/frontend/native/unistyles/expo-env.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-///
-
-// NOTE: This file should not be edited and should be in your git ignore
\ No newline at end of file
diff --git a/apps/cli/templates/frontend/native/unistyles/index.js b/apps/cli/templates/frontend/native/unistyles/index.js.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/unistyles/index.js
rename to apps/cli/templates/frontend/native/unistyles/index.js.hbs
diff --git a/apps/cli/templates/frontend/native/unistyles/metro.config.js b/apps/cli/templates/frontend/native/unistyles/metro.config.js
deleted file mode 100644
index ab4694820..000000000
--- a/apps/cli/templates/frontend/native/unistyles/metro.config.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Learn more https://docs.expo.io/guides/customizing-metro
-const { getDefaultConfig } = require("expo/metro-config");
-const path = require("path");
-
-const workspaceRoot = path.resolve(__dirname, "../..");
-const projectRoot = __dirname;
-
-const config = getDefaultConfig(projectRoot);
-
-// 1. Watch all files within the monorepo
-config.watchFolders = [workspaceRoot];
-// 2. Let Metro know where to resolve packages, and in what order
-config.resolver.nodeModulesPaths = [
- path.resolve(projectRoot, "node_modules"),
- path.resolve(workspaceRoot, "node_modules"),
-];
-// 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
-config.resolver.disableHierarchicalLookup = true;
-
-module.exports = config;
diff --git a/apps/cli/templates/frontend/native/unistyles/metro.config.js.hbs b/apps/cli/templates/frontend/native/unistyles/metro.config.js.hbs
new file mode 100644
index 000000000..f3678d3b4
--- /dev/null
+++ b/apps/cli/templates/frontend/native/unistyles/metro.config.js.hbs
@@ -0,0 +1,5 @@
+const { getDefaultConfig } = require("expo/metro-config");
+
+const config = getDefaultConfig(__dirname);
+
+module.exports = config;
diff --git a/apps/cli/templates/frontend/native/unistyles/package.json.hbs b/apps/cli/templates/frontend/native/unistyles/package.json.hbs
index 33f4ffca0..a751432f7 100644
--- a/apps/cli/templates/frontend/native/unistyles/package.json.hbs
+++ b/apps/cli/templates/frontend/native/unistyles/package.json.hbs
@@ -1,6 +1,7 @@
{
"name": "native",
"version": "1.0.0",
+ "private": true,
"main": "index.js",
"scripts": {
"dev": "expo start --clear",
@@ -9,7 +10,7 @@
"web": "expo start --web"
},
"dependencies": {
- "@expo/vector-icons": "^14.1.0",
+ "@expo/vector-icons": "^15.0.2",
"@react-navigation/bottom-tabs": "^7.3.10",
"@react-navigation/drawer": "^7.3.9",
"@react-navigation/native": "^7.1.6",
@@ -17,35 +18,35 @@
"@stardazed/streams-text-encoding": "^1.0.2",
"@ungap/structured-clone": "^1.3.0",
{{/if}}
- "@tanstack/react-form": "^1.14.0",
- "babel-plugin-react-compiler": "^19.1.0-rc.2",
- "expo": "^53.0.17",
- "expo-constants": "~17.1.7",
- "expo-crypto": "~14.1.5",
- "expo-linking": "~7.1.7",
- "expo-router": "~5.1.3",
- "expo-secure-store": "~14.2.3",
- "expo-status-bar": "~2.2.3",
- "expo-system-ui": "~5.0.10",
- "expo-dev-client": "~5.2.4",
- "expo-web-browser": "~14.2.0",
- "react": "19.0.0",
- "react-dom": "19.0.0",
- "react-native": "0.79.5",
- "react-native-edge-to-edge": "1.6.0",
- "react-native-gesture-handler": "~2.24.0",
- "react-native-nitro-modules": "0.26.3",
- "react-native-reanimated": "~3.17.4",
- "react-native-safe-area-context": "5.4.0",
- "react-native-screens": "~4.11.1",
- "react-native-unistyles": "^3.0.0",
- "react-native-web": "^0.20.0"
+ "@tanstack/react-form": "^1.0.5",
+ "expo": "^54.0.0",
+ "expo-constants": "~18.0.8",
+ "expo-crypto": "~15.0.6",
+ "expo-linking": "~8.0.7",
+ "expo-router": "~6.0.0",
+ "expo-secure-store": "~15.0.6",
+ "expo-splash-screen": "~31.0.8",
+ "expo-status-bar": "^3.0.7",
+ "expo-system-ui": "~6.0.7",
+ "expo-dev-client": "~6.0.11",
+ "expo-web-browser": "~15.0.6",
+ "react": "19.1.0",
+ "react-dom": "19.1.0",
+ "react-native": "0.81.4",
+ "react-native-edge-to-edge": "^1.7.0",
+ "react-native-gesture-handler": "~2.28.0",
+ "react-native-nitro-modules": "^0.29.4",
+ "react-native-reanimated": "~4.1.0",
+ "react-native-safe-area-context": "~5.6.0",
+ "react-native-screens": "~4.16.0",
+ "react-native-unistyles": "^3.0.12",
+ "react-native-web": "^0.21.0",
+ "react-native-worklets": "^0.5.1"
},
"devDependencies": {
"ajv": "^8.17.1",
"@babel/core": "^7.28.0",
- "@types/react": "~19.0.10",
- "typescript": "~5.8.3"
- },
- "private": true
+ "@types/react": "~19.1.10",
+ "typescript": "~5.9.2"
+ }
}
diff --git a/apps/cli/templates/frontend/native/unistyles/theme.ts b/apps/cli/templates/frontend/native/unistyles/theme.ts
deleted file mode 100644
index c754ee7e1..000000000
--- a/apps/cli/templates/frontend/native/unistyles/theme.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-const sharedColors = {
- success: "#22C55E",
- destructive: "#EF4444",
- warning: "#F59E0B",
- info: "#3B82F6",
-} as const;
-
-export const lightTheme = {
- colors: {
- ...sharedColors,
- typography: "hsl(222.2 84% 4.9%)",
- background: "hsl(0 0% 100%)",
- foreground: "hsl(222.2 84% 4.9%)",
- card: "hsl(0 0% 100%)",
- cardForeground: "hsl(222.2 84% 4.9%)",
- primary: "hsl(221.2 83.2% 53.3%)",
- primaryForeground: "hsl(210 40% 98%)",
- secondary: "hsl(210 40% 96%)",
- secondaryForeground: "hsl(222.2 84% 4.9%)",
- muted: "hsl(210 40% 96%)",
- mutedForeground: "hsl(215.4 16.3% 46.9%)",
- accent: "hsl(210 40% 96%)",
- accentForeground: "hsl(222.2 84% 4.9%)",
- border: "hsl(214.3 31.8% 91.4%)",
- input: "hsl(214.3 31.8% 91.4%)",
- ring: "hsl(221.2 83.2% 53.3%)",
- },
- spacing: {
- xs: 4,
- sm: 8,
- md: 16,
- lg: 24,
- xl: 32,
- xxl: 48,
- },
- borderRadius: {
- sm: 6,
- md: 8,
- lg: 12,
- xl: 16,
- },
- fontSize: {
- xs: 12,
- sm: 14,
- base: 16,
- lg: 18,
- xl: 20,
- "2xl": 24,
- "3xl": 30,
- "4xl": 36,
- },
-} as const;
-
-export const darkTheme = {
- colors: {
- ...sharedColors,
- typography: "hsl(210 40% 98%)",
- background: "hsl(222.2 84% 4.9%)",
- foreground: "hsl(210 40% 98%)",
- card: "hsl(222.2 84% 4.9%)",
- cardForeground: "hsl(210 40% 98%)",
- primary: "hsl(217.2 91.2% 59.8%)",
- primaryForeground: "hsl(222.2 84% 4.9%)",
- secondary: "hsl(217.2 32.6% 17.5%)",
- secondaryForeground: "hsl(210 40% 98%)",
- muted: "hsl(217.2 32.6% 17.5%)",
- mutedForeground: "hsl(215 20.2% 65.1%)",
- accent: "hsl(217.2 32.6% 17.5%)",
- accentForeground: "hsl(210 40% 98%)",
- border: "hsl(217.2 32.6% 17.5%)",
- input: "hsl(217.2 32.6% 17.5%)",
- ring: "hsl(224.3 76.3% 94.1%)",
- },
- spacing: {
- xs: 4,
- sm: 8,
- md: 16,
- lg: 24,
- xl: 32,
- xxl: 48,
- },
- borderRadius: {
- sm: 6,
- md: 8,
- lg: 12,
- xl: 16,
- },
- fontSize: {
- xs: 12,
- sm: 14,
- base: 16,
- lg: 18,
- xl: 20,
- "2xl": 24,
- "3xl": 30,
- "4xl": 36,
- },
-} as const;
diff --git a/apps/cli/templates/frontend/native/unistyles/theme.ts.hbs b/apps/cli/templates/frontend/native/unistyles/theme.ts.hbs
new file mode 100644
index 000000000..4c58baac7
--- /dev/null
+++ b/apps/cli/templates/frontend/native/unistyles/theme.ts.hbs
@@ -0,0 +1,98 @@
+const sharedColors = {
+ success: "#22C55E",
+ destructive: "#EF4444",
+ warning: "#F59E0B",
+ info: "#3B82F6",
+} as const;
+
+export const lightTheme = {
+ colors: {
+ ...sharedColors,
+ typography: "hsl(0 0% 0%)",
+ background: "hsl(0 0% 100%)",
+ foreground: "hsl(0 0% 0%)",
+ card: "hsl(0 0% 98%)",
+ cardForeground: "hsl(0 0% 0%)",
+ primary: "hsl(0 0% 10%)",
+ primaryForeground: "hsl(0 0% 100%)",
+ secondary: "hsl(0 0% 95%)",
+ secondaryForeground: "hsl(0 0% 0%)",
+ muted: "hsl(0 0% 96%)",
+ mutedForeground: "hsl(0 0% 45%)",
+ accent: "hsl(0 0% 96%)",
+ accentForeground: "hsl(0 0% 0%)",
+ border: "hsl(0 0% 90%)",
+ input: "hsl(0 0% 90%)",
+ ring: "hsl(0 0% 20%)",
+ },
+ spacing: {
+ xs: 4,
+ sm: 8,
+ md: 16,
+ lg: 24,
+ xl: 32,
+ xxl: 48,
+ },
+ borderRadius: {
+ sm: 6,
+ md: 8,
+ lg: 12,
+ xl: 16,
+ },
+ fontSize: {
+ xs: 12,
+ sm: 14,
+ base: 16,
+ lg: 18,
+ xl: 20,
+ "2xl": 24,
+ "3xl": 30,
+ "4xl": 36,
+ },
+} as const;
+
+export const darkTheme = {
+ colors: {
+ ...sharedColors,
+ typography: "hsl(0 0% 100%)",
+ background: "hsl(0 0% 0%)",
+ foreground: "hsl(0 0% 100%)",
+ card: "hsl(0 0% 2%)",
+ cardForeground: "hsl(0 0% 100%)",
+ primary: "hsl(0 0% 90%)",
+ primaryForeground: "hsl(0 0% 0%)",
+ secondary: "hsl(0 0% 10%)",
+ secondaryForeground: "hsl(0 0% 100%)",
+ muted: "hsl(0 0% 8%)",
+ mutedForeground: "hsl(0 0% 65%)",
+ accent: "hsl(0 0% 8%)",
+ accentForeground: "hsl(0 0% 100%)",
+ border: "hsl(0 0% 15%)",
+ input: "hsl(0 0% 15%)",
+ ring: "hsl(0 0% 80%)",
+ },
+ spacing: {
+ xs: 4,
+ sm: 8,
+ md: 16,
+ lg: 24,
+ xl: 32,
+ xxl: 48,
+ },
+ borderRadius: {
+ sm: 6,
+ md: 8,
+ lg: 12,
+ xl: 16,
+ },
+ fontSize: {
+ xs: 12,
+ sm: 14,
+ base: 16,
+ lg: 18,
+ xl: 20,
+ "2xl": 24,
+ "3xl": 30,
+ "4xl": 36,
+ },
+} as const;
diff --git a/apps/cli/templates/frontend/native/unistyles/unistyles.ts b/apps/cli/templates/frontend/native/unistyles/unistyles.ts.hbs
similarity index 100%
rename from apps/cli/templates/frontend/native/unistyles/unistyles.ts
rename to apps/cli/templates/frontend/native/unistyles/unistyles.ts.hbs
diff --git a/apps/cli/templates/frontend/react/next/package.json.hbs b/apps/cli/templates/frontend/react/next/package.json.hbs
index 176702eab..352916244 100644
--- a/apps/cli/templates/frontend/react/next/package.json.hbs
+++ b/apps/cli/templates/frontend/react/next/package.json.hbs
@@ -15,8 +15,8 @@
"lucide-react": "^0.487.0",
"next": "15.5.0",
"next-themes": "^0.4.6",
- "react": "^19.0.0",
- "react-dom": "^19.0.0",
+ "react": "19.1.0",
+ "react-dom": "19.1.0",
"sonner": "^2.0.5",
"tailwind-merge": "^3.3.1",
"tw-animate-css": "^1.3.4",
@@ -25,7 +25,7 @@
"devDependencies": {
"@tailwindcss/postcss": "^4.1.10",
"@types/node": "^20",
- "@types/react": "^19",
+ "@types/react": "~19.1.10",
"@types/react-dom": "^19",
"tailwindcss": "^4.1.10",
"typescript": "^5"
diff --git a/apps/cli/templates/frontend/react/react-router/package.json.hbs b/apps/cli/templates/frontend/react/react-router/package.json.hbs
index 22e404d78..f81d1644d 100644
--- a/apps/cli/templates/frontend/react/react-router/package.json.hbs
+++ b/apps/cli/templates/frontend/react/react-router/package.json.hbs
@@ -19,8 +19,8 @@
"isbot": "^5.1.28",
"lucide-react": "^0.511.0",
"next-themes": "^0.4.6",
- "react": "19.0.0",
- "react-dom": "19.0.0",
+ "react": "19.1.0",
+ "react-dom": "19.1.0",
"react-router": "^7.6.1",
"sonner": "^2.0.3",
"tailwind-merge": "^3.3.0",
@@ -31,7 +31,7 @@
"@react-router/dev": "^7.6.1",
"@tailwindcss/vite": "^4.1.8",
"@types/node": "^20",
- "@types/react": "^19.0.12",
+ "@types/react": "~19.1.10",
"@types/react-dom": "^19.0.4",
"react-router-devtools": "^1.1.0",
"tailwindcss": "^4.1.8",
diff --git a/apps/cli/templates/frontend/react/tanstack-router/package.json.hbs b/apps/cli/templates/frontend/react/tanstack-router/package.json.hbs
index 325ba5dbf..04bc6fe59 100644
--- a/apps/cli/templates/frontend/react/tanstack-router/package.json.hbs
+++ b/apps/cli/templates/frontend/react/tanstack-router/package.json.hbs
@@ -20,8 +20,8 @@
"clsx": "^2.1.1",
"lucide-react": "^0.473.0",
"next-themes": "^0.4.6",
- "react": "^19.0.0",
- "react-dom": "^19.0.0",
+ "react": "19.1.0",
+ "react-dom": "19.1.0",
"sonner": "^2.0.5",
"tailwind-merge": "^3.3.1",
"tw-animate-css": "^1.2.5",
@@ -31,7 +31,7 @@
"@tanstack/react-router-devtools": "^1.114.27",
"@tanstack/router-plugin": "^1.114.27",
"@types/node": "^22.13.13",
- "@types/react": "^19.0.12",
+ "@types/react": "~19.1.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.3.4",
"postcss": "^8.5.3",
diff --git a/apps/cli/templates/frontend/react/tanstack-start/package.json.hbs b/apps/cli/templates/frontend/react/tanstack-start/package.json.hbs
index 53f80efc1..16e6fb519 100644
--- a/apps/cli/templates/frontend/react/tanstack-start/package.json.hbs
+++ b/apps/cli/templates/frontend/react/tanstack-start/package.json.hbs
@@ -20,8 +20,8 @@
"clsx": "^2.1.1",
"lucide-react": "^0.525.0",
"next-themes": "^0.4.6",
- "react": "19.0.0",
- "react-dom": "19.0.0",
+ "react": "19.1.0",
+ "react-dom": "19.1.0",
"sonner": "^2.0.3",
"tailwindcss": "^4.1.3",
"tailwind-merge": "^3.3.1",
@@ -33,7 +33,7 @@
"@tanstack/react-router-devtools": "^1.121.0-alpha.27",
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.2.0",
- "@types/react": "^19.0.12",
+ "@types/react": "~19.1.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^5.0.1",
"jsdom": "^26.0.0",