Skip to content

Conversation

@AmanVarshney01
Copy link
Owner

@AmanVarshney01 AmanVarshney01 commented Nov 9, 2025

  • add uniwind and bare expo example
  • nativewind

Note

Introduce new native frontends (Expo Bare, UniWind), remove NativeWind, and update CLI, templates, compatibility, analytics, and tests accordingly.

  • CLI & Types:
    • Add native-bare and native-uniwind frontend options; remove native-nativewind across flags, prompts, schemas, compatibility rules, and env/setup logic.
    • Update dependency map (e.g., alchemy), catalogs to include apps/native, and bun config conditions.
  • Templates:
    • Add comprehensive Expo Bare and UniWind templates (app layout, components, auth screens, examples: AI/Todo, polyfills, configs).
    • Update Better-Auth (Convex/server) templates to handle new native options and trusted origins.
    • Remove NativeWind templates.
  • Docs/README:
    • Reflect new frontend options and usage examples; adjust commands.
  • Analytics (web):
    • Update frontend legend/color mappings to include native-bare, native-uniwind, and replace NativeWind.
  • Tests:
    • Revise e2e/unit tests to use new native options and expectations.
  • Rules:
    • Add note to escape {{ in Handlebars templates.

Written by Cursor Bugbot for commit 22f93ed. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features

    • Added two native frontend options: Bare (Expo Bare, now default) and UniWind (Tailwind for RN).
  • Templates Updated

    • New and refreshed native templates, examples (Todo, AI), auth screens (Sign In/Sign Up), layouts, and tooling to support Bare and UniWind flows.
    • README/frontend option names updated to reflect the new tokens.
  • Deprecated

    • Removed the previous NativeWind frontend option and its associated templates.

@vercel
Copy link

vercel bot commented Nov 9, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
create-better-t-stack-web Ready Ready Preview Comment Nov 9, 2025 6:49pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 9, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This PR replaces the single native-nativewind frontend token with native-bare and native-uniwind, and updates CLI logic, templates, prompt options, types, examples, tests, and related assets to use and support the two new native variants.

Changes

Cohort / File(s) Summary
Type & Schema
apps/cli/src/types.ts
Removed native-nativewind; added native-bare and native-uniwind in FrontendSchema.
Prompts / README
apps/cli/src/prompts/frontend.ts, apps/cli/src/prompts/auth.ts, apps/cli/README.md
Replaced NativeWind option with Bare (native-bare), added UniWind (native-uniwind), updated initialValue/hints and auth compatibility lists; README usage updated.
CLI helpers — detection & wiring
apps/cli/src/helpers/* (api-setup.ts, auth-setup.ts, create-readme.ts, env-setup.ts, post-installation.ts, template-manager.ts), apps/cli/src/utils/better-auth-plugin-setup.ts
Expanded native feature checks and framework mappings to treat native-bare and native-uniwind (plus existing native-unistyles) as native variants; updated path resolution and template selection.
Addons / examples setup
apps/cli/src/helpers/addons/examples-setup.ts, apps/cli/src/helpers/addons/ultracite-setup.ts
Adjusted hasReactNative / frontend→framework mappings to include native-bare and native-uniwind.
Compatibility & validation
apps/cli/src/utils/compatibility-rules.ts, apps/cli/src/utils/config-validation.ts, apps/cli/src/utils/setup-catalogs.ts
Updated native classification, error/validation messages, and enabled apps/native in package catalog discovery.
Templates — auth (Better-Auth / Convex / server)
apps/cli/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs, .../http.ts.hbs, .../server/base/src/index.ts.hbs
Broadened Handlebars conditional checks and trustedOrigins to include native-bare and native-uniwind.
Templates — removed: NativeWind auth & frontend
apps/cli/templates/auth/better-auth/convex/native/nativewind/*, apps/cli/templates/frontend/native/nativewind/*
Deleted NativeWind-specific auth app and component templates, frontend layouts, components, global.css, metro/tailwind configs, and related files.
Templates — added: Bare & UniWind auth/frontend
apps/cli/templates/auth/better-auth/convex/native/uniwind/*, .../native/bare/*, apps/cli/templates/frontend/native/bare/*, apps/cli/templates/frontend/native/uniwind/*
Added Bare and UniWind templates (layouts, screens, components, metro/configs, global.css, theme/context, hooks, and example screens) and adapted auth wiring for both.
Templates — examples (todo & ai)
apps/cli/templates/examples/todo/native/*, apps/cli/templates/examples/ai/native/*
Removed NativeWind examples; added Bare and UniWind example screens (Todos, AI chat) with backend-conditional hooks and UI updates.
Auth — unistyles tweaks
apps/cli/templates/auth/better-auth/native/unistyles/*
Added API-conditional query invalidation/refetch blocks and conditional imports for ORPC/TRPC.
Extras / bunfig
apps/cli/templates/extras/bunfig.toml.hbs
Narrowed linker hoist condition (removed native-based branches).
Tests
apps/cli/test/*.test.ts (addons, api, auth, deployment, frontend, integration)
Replaced native-nativewind with native-bare and added native-uniwind across test matrices and assertions.
Web / UI constants & analytics
apps/web/src/lib/constant.ts, apps/web/src/app/(home)/analytics/*, apps/web/src/app/(home)/new/_components/utils.ts
Updated TECH_OPTIONS/nativeFrontend and frontendConfig to include native-bare and native-uniwind; adjusted labels, descriptions, color mappings, and compatibility messages.
Misc — constants
apps/cli/src/constants.ts
Bumped dependency version for alchemy from ^0.75.1 to ^0.77.0.
Repo rules / docs
.cursor/rules/better-t-stack-repo.mdc
Added guideline to escape {{ in Handlebars templates; removed explicit return type guideline.

Sequence Diagram(s)

sequenceDiagram
    participant User as CLI User
    participant Prompt as Frontend Prompt
    participant Types as Frontend Types
    participant Helpers as CLI Helpers
    participant TemplateMgr as Template Manager

    User->>Prompt: select frontend option
    Prompt->>Types: validate selection (native-bare / native-uniwind / native-unistyles)
    Types-->>Prompt: confirmed
    Prompt->>Helpers: build project config
    Helpers->>Helpers: evaluate native flags
    alt native detected
        Helpers->>TemplateMgr: request native templates
        TemplateMgr->>TemplateMgr: resolve framework path ("bare"/"uniwind"/"unistyles")
        TemplateMgr-->>Helpers: templates & assets to copy
    end
    Helpers-->>User: scaffold project
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas to focus during review:

  • apps/cli/src/helpers/core/template-manager.ts — framework path resolution and all conditional branches for bare/uniwind/unistyles.
  • Handlebars templates under auth/ and frontend/ — ensure no stale references to removed nativewind assets; verify ORPC/TRPC conditional blocks.
  • Tests — confirm enums, prompts, and expected assets match the new tokens and that removed template expectations are updated.

Possibly related PRs

Poem

🐰 I hopped the tokens, split the tide,

Bare and UniWind now side-by-side,
NativeWind’s nest softly cleared away,
New screens and templates greet the day,
I nibble tests and tidy seams—hip-hop—fresh native dreams!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(cli): add uniwind with heroui-native' clearly describes the main addition of a new native frontend option (Uniwind with heroui-native) that is central to this changeset. It accurately reflects the primary objective while maintaining clarity and conciseness.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch expo-overhaul

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/cli/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs (1)

34-44: Replace generic else block with explicit condition.

The generic {{else}} block violates the coding guideline and creates a potential runtime issue. Lines 42-43 use siteUrl which may be undefined if the frontend doesn't match any of the conditions in lines 17-19. Additionally, the else block duplicates the logic from lines 39-41.

As per coding guidelines

Apply this diff to remove the redundant else block:

-    {{else if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
+    {{else}}
     baseURL: siteUrl,
     trustedOrigins: [siteUrl],
-    {{else}}
-    trustedOrigins: [siteUrl],
     {{/if}}

This consolidates the duplicate logic while maintaining the same behavior. If there are other frontend types that need different handling, add explicit conditions for them.

apps/cli/templates/frontend/native/bare/app/(drawer)/_layout.tsx.hbs (1)

9-88: Switch DrawerLayout to a function declaration.
Line 9 currently uses an arrow component (const DrawerLayout = () => { ... }), which violates our directive to define JS/TS functions with the standard declaration syntax. Please convert it to a function DrawerLayout() declaration so the template stays compliant.

Apply this diff:

-const DrawerLayout = () => {
+function DrawerLayout() {
   const { colorScheme } = useColorScheme();
   const theme = colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light;
 
   return (
     <Drawer
       screenOptions={{{{
         headerStyle: {
           backgroundColor: theme.background,
         },
         headerTitleStyle: {
           color: theme.text,
         },
         headerTintColor: theme.text,
         drawerStyle: {
           backgroundColor: theme.background,
         },
         drawerLabelStyle: {
           color: theme.text,
         },
         drawerInactiveTintColor: theme.text,
       }}}}
     >
@@
-  );
-};
-
-export default DrawerLayout;
+  );
+}
+
+export default DrawerLayout;
apps/cli/src/helpers/core/template-manager.ts (1)

537-553: Copy native-bare auth templates

native-bare is now a supported frontend, but both Better Auth code paths only select uniwind/unistyles. As a result the bare-specific auth templates never get copied, leaving generated projects incomplete. Please include hasNativeBare when deriving nativeFrameworkPath.

-      if (hasUniwind) nativeFrameworkPath = "uniwind";
-      else if (hasUnistyles) nativeFrameworkPath = "unistyles";
+      if (hasNativeBare) nativeFrameworkPath = "bare";
+      else if (hasUniwind) nativeFrameworkPath = "uniwind";
+      else if (hasUnistyles) nativeFrameworkPath = "unistyles";
...
-    if (hasUniwind) {
-      nativeFrameworkAuthPath = "uniwind";
+    if (hasNativeBare) {
+      nativeFrameworkAuthPath = "bare";
+    } else if (hasUniwind) {
+      nativeFrameworkAuthPath = "uniwind";
     } else if (hasUnistyles) {
       nativeFrameworkAuthPath = "unistyles";
     }

Without this adjustment the new bare Expo variant ships without its auth scaffolding.

Also applies to: 699-703

🧹 Nitpick comments (6)
apps/cli/templates/frontend/native/bare/lib/android-navigation-bar.tsx.hbs (1)

5-11: Consider adding error handling for native API calls.

The async function calls setButtonStyleAsync and setBackgroundColorAsync without error handling. If these operations fail on certain devices or Android versions, the error will be silently swallowed. Consider wrapping in a try-catch or at least logging failures.

 export async function setAndroidNavigationBar(theme: "light" | "dark") {
   if (Platform.OS !== "android") return;
+  try {
-  await NavigationBar.setButtonStyleAsync(theme === "dark" ? "light" : "dark");
-  await NavigationBar.setBackgroundColorAsync(
-    theme === "dark" ? NAV_THEME.dark.background : NAV_THEME.light.background,
-  );
+    await NavigationBar.setButtonStyleAsync(theme === "dark" ? "light" : "dark");
+    await NavigationBar.setBackgroundColorAsync(
+      theme === "dark" ? NAV_THEME.dark.background : NAV_THEME.light.background,
+    );
+  } catch (error) {
+    console.warn("Failed to set Android navigation bar:", error);
+  }
 }
apps/cli/templates/extras/bunfig.toml.hbs (1)

2-6: Remove redundant or helper and consider using eq for explicit comparison.

The or helper with a single condition is unnecessary. Consider simplifying to:

-{{#if (or (includes frontend "nuxt"))}}
+{{#if (eq frontend "nuxt")}}
 linker = "hoisted" # having issues with Nuxt when linker is isolated
 {{else}}
 linker = "isolated"
 {{/if}}

If frontend is a string variable (as suggested by the coding guidelines example using eq), then eq provides a clearer exact match. If frontend is an array and you need substring matching, use includes without the or wrapper.

As per coding guidelines

apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs (2)

39-39: Add displayName for better debugging.

Components using forwardRef should have a displayName for better debugging in React DevTools.

Apply this diff to add the displayName:

 });
+
+HeaderButton.displayName = "HeaderButton";

27-36: Consider extracting pressed state to avoid inline style object.

The current implementation creates a new style object on every render. While functionally correct, extracting the pressed state could improve performance slightly.

Consider this alternative:

     >
-      {({ pressed }) => (
+      {() => (
         <FontAwesome
           name="info-circle"
           size={20}
           color={theme.text}
-          style={{
-            opacity: pressed ? 0.7 : 1,
-          }}
+          style={styles.icon}
         />
       )}
     </Pressable>

And update the styles:

 const styles = StyleSheet.create({
   button: {
     padding: 8,
     marginRight: 8,
     borderRadius: 8,
   },
+  icon: {
+    opacity: 1,
+  },
 });

Then use the container's pressed state to control the icon opacity via the button backgroundColor alone. Alternatively, if you need the opacity change, you can access pressed from the outer render prop.

apps/cli/templates/frontend/native/bare/metro.config.js.hbs (1)

6-6: Remove redundant explicit unstable_enablePackageExports setting or explain its necessity.

The unstable_enablePackageExports option is experimental and enabled by default. Explicitly setting it to true in the template is redundant. Either remove this line or add a comment explaining why it's necessary for this template, as no package exports are evident in the generated bare Expo project structure.

apps/cli/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs (1)

12-20: Remove unused header styles when headerShown is false.

Lines 13-20 define header styling options (backgroundColor, tintColor, titleStyle), but line 12 sets headerShown: false, making these styles ineffective. Either remove the unused style definitions or set headerShown: true if headers are intended to be visible.

Apply this diff if headers are not needed:

 		<Tabs
 			screenOptions=\{{
 				headerShown: false,
-				headerStyle: {
-					backgroundColor: themeColorBackground,
-				},
-				headerTintColor: themeColorForeground,
-				headerTitleStyle: {
-					color: themeColorForeground,
-					fontWeight: "600",
-				},
 				tabBarStyle: {
 					backgroundColor: themeColorBackground,
 				},

Or set headerShown: true if headers should be visible.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7cf7b57 and d79092a.

📒 Files selected for processing (89)
  • apps/cli/README.md (2 hunks)
  • apps/cli/src/helpers/addons/examples-setup.ts (1 hunks)
  • apps/cli/src/helpers/addons/ultracite-setup.ts (1 hunks)
  • apps/cli/src/helpers/core/api-setup.ts (3 hunks)
  • apps/cli/src/helpers/core/auth-setup.ts (4 hunks)
  • apps/cli/src/helpers/core/create-readme.ts (3 hunks)
  • apps/cli/src/helpers/core/env-setup.ts (2 hunks)
  • apps/cli/src/helpers/core/post-installation.ts (2 hunks)
  • apps/cli/src/helpers/core/template-manager.ts (9 hunks)
  • apps/cli/src/prompts/auth.ts (2 hunks)
  • apps/cli/src/prompts/frontend.ts (2 hunks)
  • apps/cli/src/types.ts (1 hunks)
  • apps/cli/src/utils/better-auth-plugin-setup.ts (1 hunks)
  • apps/cli/src/utils/compatibility-rules.ts (3 hunks)
  • apps/cli/src/utils/config-validation.ts (1 hunks)
  • apps/cli/src/utils/setup-catalogs.ts (1 hunks)
  • apps/cli/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs (4 hunks)
  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/convex/native/nativewind/components/sign-in.tsx.hbs (0 hunks)
  • apps/cli/templates/auth/better-auth/convex/native/nativewind/components/sign-up.tsx.hbs (0 hunks)
  • apps/cli/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/nativewind/app/(drawer)/index.tsx.hbs (0 hunks)
  • apps/cli/templates/auth/better-auth/native/nativewind/components/sign-in.tsx.hbs (0 hunks)
  • apps/cli/templates/auth/better-auth/native/nativewind/components/sign-up.tsx.hbs (0 hunks)
  • apps/cli/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs (5 hunks)
  • apps/cli/templates/examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs (5 hunks)
  • apps/cli/templates/examples/ai/native/uniwind/polyfills.js (1 hunks)
  • apps/cli/templates/examples/todo/native/nativewind/app/(drawer)/todos.tsx.hbs (0 hunks)
  • apps/cli/templates/examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs (1 hunks)
  • apps/cli/templates/extras/bunfig.toml.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/_gitignore (1 hunks)
  • apps/cli/templates/frontend/native/bare/app.json.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/_layout.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/_layout.tsx.hbs (3 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/+not-found.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/modal.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/babel.config.js.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/components/container.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/components/tabbar-icon.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/lib/android-navigation-bar.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/lib/constants.ts.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/lib/use-color-scheme.ts.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/metro.config.js.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/package.json.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/tsconfig.json.hbs (1 hunks)
  • apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/app/+not-found.tsx.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/app/_layout.tsx.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/app/modal.tsx.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/components/container.tsx.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/components/header-button.tsx.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/global.css (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/metro.config.js.hbs (0 hunks)
  • apps/cli/templates/frontend/native/nativewind/tailwind.config.js.hbs (0 hunks)
  • apps/cli/templates/frontend/native/uniwind/_gitignore (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app.json.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app/+not-found.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app/modal.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/components/container.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/contexts/app-theme-context.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/global.css (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/metro.config.js.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/package.json.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/tsconfig.json.hbs (1 hunks)
  • apps/cli/test/addons.test.ts (2 hunks)
  • apps/cli/test/api.test.ts (3 hunks)
  • apps/cli/test/auth.test.ts (3 hunks)
  • apps/cli/test/deployment.test.ts (3 hunks)
  • apps/cli/test/frontend.test.ts (5 hunks)
  • apps/cli/test/integration.test.ts (4 hunks)
💤 Files with no reviewable changes (18)
  • apps/cli/templates/frontend/native/nativewind/app/+not-found.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/native/nativewind/components/sign-in.tsx.hbs
  • apps/cli/templates/frontend/native/nativewind/tailwind.config.js.hbs
  • apps/cli/templates/auth/better-auth/convex/native/nativewind/components/sign-up.tsx.hbs
  • apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs
  • apps/cli/templates/frontend/native/nativewind/app/_layout.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/nativewind/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/frontend/native/nativewind/app/modal.tsx.hbs
  • apps/cli/templates/frontend/native/nativewind/global.css
  • apps/cli/templates/auth/better-auth/native/nativewind/components/sign-in.tsx.hbs
  • apps/cli/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs
  • apps/cli/templates/frontend/native/nativewind/metro.config.js.hbs
  • apps/cli/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs
  • apps/cli/templates/examples/todo/native/nativewind/app/(drawer)/todos.tsx.hbs
  • apps/cli/templates/frontend/native/nativewind/components/header-button.tsx.hbs
  • apps/cli/templates/frontend/native/nativewind/components/container.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/nativewind/components/sign-up.tsx.hbs
  • apps/cli/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{hbs,handlebars}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

In Handlebars templates, avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle")).

Files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs
  • apps/cli/templates/frontend/native/bare/lib/constants.ts.hbs
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/bare/metro.config.js.hbs
  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs
  • apps/cli/templates/frontend/native/bare/components/container.tsx.hbs
  • apps/cli/templates/frontend/native/bare/components/tabbar-icon.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/components/container.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/+not-found.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs
  • apps/cli/templates/extras/bunfig.toml.hbs
  • apps/cli/templates/frontend/native/bare/app/modal.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs
  • apps/cli/templates/frontend/native/bare/lib/use-color-scheme.ts.hbs
  • apps/cli/templates/frontend/native/uniwind/app/+not-found.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/bare/package.json.hbs
  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs
  • apps/cli/templates/frontend/native/bare/babel.config.js.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/contexts/app-theme-context.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app.json.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/metro.config.js.hbs
  • apps/cli/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/_layout.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app/modal.tsx.hbs
  • apps/cli/templates/frontend/native/bare/tsconfig.json.hbs
  • apps/cli/templates/frontend/native/uniwind/package.json.hbs
  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
  • apps/cli/templates/examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs
  • apps/cli/templates/frontend/native/bare/lib/android-navigation-bar.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app.json.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs
  • apps/cli/templates/examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/tsconfig.json.hbs
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

**/*.{ts,tsx}: Use Id from './_generated/dataModel' to type document ids (e.g., Id<'users'>)
Ensure Record key/value types align with validators (e.g., v.record(v.id('users'), v.string()) => Record<Id<'users'>, string>)
Be strict with types for document ids; prefer Id<'table'> over string
Use 'as const' for string literals in discriminated unions
When using Array and Record types, declare with explicit generic types (e.g., const arr: Array = ...)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations.
Do not use explicit return types in TypeScript.

Files:

  • apps/cli/src/utils/config-validation.ts
  • apps/cli/test/auth.test.ts
  • apps/cli/src/types.ts
  • apps/cli/src/helpers/core/api-setup.ts
  • apps/cli/test/api.test.ts
  • apps/cli/src/helpers/core/env-setup.ts
  • apps/cli/src/prompts/frontend.ts
  • apps/cli/src/helpers/core/auth-setup.ts
  • apps/cli/src/helpers/core/post-installation.ts
  • apps/cli/src/helpers/addons/examples-setup.ts
  • apps/cli/src/utils/compatibility-rules.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/prompts/auth.ts
  • apps/cli/test/addons.test.ts
  • apps/cli/src/utils/better-auth-plugin-setup.ts
  • apps/cli/test/deployment.test.ts
  • apps/cli/test/integration.test.ts
  • apps/cli/test/frontend.test.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/utils/setup-catalogs.ts
  • apps/cli/src/helpers/core/create-readme.ts
**/*.{js,jsx,ts,tsx,mjs,cjs}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{js,jsx,ts,tsx,mjs,cjs}: Do not use dotenv; Bun auto-loads .env
Use Bun.serve() for HTTP/WebSockets; do not use express
Use bun:sqlite for SQLite; do not use better-sqlite3
Use Bun.redis for Redis; do not use ioredis
Use Bun.sql for Postgres; do not use pg or postgres.js
Use built-in WebSocket; do not use ws
Prefer Bun.file over node:fs readFile/writeFile
Use Bun.$ instead of execa for shelling out

Files:

  • apps/cli/src/utils/config-validation.ts
  • apps/cli/test/auth.test.ts
  • apps/cli/src/types.ts
  • apps/cli/src/helpers/core/api-setup.ts
  • apps/cli/test/api.test.ts
  • apps/cli/src/helpers/core/env-setup.ts
  • apps/cli/src/prompts/frontend.ts
  • apps/cli/src/helpers/core/auth-setup.ts
  • apps/cli/src/helpers/core/post-installation.ts
  • apps/cli/src/helpers/addons/examples-setup.ts
  • apps/cli/src/utils/compatibility-rules.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/prompts/auth.ts
  • apps/cli/test/addons.test.ts
  • apps/cli/src/utils/better-auth-plugin-setup.ts
  • apps/cli/test/deployment.test.ts
  • apps/cli/templates/examples/ai/native/uniwind/polyfills.js
  • apps/cli/test/integration.test.ts
  • apps/cli/test/frontend.test.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/utils/setup-catalogs.ts
  • apps/cli/src/helpers/core/create-readme.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions.

Files:

  • apps/cli/src/utils/config-validation.ts
  • apps/cli/test/auth.test.ts
  • apps/cli/src/types.ts
  • apps/cli/src/helpers/core/api-setup.ts
  • apps/cli/test/api.test.ts
  • apps/cli/src/helpers/core/env-setup.ts
  • apps/cli/src/prompts/frontend.ts
  • apps/cli/src/helpers/core/auth-setup.ts
  • apps/cli/src/helpers/core/post-installation.ts
  • apps/cli/src/helpers/addons/examples-setup.ts
  • apps/cli/src/utils/compatibility-rules.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/prompts/auth.ts
  • apps/cli/test/addons.test.ts
  • apps/cli/src/utils/better-auth-plugin-setup.ts
  • apps/cli/test/deployment.test.ts
  • apps/cli/templates/examples/ai/native/uniwind/polyfills.js
  • apps/cli/test/integration.test.ts
  • apps/cli/test/frontend.test.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/utils/setup-catalogs.ts
  • apps/cli/src/helpers/core/create-readme.ts
🧠 Learnings (22)
📚 Learning: 2025-09-11T04:31:24.508Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Applies to **/*.{hbs,handlebars} : In Handlebars templates, avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle")).

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Always use the new Convex function syntax (query/mutation/action/internal*) with args/returns/handler

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs
  • apps/cli/src/utils/config-validation.ts
  • apps/cli/src/prompts/auth.ts
  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Always include argument and return validators for all Convex functions (public and internal)

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs
  • apps/cli/src/utils/config-validation.ts
  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/schema.ts : Always define the Convex schema in convex/schema.ts and import schema helpers from convex/server

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs
  • apps/cli/src/utils/config-validation.ts
  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Use v.null() instead of undefined; undefined is not a valid Convex value

Applied to files:

  • apps/cli/src/utils/config-validation.ts
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Use v.int64() instead of deprecated v.bigint() for 64-bit integers

Applied to files:

  • apps/cli/src/utils/config-validation.ts
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/_generated/api.ts : Use the generated api object to reference public functions

Applied to files:

  • apps/cli/src/utils/config-validation.ts
  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/_generated/api.ts : Use the generated internal object to reference internal functions

Applied to files:

  • apps/cli/src/utils/config-validation.ts
📚 Learning: 2025-08-24T18:01:11.544Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-08-24T18:01:11.544Z
Learning: Applies to {**/package.json,**/webpack.config.@(js|ts|mjs|cjs),**/esbuild.config.@(js|ts|mjs|cjs)} : Use `bun build <file>` instead of `webpack` or `esbuild`

Applied to files:

  • apps/cli/templates/extras/bunfig.toml.hbs
  • apps/cli/templates/frontend/native/uniwind/tsconfig.json.hbs
📚 Learning: 2025-08-24T18:01:11.544Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-08-24T18:01:11.544Z
Learning: Applies to {**/package.json,**/@(jest|vitest).config.@(js|ts|mjs|cjs)} : Use `bun test` to run tests

Applied to files:

  • apps/cli/test/api.test.ts
📚 Learning: 2025-06-08T17:57:33.083Z
Learnt from: Vijayabaskar56
Repo: AmanVarshney01/create-better-t-stack PR: 310
File: apps/cli/templates/frontend/angular/src/app.component.html:1-7
Timestamp: 2025-06-08T17:57:33.083Z
Learning: The Angular frontend template uses Tailwind CSS v4, which doesn't require a traditional tailwind.config.js configuration file.

Applied to files:

  • apps/cli/templates/frontend/native/bare/package.json.hbs
  • apps/cli/templates/frontend/native/uniwind/global.css
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to package.json : Add types/node to package.json when using Node.js built-in modules

Applied to files:

  • apps/cli/templates/frontend/native/bare/package.json.hbs
📚 Learning: 2025-08-24T18:01:11.544Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-08-24T18:01:11.544Z
Learning: Applies to **/*.{js,jsx,ts,tsx,mjs,cjs} : Use `Bun.$` instead of `execa` for shelling out

Applied to files:

  • apps/cli/src/prompts/auth.ts
  • apps/cli/src/helpers/core/template-manager.ts
📚 Learning: 2025-08-24T18:01:11.544Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-08-24T18:01:11.544Z
Learning: Applies to {**/package.json,**/@(jest|vitest).config.@(js|ts|mjs|cjs)} : Use `bun test` instead of `jest` or `vitest`

Applied to files:

  • apps/cli/test/integration.test.ts
  • apps/cli/test/frontend.test.ts
📚 Learning: 2025-09-11T04:31:24.508Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript type aliases instead of interface declarations.

Applied to files:

  • apps/cli/templates/frontend/native/bare/tsconfig.json.hbs
📚 Learning: 2025-09-11T04:31:24.508Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Applies to **/*.{ts,tsx} : Do not use explicit return types in TypeScript.

Applied to files:

  • apps/cli/templates/frontend/native/bare/tsconfig.json.hbs
  • apps/cli/templates/frontend/native/uniwind/tsconfig.json.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/http.ts : Define HTTP endpoints only in convex/http.ts and wrap handlers with httpAction

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/http.ts : HTTP endpoints are registered at the exact path specified in route.path (no implicit prefixes)

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Respect file-based routing: api.<path>.<name> for public and internal.<path>.<name> for private functions based on file location/name

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Use query/mutation/action for public API; use internalQuery/internalMutation/internalAction for private functions; do not register via api/internal objects

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:01:11.544Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-08-24T18:01:11.544Z
Learning: Applies to **/*.{js,jsx,ts,tsx,mjs,cjs} : Use `Bun.serve()` for HTTP/WebSockets; do not use `express`

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/backend/convex/http.ts.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to **/*.{ts,tsx} : Use 'as const' for string literals in discriminated unions

Applied to files:

  • apps/cli/templates/frontend/native/uniwind/tsconfig.json.hbs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (63)
apps/cli/templates/frontend/native/bare/_gitignore (1)

1-18: Solid .gitignore template for bare Expo projects.

The gitignore patterns are appropriate and comprehensive, covering dependencies, build artifacts, Expo/Metro tooling, macOS metadata, and critically, security-sensitive files (keys, certificates, provisioning profiles). The structure is clear and follows common conventions.

apps/cli/templates/frontend/native/bare/tsconfig.json.hbs (1)

1-11: LGTM! Standard Expo TypeScript configuration.

The tsconfig.json template follows Expo best practices with strict mode enabled and appropriate path aliases. The include patterns correctly reference Expo-generated types and source files.

Verify that the "@/*" path alias correctly maps to the project structure when the template is rendered. Ensure that imports using @/ resolve properly from the generated bare Expo project root.

apps/cli/src/utils/setup-catalogs.ts (1)

28-28: LGTM! Native apps can now use catalog dependencies.

Re-enabling the native app path allows its dependencies to participate in catalog-based deduplication. The existing pathExists check at line 43 ensures this won't cause errors for projects without a native app. Verification confirms native templates are properly scaffolded and the path is safely referenced throughout the codebase.

apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs (1)

19-21: The native frontend identifiers in the template are correct and consistent.

The three native frontend options—native-bare, native-uniwind, and native-unistyles—are legitimate, distinct options defined throughout the codebase. They represent different styling approaches for Expo:

  • native-bare: Bare Expo without styling library
  • native-uniwind: Expo with Tailwind CSS (UniWind)
  • native-unistyles: Expo with Unistyles styling

All three are present in the type definitions, prompts, and compatibility checks. The template correctly checks for all three as valid native frontend selections.

Likely an incorrect or invalid review comment.

apps/cli/templates/examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs (7)

1-16: LGTM! Clean design system integration.

The imports correctly introduce Pressable for modern touch handling and Card + useThemeColor from heroui-native for consistent theming across the native UI.


18-27: LGTM! Robust URL construction.

The explicit slash handling in line 25 ensures consistent API URL formatting regardless of input format—good defensive coding practice.


29-42: LGTM! Theme-driven initialization.

The theme color hooks (lines 39-42) enable consistent, theme-aware styling throughout the component. The useChat configuration with custom transport is properly set up.


56-71: LGTM! Improved error presentation.

Wrapping the error state in a Card (lines 60-67) with semantic danger colors creates a visually distinct and accessible error state that aligns with the design system.


73-98: LGTM! Clean layout structure.

The KeyboardAvoidingView platform handling (line 77) and empty state messaging follow React Native best practices. The text hierarchy is clear and theme-consistent.


100-136: LGTM! Card-based message layout.

The Card component usage (lines 102-134) provides consistent visual treatment for messages. The role-based variants and conditional styling (lines 104-109) create clear visual distinction between user and AI messages. The parts rendering logic (lines 115-131) correctly handles both text and non-text content types.


138-167: LGTM! Modern input area with excellent UX.

The Pressable component (lines 152-165) provides better touch handling than the previous TouchableOpacity. The conditional styling (lines 155-157, 162) gives clear visual feedback based on input state—accent colors when ready to send, muted when disabled. The theme color integration for placeholder and icons maintains design consistency.

apps/cli/templates/frontend/native/uniwind/tsconfig.json.hbs (2)

5-8: LGTM: Path alias configuration is correct.

The baseUrl and paths configuration properly enables module aliasing with @/* for cleaner imports.


10-13: No issues found with the .d.ts handling in this tsconfig.

The configuration extends expo/tsconfig.base and includes only .ts and .tsx files. Verification showed no custom .d.ts files exist in the uniwind template directory, and the Expo base configuration handles standard type resolution. For a template that users scaffold projects from, this pattern is appropriate—if developers add custom ambient declarations later, they can configure tsconfig accordingly or use a dedicated types folder.

apps/cli/templates/frontend/native/uniwind/package.json.hbs (5)

1-12: LGTM!

The package metadata and scripts are correctly configured for an Expo Router project. The main entry point and standard Expo scripts are appropriate.


19-22: Verify compliance with coding guidelines for conditional logic.

The conditional block uses (includes examples "ai") to check array membership. As per coding guidelines, explicit conditions like (eq orm "prisma") are preferred. While includes is checking for a specific value ("ai"), verify that this pattern is acceptable for array membership checks in your Handlebars templates, as the guideline specifically mentions using eq for explicit comparisons.

As per coding guidelines


48-54: LGTM!

The devDependencies are appropriately minimal for a TypeScript-based React Native project, and the private flag is correctly set for a project template.


32-32: Versions verified as valid and available.

React 19.1.0 and Tailwind CSS 4.1.16 are both confirmed to exist and are stable releases on npm. No issues detected.


34-34: The review comment is based on outdated information and should be disregarded.

React Native 0.81.5 is the intended version for Expo SDK 54, making the concern about inconsistent versioning unfounded. The version has been verified to exist on npm, and Expo SDK 54 targets React Native 0.81.x, so version 0.81.5 is within the fully supported range. React Native has evolved to the 0.8x version line as of November 2025, which is normal progression.

Likely an incorrect or invalid review comment.

apps/cli/templates/frontend/native/uniwind/_gitignore (1)

18-20: LGTM!

Correctly excludes generated UniWind type definitions from version control.

apps/cli/templates/frontend/native/bare/package.json.hbs (1)

1-51: LGTM!

The removal of nativewind and tailwindcss dependencies correctly aligns this template with a "bare" Expo setup, as described in the PR objectives.

apps/cli/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs (1)

1-15: LGTM!

The component correctly uses standard function declaration syntax and follows the expected structure for a UniWind template.

apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs (1)

57-59: Verify environment variable availability.

Line 57 uses a non-null assertion (!) on process.env.EXPO_PUBLIC_CONVEX_URL. If this environment variable is not set, it will pass undefined to the ConvexReactClient constructor, potentially causing a runtime error.

Ensure that the setup process guarantees this environment variable is always present, or add runtime validation.

apps/cli/src/helpers/addons/examples-setup.ts (1)

58-61: LGTM! Frontend token update is correct.

The update correctly replaces native-nativewind with native-bare and native-uniwind while preserving native-unistyles, aligning with the PR's frontend restructuring.

apps/cli/src/types.ts (1)

30-31: LGTM! Core type definition updated correctly.

The FrontendSchema enum correctly removes native-nativewind and adds native-bare and native-uniwind. This change is consistently reflected across the codebase in helpers, templates, tests, and validation logic.

apps/cli/README.md (1)

60-60: LGTM! Documentation updated correctly.

The CLI help text and example commands correctly reflect the new frontend tokens native-bare and native-uniwind (replacing native-nativewind).

Also applies to: 122-122

apps/cli/src/utils/better-auth-plugin-setup.ts (1)

34-41: LGTM! Better-Auth plugin condition updated correctly.

The condition now correctly checks for native-bare and native-uniwind alongside native-unistyles to trigger the expo plugin, consistent with the frontend restructuring.

apps/cli/test/deployment.test.ts (1)

66-66: LGTM! Test cases updated correctly.

The deployment test cases correctly use native-bare instead of native-nativewind for validating web deployment constraints with native frontends.

Also applies to: 87-87, 544-544

apps/cli/test/auth.test.ts (1)

130-132: LGTM! Authentication tests updated with comprehensive coverage.

The test cases now include native-bare and native-uniwind in the compatible frontends lists for both Better-Auth and Clerk, ensuring the new native frontend options are properly tested.

Also applies to: 217-219, 460-460

apps/cli/src/utils/config-validation.ts (1)

218-220: LGTM! Validation logic updated correctly.

The supported frontends list for Better-Auth with Convex backend now correctly includes native-bare and native-uniwind (replacing native-nativewind), ensuring proper configuration validation.

apps/cli/test/addons.test.ts (2)

77-83: LGTM! Consistent renaming for PWA incompatibility.

The replacement of native-nativewind with native-bare and native-uniwind correctly maintains PWA addon incompatibility for all native frontend options.


157-161: LGTM! Consistent renaming for Tauri incompatibility.

The changes correctly update Tauri addon incompatibility checks to include both new native frontend options.

apps/cli/src/prompts/auth.ts (2)

16-25: LGTM! Better Auth compatibility updated correctly.

The frontend compatibility check for Better Auth now correctly includes both native-bare and native-uniwind, maintaining feature parity with the previous native-nativewind option.


27-37: LGTM! Clerk compatibility updated consistently.

The Clerk compatibility check mirrors the Better Auth changes, ensuring both new native frontend options are supported.

apps/cli/src/helpers/addons/ultracite-setup.ts (1)

114-137: LGTM! Framework mapping updated correctly.

Both native-bare and native-uniwind correctly map to the "react" framework, which is appropriate since they are React Native-based frontends.

apps/cli/test/integration.test.ts (4)

117-136: LGTM! Mobile app test updated to use native-bare.

The integration test correctly uses the new native-bare frontend option for testing mobile app creation.


377-396: LGTM! PWA incompatibility test updated correctly.

The test correctly verifies that the PWA addon remains incompatible with the native-bare frontend option.


444-463: LGTM! Deployment constraint test updated correctly.

The test correctly uses native-bare to verify that web deployment requires a web frontend and fails with native-only frontends.


467-486: LGTM! Hybrid app test updated correctly.

The maximum complexity test now uses native-bare alongside tanstack-router, correctly testing hybrid web + mobile configurations.

apps/cli/src/helpers/core/env-setup.ts (2)

227-272: LGTM! Native environment setup updated correctly.

The conditional logic correctly includes both native-bare and native-uniwind for native app environment variable configuration, ensuring proper setup for both new frontend options.


280-308: LGTM! Convex native detection updated consistently.

The native frontend detection for Convex backend environment setup correctly includes both new native options, ensuring proper configuration for Convex with native frontends.

apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs (1)

1-43: LGTM! Well-structured tab component with proper theming.

The TabTwo component follows React Native best practices:

  • Correctly integrates with the color scheme system
  • Uses consistent styling patterns
  • Applies theme colors appropriately
  • Maintains good visual hierarchy with opacity
apps/cli/templates/frontend/native/uniwind/global.css (1)

1-5: No issues found. The configuration is correct.

The heroui-native package is properly declared as a dependency in package.json.hbs (version ^1.0.0-beta.1), and the @source path ./node_modules/heroui-native/lib is the correct location for accessing the library's files after npm installation. The imports are consistent with how heroui-native is actively used throughout the template files.

apps/cli/templates/frontend/native/uniwind/app.json.hbs (1)

1-16: Now I need to verify the actual Metro and CSS configuration files in the Uniwind template:


The app.json configuration is correct as-is. Uniwind only supports Tailwind 4, and it handles styling configuration through metro.config.js with withUniwindConfig() and a global.css file, not through app.json plugins. The expo-font plugin is the appropriate and sufficient plugin for this template. The minimal configuration is intentional for Uniwind's architecture.

apps/cli/test/api.test.ts (3)

52-52: Great coverage for new native frontends.

Thanks for expanding the tRPC native matrix to include native-bare and native-uniwind alongside native-unistyles.


184-186: ORPC matrix stays in sync.

Appreciate that the oRPC sweep now tests the bare and uniwind stacks too.


569-569: Edge combo reflects the new default.

Good call updating the complex frontend combo to pair web with native-bare.

apps/cli/templates/frontend/native/uniwind/metro.config.js.hbs (1)

1-12: Uniwind metro config looks solid.

Wrapping Expo’s default config with withUniwindConfig and setting the CSS/DTS entry points lines up with the expected Uniwind setup.

apps/cli/src/prompts/frontend.ts (1)

95-111: Prompt update aligns with new native stacks.

The Bare default plus Uniwind option matches the expanded frontend schema and keeps the CLI prompt consistent.

apps/cli/templates/frontend/native/bare/app/modal.tsx.hbs (1)

1-36: Modal component integrates theming cleanly.

Nice to see the bare template reusing Container and pulling text color from NAV_THEME; everything lines up.

apps/cli/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs (1)

12-90: LGTM!

The SignIn component is well-structured with proper state management, error handling, and theme integration. The authentication flow correctly handles loading states and provides user feedback.

apps/cli/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs (1)

10-34: LGTM!

The ThemeToggle component properly integrates platform-specific haptics, smooth animations, and theme state management. The use of withUniwind HOC correctly enables className-based styling for the Ionicons.

apps/cli/src/helpers/core/create-readme.ts (2)

325-327: Consistent update in generateProjectStructure.

The native frontend detection logic is correctly updated here as well, maintaining consistency with the changes at lines 46-48.


407-409: Consistent update in generateFeaturesList.

The native frontend detection is correctly updated, completing the migration across all functions in this file.

apps/cli/templates/frontend/native/uniwind/app/modal.tsx.hbs (1)

7-53: LGTM!

The Modal component follows Expo Router modal patterns correctly, with proper navigation handling via router.back() and consistent theme integration. The UI structure with Card components is well-organized.

apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs (1)

6-43: LGTM!

The TabOne component correctly implements theme-aware styling using the color scheme hook and NAV_THEME constants. The use of StyleSheet follows React Native best practices.

apps/cli/test/frontend.test.ts (4)

17-33: Test configuration correctly updated for new native frontend options.

The singleFrontends array now includes native-bare and native-uniwind instead of the removed native-nativewind, with matching type annotations. This ensures all new native frontend variants are tested.


342-342: Test correctly uses native-bare for multiple native frontends validation.

The test case now validates that users cannot select both native-bare and native-unistyles, maintaining the constraint logic with the updated frontend tokens.


363-363: Test correctly uses native-bare for web-native combination.

The web-native combo test now uses native-bare alongside tanstack-router, validating that one web and one native frontend can be selected together.


495-495: Test correctly validates web deploy requirement with native-bare.

The test now uses native-bare to verify that web deployment options require a web frontend, not just a native frontend.

apps/cli/src/utils/compatibility-rules.ts (3)

26-28: Native frontend detection correctly updated.

The splitFrontends function now properly identifies all three native frontend variants: native-bare, native-uniwind, and native-unistyles. This ensures compatibility validation works correctly with the new frontend options.


40-42: Error message accurately reflects available native frontends.

The validation message now lists all three supported native frontend options, providing clear guidance to users when they attempt to select multiple native frameworks.


74-76: Consistent error message in self-backend validation.

The error message for fullstack (self-backend) native framework validation is consistently updated to match the changes elsewhere in the file.

apps/cli/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs (1)

24-49: Switch handleSignUp to a function declaration

Project guidelines require standard function declarations instead of arrow functions. Converting handleSignUp keeps the logic unchanged while aligning with the convention.

-  const handleSignUp = async () => {
+  async function handleSignUp() {
     setIsLoading(true);
     setError(null);

     await authClient.signUp.email(
       {
         name,
         email,
         password,
       },
       {
         onError: (error) => {
           setError(error.error?.message || "Failed to sign up");
           setIsLoading(false);
         },
         onSuccess: () => {
           setName("");
           setEmail("");
           setPassword("");
         },
         onFinished: () => {
           setIsLoading(false);
         },
       },
     );
-  };
+  }

[As per coding guidelines]

⛔ Skipped due to learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Define functions using the standard function declaration syntax, not arrow functions.

Comment on lines 12 to 36
screenOptions=\{{{
headerShown: false,
tabBarActiveTintColor: isDarkColorScheme
? "hsl(217.2 91.2% 59.8%)"
: "hsl(221.2 83.2% 53.3%)",
tabBarInactiveTintColor: isDarkColorScheme
? "hsl(215 20.2% 65.1%)"
: "hsl(215.4 16.3% 46.9%)",
tabBarActiveTintColor: theme.primary,
tabBarInactiveTintColor: theme.text,
tabBarStyle: {
backgroundColor: isDarkColorScheme
? "hsl(222.2 84% 4.9%)"
: "hsl(0 0% 100%)",
borderTopColor: isDarkColorScheme
? "hsl(217.2 32.6% 17.5%)"
: "hsl(214.3 31.8% 91.4%)",
backgroundColor: theme.background,
borderTopColor: theme.border,
},
}}
}}}
>
<Tabs.Screen
name="index"
options=\{{
options=\{{{
title: "Home",
tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color} />,
}}
}}}
/>
<Tabs.Screen
name="two"
options=\{{
options=\{{{
title: "Explore",
tabBarIcon: ({ color }) => (
<TabBarIcon name="compass" color={color} />
),
}}
}}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Revert to double braces in generated JSX.

Changing to \{{{ … }}} causes Handlebars to emit literal triple braces, so the generated Expo Router layout becomes screenOptions={{{ … }}}, which is invalid JSX. Please return to the standard double-brace form (no backslash, no extra {).

Apply this diff:

-    <Tabs
-      screenOptions=\{{{
+    <Tabs
+      screenOptions={{
@@
-        },
-      }}}
+        },
+      }}
@@
-      <Tabs.Screen
-        name="index"
-        options=\{{{
+      <Tabs.Screen
+        name="index"
+        options={{
@@
-        name="two"
-        options=\{{{
+        name="two"
+        options={{
@@
-          ),
-        }}}
+          ),
+        }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
screenOptions=\{{{
headerShown: false,
tabBarActiveTintColor: isDarkColorScheme
? "hsl(217.2 91.2% 59.8%)"
: "hsl(221.2 83.2% 53.3%)",
tabBarInactiveTintColor: isDarkColorScheme
? "hsl(215 20.2% 65.1%)"
: "hsl(215.4 16.3% 46.9%)",
tabBarActiveTintColor: theme.primary,
tabBarInactiveTintColor: theme.text,
tabBarStyle: {
backgroundColor: isDarkColorScheme
? "hsl(222.2 84% 4.9%)"
: "hsl(0 0% 100%)",
borderTopColor: isDarkColorScheme
? "hsl(217.2 32.6% 17.5%)"
: "hsl(214.3 31.8% 91.4%)",
backgroundColor: theme.background,
borderTopColor: theme.border,
},
}}
}}}
>
<Tabs.Screen
name="index"
options=\{{
options=\{{{
title: "Home",
tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color} />,
}}
}}}
/>
<Tabs.Screen
name="two"
options=\{{
options=\{{{
title: "Explore",
tabBarIcon: ({ color }) => (
<TabBarIcon name="compass" color={color} />
),
}}
}}}
screenOptions={{
headerShown: false,
tabBarActiveTintColor: theme.primary,
tabBarInactiveTintColor: theme.text,
tabBarStyle: {
backgroundColor: theme.background,
borderTopColor: theme.border,
},
}}
>
<Tabs.Screen
name="index"
options={{
title: "Home",
tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color} />,
}}
/>
<Tabs.Screen
name="two"
options={{
title: "Explore",
tabBarIcon: ({ color }) => (
<TabBarIcon name="compass" color={color} />
),
}}
🤖 Prompt for AI Agents
In apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/_layout.tsx.hbs
around lines 12 to 36, the template currently emits triple-brace sequences like
\{{{ … }}} which produce invalid JSX (screenOptions={{{ … }}}) in the generated
Expo Router layout; change those occurrences back to standard double-brace JSX
syntax by replacing any \{{{ and }}} (and any backslash-escaped variants) with {
and } pairs that result in screenOptions={{ ... }} and options={{ ... }} so the
generated file uses valid JSX object literals for screenOptions and options.

Comment on lines +52 to +100
{{#if (eq backend "convex")}}
const isConnected = healthCheck === "OK";
const isLoading = healthCheck === undefined;
{{else}}
{{#unless (eq api "none")}}
const isConnected = healthCheck?.data === "OK";
const isLoading = healthCheck?.isLoading;
{{/unless}}
{{/if}}

return (
<Container className="p-6">
<View className="py-4 mb-6">
<Text className="text-4xl font-bold text-foreground mb-2">
BETTER T STACK
</Text>
</View>

{{#unless (and (eq backend "convex") (eq auth "better-auth"))}}
<Card variant="secondary" className="p-6">
<View className="flex-row items-center justify-between mb-4">
<Card.Title>System Status</Card.Title>
<Chip
variant="secondary"
color={isConnected ? "success" : "danger"}
size="sm"
>
<Chip.Label>
{isConnected ? "LIVE" : "OFFLINE"}
</Chip.Label>
</Chip>
</View>
<Card className="p-4">
<View className="flex-row items-center">
<View
className={`w-3 h-3 rounded-full mr-3 ${
isConnected ? "bg-success" : "bg-muted"
}`}
/>
<View className="flex-1">
<Text className="text-foreground font-medium mb-1">
{{#if (eq backend "convex")}}
Convex Backend
{{else}}
{{#unless (eq api "none")}}
{{#if (eq api "orpc")}}ORPC{{else}}TRPC{{/if}} Backend
{{/unless}}
{{/if}}
</Text>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Guard the status card when api === "none"

When the template runs with api set to "none", the const declarations for isConnected/isLoading are omitted (Lines 56-59), but the System Status card (Lines 70-120) still renders and references those identifiers. The generated file will fail to compile with ReferenceError: isConnected is not defined. Please either skip rendering the card when api === "none" or provide fallback declarations so the identifiers always exist.

🤖 Prompt for AI Agents
In apps/cli/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs around
lines 52 to 100, the System Status card references isConnected/isLoading which
are not declared when api === "none", causing a runtime/compile error; fix by
guarding the card with a Handlebars conditional (wrap the entire Card block in
{{#unless (eq api "none")}} ... {{/unless}}) so it's not rendered when api is
"none", or alternatively add an else branch that defines fallback consts (e.g.,
const isConnected = false; const isLoading = false;) before the return so the
identifiers always exist.

},
}
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Async Inconsistency: Broken Error Handling

The signUpHandler function is missing the async keyword but calls authClient.signUp.email() which returns a promise. Without async, the promise isn't awaited and errors won't be properly caught. The corresponding handleLogin in sign-in.tsx.hbs correctly uses async, showing this is an inconsistency that breaks error handling.

Fix in Cursor Fix in Web

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

♻️ Duplicate comments (2)
apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs (1)

7-9: Incorrect ref type causes TypeScript errors.

The first type parameter of forwardRef should be the element instance type, not the component type. typeof Pressable refers to the component constructor, which is incorrect. For Pressable components, the ref type should be View.

Apply this diff to fix the ref type:

-import { Pressable, StyleSheet } from "react-native";
+import { Pressable, StyleSheet, View } from "react-native";

 export const HeaderButton = forwardRef<
-  typeof Pressable,
+  View,
   { onPress?: () => void }
 >(({ onPress }, ref) => {
apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs (1)

124-159: Replace bare {{else}} branches with explicit conditions

The default Convex branch (Line 124) and the API fallback (Line 150) still rely on a plain {{else}}. Our Handlebars guideline requires explicit conditions, as previously flagged, so please rewrite these branches to something like {{else if (eq auth "none")}} and {{else if (eq api "none")}}, adjusting the surrounding blocks as needed to keep the logic the same.
As per coding guidelines

🧹 Nitpick comments (10)
apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs (1)

7-39: Consider adding a displayName for better debugging.

Components created with forwardRef benefit from an explicit displayName property, which improves the debugging experience in React DevTools.

Add a displayName after the component definition:

 });
+
+HeaderButton.displayName = "HeaderButton";
apps/cli/templates/frontend/native/uniwind/app.json.hbs (2)

1-19: Add missing critical Expo configuration fields.

The template is missing several standard Expo app.json fields that are typically required or recommended for production apps:

  • version (required for app store submissions and OTA updates)
  • icon path for the app icon
  • splash screen configuration
  • ios and android platform-specific settings (bundle identifiers, build numbers, etc.)
  • assetBundlePatterns to specify which assets to bundle

Consider extending the template to include these fields:

 {
   "expo": {
     "scheme": "{{projectName}}",
+    "version": "1.0.0",
     "userInterfaceStyle": "automatic",
     "orientation": "default",
+    "icon": "./assets/icon.png",
+    "splash": {
+      "image": "./assets/splash.png",
+      "resizeMode": "contain",
+      "backgroundColor": "#ffffff"
+    },
     "web": {
       "bundler": "metro"
     },
     "name": "{{projectName}}",
     "slug": "{{projectName}}",
+    "ios": {
+      "bundleIdentifier": "com.{{projectName}}.app",
+      "supportsTablet": true
+    },
+    "android": {
+      "package": "com.{{projectName}}.app",
+      "adaptiveIcon": {
+        "foregroundImage": "./assets/adaptive-icon.png",
+        "backgroundColor": "#ffffff"
+      }
+    },
+    "assetBundlePatterns": [
+      "**/*"
+    ],
     "plugins": [
       "expo-font"
     ],
     "experiments": {
       "typedRoutes": true,
       "reactCompiler": true
     }
   }
 }

11-13: Remove unused expo-font plugin to reduce bundle size.

The expo-font plugin and dependency are not used anywhere in the uniwind template. No font loading logic exists (no useFonts, Font.loadAsync, or custom font imports found). Since the template relies on system fonts and icon libraries, this plugin can be safely removed from both app.json.hbs (lines 11–13) and package.json.hbs.

apps/cli/src/helpers/core/template-manager.ts (3)

75-75: Remove unused variable _hasNative.

The variable _hasNative is declared but never used. Line 205 duplicates the same condition inline instead of using this variable. Either remove the variable or use it at line 205.

Apply this diff to use the variable:

-	if (hasNativeBare || hasNativeUniwind || hasUnistyles) {
+	if (_hasNative) {

Or remove the unused variable entirely:

-	const _hasNative = hasNativeBare || hasNativeUniwind || hasUnistyles;

224-230: Consider extracting the repeated native framework path resolution pattern.

This if-else chain for mapping native frontend tokens to framework path strings is duplicated at lines 447-450, 534-537, 697-703, and 1049-1055. Consider extracting it to a helper function to improve maintainability.

Example helper function:

function getNativeFrameworkPath(context: ProjectConfig) {
  if (context.frontend.includes("native-bare")) return "bare";
  if (context.frontend.includes("native-uniwind")) return "uniwind";
  if (context.frontend.includes("native-unistyles")) return "unistyles";
  return "";
}

Then use it consistently:

-		let nativeFrameworkPath = "";
-		if (hasNativeBare) {
-			nativeFrameworkPath = "bare";
-		} else if (hasNativeUniwind) {
-			nativeFrameworkPath = "uniwind";
-		} else if (hasUnistyles) {
-			nativeFrameworkPath = "unistyles";
-		}
+		const nativeFrameworkPath = getNativeFrameworkPath(context);

389-389: Use consistent variable naming for native frameworks.

The variable hasUniwind is inconsistent with hasNativeUniwind used in setupFrontendTemplates at line 73. For consistency and searchability, use the full name hasNativeUniwind throughout the file. This same issue appears at lines 1044 and 1078.

Apply this diff:

-	const hasUniwind = context.frontend.includes("native-uniwind");
+	const hasNativeUniwind = context.frontend.includes("native-uniwind");

And update references at lines 391, 449, 536, 700, 1044, 1047, 1051, 1078, 1080.

apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs (1)

93-93: Consider using theme values for button colors.

The hardcoded #ffffff colors could be replaced with theme values for better consistency and dark mode support.

Apply this diff:

-        {isLoading ? (
-          <ActivityIndicator size="small" color="#ffffff" />
-        ) : (
-          <Text style={styles.buttonText}>Sign Up</Text>
+        {isLoading ? (
+          <ActivityIndicator size="small" color={theme.card} />
+        ) : (
+          <Text style={[styles.buttonText, { color: theme.card }]}>Sign Up</Text>
         )}

And update the StyleSheet:

   buttonText: {
-    color: "#ffffff",
     fontSize: 16,
     fontWeight: "500",
   },

Also applies to: 139-139

apps/cli/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs (1)

99-103: Consider using theme values for button colors.

Similar to the Convex variant, the hardcoded #ffffff colors could use theme values for consistency.

Also applies to: 145-149

apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs (1)

82-82: Consider using theme values for button colors.

The hardcoded #ffffff colors could be replaced with theme values for better consistency, similar to the SignUp component.

Also applies to: 127-127

apps/cli/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs (1)

75-75: Consider using theme values for button colors.

Same as the other templates: hardcoded #ffffff could use theme values.

Also applies to: 120-120

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d79092a and ddad5ea.

📒 Files selected for processing (15)
  • apps/cli/src/helpers/core/template-manager.ts (9 hunks)
  • apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs (1 hunks)
  • apps/cli/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs (1 hunks)
  • apps/cli/templates/examples/ai/native/bare/polyfills.js (1 hunks)
  • apps/cli/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/_layout.tsx.hbs (2 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/_layout.tsx.hbs (2 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/components/container.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/uniwind/app.json.hbs (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/cli/templates/examples/ai/native/bare/polyfills.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/cli/templates/frontend/native/bare/components/container.tsx.hbs
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{hbs,handlebars}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

In Handlebars templates, avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle")).

Files:

  • apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs
  • apps/cli/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app.json.hbs
  • apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs
  • apps/cli/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

**/*.{ts,tsx}: Use Id from './_generated/dataModel' to type document ids (e.g., Id<'users'>)
Ensure Record key/value types align with validators (e.g., v.record(v.id('users'), v.string()) => Record<Id<'users'>, string>)
Be strict with types for document ids; prefer Id<'table'> over string
Use 'as const' for string literals in discriminated unions
When using Array and Record types, declare with explicit generic types (e.g., const arr: Array = ...)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations.
Do not use explicit return types in TypeScript.

Files:

  • apps/cli/src/helpers/core/template-manager.ts
**/*.{js,jsx,ts,tsx,mjs,cjs}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{js,jsx,ts,tsx,mjs,cjs}: Do not use dotenv; Bun auto-loads .env
Use Bun.serve() for HTTP/WebSockets; do not use express
Use bun:sqlite for SQLite; do not use better-sqlite3
Use Bun.redis for Redis; do not use ioredis
Use Bun.sql for Postgres; do not use pg or postgres.js
Use built-in WebSocket; do not use ws
Prefer Bun.file over node:fs readFile/writeFile
Use Bun.$ instead of execa for shelling out

Files:

  • apps/cli/src/helpers/core/template-manager.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions.

Files:

  • apps/cli/src/helpers/core/template-manager.ts
🧠 Learnings (2)
📚 Learning: 2025-09-11T04:31:24.508Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Applies to **/*.{hbs,handlebars} : In Handlebars templates, avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle")).

Applied to files:

  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs
📚 Learning: 2025-08-24T18:01:11.544Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-08-24T18:01:11.544Z
Learning: Applies to **/*.{js,jsx,ts,tsx,mjs,cjs} : Use `Bun.$` instead of `execa` for shelling out

Applied to files:

  • apps/cli/src/helpers/core/template-manager.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (4)
apps/cli/src/helpers/core/template-manager.ts (1)

697-703: Past review concern resolved: native-bare now supported.

The previous review flagged that native-bare was missing from this auth path resolution. The code now correctly handles native-bare by checking hasNativeBare first and setting the path to "bare". This resolves the inconsistency with Clerk auth handling.

apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs (1)

14-48: LGTM! Auth flow correctly omits queryClient for Convex.

The SignUp component correctly handles the authentication flow for Convex, which manages its own reactivity without needing manual query refetching.

apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs (1)

14-45: LGTM! Auth flow correctly omits queryClient for Convex.

The SignIn component correctly handles the authentication flow for Convex without manual query refetching.

apps/cli/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs (1)

45-45: Verify that api is always either "trpc" or "orpc".

Same verification needed as in the SignUp template: ensure queryClient is always imported when used.

Run the verification script provided in the SignUp template review comment.

Comment on lines +2 to +7
{{#if (eq api "trpc")}}
import { queryClient } from "@/utils/trpc";
{{/if}}
{{#if (eq api "orpc")}}
import { queryClient } from "@/utils/orpc";
{{/if}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Refactor to use else if in Handlebars template.

Same issue as in the SignUp template: use explicit else if for mutually exclusive API conditions.

Apply this diff:

-{{#if (eq api "trpc")}}
+{{#if (eq api "trpc")}}
 import { queryClient } from "@/utils/trpc";
-{{/if}}
-{{#if (eq api "orpc")}}
+{{else if (eq api "orpc")}}
 import { queryClient } from "@/utils/orpc";
 {{/if}}

As per coding guidelines.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{#if (eq api "trpc")}}
import { queryClient } from "@/utils/trpc";
{{/if}}
{{#if (eq api "orpc")}}
import { queryClient } from "@/utils/orpc";
{{/if}}
{{#if (eq api "trpc")}}
import { queryClient } from "@/utils/trpc";
{{else if (eq api "orpc")}}
import { queryClient } from "@/utils/orpc";
{{/if}}
🤖 Prompt for AI Agents
In apps/cli/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs
around lines 2 to 7, the template uses two separate Handlebars {{#if}} blocks
for mutually exclusive api values which can render both; change them to a single
conditional chain by replacing the second standalone {{#if (eq api "orpc")}}
with an {{else if (eq api "orpc")}} branch so only one import is emitted based
on the api value and keep closing tags correctly.

Comment on lines 64 to 79
<TextInput style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor:
theme.background }]} placeholder="Email" placeholderTextColor={theme.text} value={email}
onChangeText={setEmail} keyboardType="email-address" autoCapitalize="none" />

<TextInput style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor:
theme.background }]} placeholder="Password" placeholderTextColor={theme.text} value={password}
onChangeText={setPassword} secureTextEntry />

<TouchableOpacity onPress={handleLogin} disabled={isLoading} style={[styles.button, { backgroundColor:
theme.primary, opacity: isLoading ? 0.5 : 1 }]}>
{isLoading ? (
<ActivityIndicator size="small" color="#ffffff" />
) : (
<Text style={styles.buttonText}>Sign In</Text>
)}
</TouchableOpacity>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Fix JSX formatting for readability.

The JSX elements are broken across lines in a way that makes the code hard to read and maintain.

Apply this diff to fix formatting:

-        <TextInput style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor:
-            theme.background }]} placeholder="Email" placeholderTextColor={theme.text} value={email}
-            onChangeText={setEmail} keyboardType="email-address" autoCapitalize="none" />
+        <TextInput
+          style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}
+          placeholder="Email"
+          placeholderTextColor={theme.text}
+          value={email}
+          onChangeText={setEmail}
+          keyboardType="email-address"
+          autoCapitalize="none"
+        />

-        <TextInput style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor:
-            theme.background }]} placeholder="Password" placeholderTextColor={theme.text} value={password}
-            onChangeText={setPassword} secureTextEntry />
+        <TextInput
+          style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}
+          placeholder="Password"
+          placeholderTextColor={theme.text}
+          value={password}
+          onChangeText={setPassword}
+          secureTextEntry
+        />

-        <TouchableOpacity onPress={handleLogin} disabled={isLoading} style={[styles.button, { backgroundColor:
-            theme.primary, opacity: isLoading ? 0.5 : 1 }]}>
+        <TouchableOpacity
+          onPress={handleLogin}
+          disabled={isLoading}
+          style={[styles.button, { backgroundColor: theme.primary, opacity: isLoading ? 0.5 : 1 }]}
+        >
             {isLoading ? (
-            <ActivityIndicator size="small" color="#ffffff" />
+              <ActivityIndicator size="small" color="#ffffff" />
             ) : (
-            <Text style={styles.buttonText}>Sign In</Text>
+              <Text style={styles.buttonText}>Sign In</Text>
             )}
         </TouchableOpacity>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<TextInput style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor:
theme.background }]} placeholder="Email" placeholderTextColor={theme.text} value={email}
onChangeText={setEmail} keyboardType="email-address" autoCapitalize="none" />
<TextInput style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor:
theme.background }]} placeholder="Password" placeholderTextColor={theme.text} value={password}
onChangeText={setPassword} secureTextEntry />
<TouchableOpacity onPress={handleLogin} disabled={isLoading} style={[styles.button, { backgroundColor:
theme.primary, opacity: isLoading ? 0.5 : 1 }]}>
{isLoading ? (
<ActivityIndicator size="small" color="#ffffff" />
) : (
<Text style={styles.buttonText}>Sign In</Text>
)}
</TouchableOpacity>
<TextInput
style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}
placeholder="Email"
placeholderTextColor={theme.text}
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
/>
<TextInput
style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}
placeholder="Password"
placeholderTextColor={theme.text}
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<TouchableOpacity
onPress={handleLogin}
disabled={isLoading}
style={[styles.button, { backgroundColor: theme.primary, opacity: isLoading ? 0.5 : 1 }]}
>
{isLoading ? (
<ActivityIndicator size="small" color="#ffffff" />
) : (
<Text style={styles.buttonText}>Sign In</Text>
)}
</TouchableOpacity>
🤖 Prompt for AI Agents
In apps/cli/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs
around lines 64 to 79 the JSX props and nested children are broken across lines
making it hard to read; reformat each TextInput and the TouchableOpacity so
props are one-per-line (style, placeholder, placeholderTextColor, value,
onChangeText, keyboardType, autoCapitalize, secureTextEntry, disabled) with
consistent indentation, wrap long style objects onto multiple lines, place the
ActivityIndicator and the fallback Text each on their own indented lines inside
the TouchableOpacity, and ensure closing tags align with their openings for
clear, consistent JSX formatting.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
apps/cli/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs (1)

20-29: This issue was already flagged in a previous review.

The generateAPIUrl function throws during render when EXPO_PUBLIC_SERVER_URL is missing, causing a hard crash before any error UI can mount. As noted in the previous review, this should degrade gracefully with a friendly configuration message instead.

apps/cli/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs (1)

18-58: Add async keyword to prevent broken error handling.

The signUpHandler function calls authClient.signUp.email() without the async keyword, so the promise isn't awaited and errors won't be caught properly. This is inconsistent with the corresponding handleLogin in sign-in.tsx.hbs (lines 29-58), which correctly uses async.

Apply this diff:

-function signUpHandler({
+async function signUpHandler({
   name,
   email,
   password,
   setError,
   setIsLoading,
   setName,
   setEmail,
   setPassword,
 }) {
   setIsLoading(true);
   setError(null);

-  authClient.signUp.email(
+  await authClient.signUp.email(
     {
       name,
       email,
       password,
     },
apps/cli/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs (1)

215-259: Fix invalid JSX style expressions (still outstanding).

The template still emits style={{ styles.loadingText, { … } }} and similar patterns, which compile to invalid JSX and break the generated app. Please wrap multi-part styles in arrays and use plain expressions for single-style bindings.

-              <Text style=\{{ styles.loadingText, { color: theme.text, opacity: 0.7 } }}>
+              <Text
+                style={[
+                  styles.loadingText,
+                  \{{ color: theme.text, opacity: 0.7 }},
+                ]}
+              >
...
-              <Text style=\{{ styles.emptyTitle, { color: theme.text } }}>
+              <Text
+                style={[
+                  styles.emptyTitle,
+                  \{{ color: theme.text }},
+                ]}
+              >
...
-              <Text style=\{{ styles.emptyText, { color: theme.text, opacity: 0.7 } }}>
+              <Text
+                style={[
+                  styles.emptyText,
+                  \{{ color: theme.text, opacity: 0.7 }},
+                ]}
+              >
...
-                    <TouchableOpacity
-                      onPress={() => handleDeleteTodo(todo._id)}
-                      style=\{{ styles.deleteButton }}
-                    >
+                    <TouchableOpacity
+                      onPress={() => handleDeleteTodo(todo._id)}
+                      style={styles.deleteButton}
+                    >
...
-              <Text style=\{{ styles.emptyTitle, { color: theme.text } }}>
+              <Text
+                style={[
+                  styles.emptyTitle,
+                  \{{ color: theme.text }},
+                ]}
+              >
...
-              <Text style=\{{ styles.emptyText, { color: theme.text, opacity: 0.7 } }}>
+              <Text
+                style={[
+                  styles.emptyText,
+                  \{{ color: theme.text, opacity: 0.7 }},
+                ]}
+              >

Also applies to: 279-283

🧹 Nitpick comments (9)
.cursor/rules/better-t-stack-repo.mdc (1)

10-10: Improve clarity of the Handlebars escaping guideline.

The new rule about escaping {{ in Handlebars templates is valuable context given the PR's template refactors. However, the guideline could be clearer about the purpose and edge cases. Consider rewording to explain why this escaping is necessary (e.g., to avoid unintended Handlebars expressions).

Suggested improvement:

- - escape the '{{' in hbs templates like '\{{'
+ - Escape '{{' in Handlebars templates as '\{{' to prevent unintended variable interpolation.
apps/cli/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs (1)

44-49: Consider consolidating duplicate refetch calls.

Both API conditions execute the identical queryClient.refetchQueries() call. Since the queryClient interface is the same for both ORPC and TRPC, you can simplify this to a single unconditional call.

Apply this diff:

-          {{#if (eq api "orpc")}}
-          queryClient.refetchQueries();
-          {{/if}}
-          {{#if (eq api "trpc")}}
           queryClient.refetchQueries();
-          {{/if}}
apps/cli/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs (1)

41-46: Consider consolidating the duplicate refetch call.

Both the orpc and trpc branches execute identical logic. While the imports differ, the refetch call is duplicated.

If your Handlebars environment supports an or helper, you can simplify this to:

-          {{#if (eq api "orpc")}}
-          queryClient.refetchQueries();
-          {{/if}}
-          {{#if (eq api "trpc")}}
           queryClient.refetchQueries();
-          {{/if}}
+          {{#if (or (eq api "orpc") (eq api "trpc"))}}
+          queryClient.refetchQueries();
+          {{/if}}

Alternatively, if an or helper isn't available, the current explicit approach is acceptable per the coding guidelines, though it does result in some duplication.

apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs (1)

6-24: Consider adding accessibility props for better screen reader support.

The Text components would benefit from accessibility labels to improve screen reader support. This is especially important for navigation elements in mobile apps.

Apply this diff to enhance accessibility:

-          <Text style={[styles.title, { color: theme.text }]}>
+          <Text 
+            style={[styles.title, { color: theme.text }]}
+            accessibilityRole="header"
+          >
             Tab One
           </Text>
-          <Text style={[styles.subtitle, { color: theme.text, opacity: 0.7 }]}>
+          <Text 
+            style={[styles.subtitle, { color: theme.text, opacity: 0.7 }]}
+            accessibilityRole="text"
+          >
             Explore the first section of your app
           </Text>
apps/cli/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs (1)

163-163: Simplify boolean prop syntax.

The ={true} is redundant in JSX. The shorter form autoFocus is more idiomatic.

-                autoFocus={true}
+                autoFocus
apps/cli/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs (2)

8-15: Consider extracting the common useQuery import.

The useQuery import from @tanstack/react-query is duplicated in both the orpc and trpc conditional blocks. You can reduce duplication by extracting it:

+{{#unless (eq api "none")}}
+import { useQuery } from "@tanstack/react-query";
+{{/unless}}
 {{#if (eq api "orpc")}}
-import { useQuery } from "@tanstack/react-query";
 import { queryClient, orpc } from "@/utils/orpc";
 {{/if}}
 {{#if (eq api "trpc")}}
-import { useQuery } from "@tanstack/react-query";
 import { queryClient, trpc } from "@/utils/trpc";
 {{/if}}

43-53: Consider consolidating the duplicate invalidateQueries call.

The queryClient.invalidateQueries() call is duplicated in both conditional blocks. Since both orpc and trpc use the same invalidation logic, you can simplify:

 <TouchableOpacity
   style={styles.signOutButton}
   onPress={() => {
     authClient.signOut();
-    {{#if (eq api "orpc")}}
-    queryClient.invalidateQueries();
-    {{/if}}
-    {{#if (eq api "trpc")}}
+    {{#unless (eq api "none")}}
     queryClient.invalidateQueries();
-    {{/if}}
+    {{/unless}}
   }}
 >
apps/cli/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs (1)

25-27: Consider removing unused theme colors.

The accentColor and dangerColor hooks are defined but never referenced in the component. The UI uses Tailwind classes (bg-accent, text-danger) instead of these programmatic colors. Consider removing these unused hooks to reduce unnecessary re-renders.

Apply this diff:

   const mutedColor = useThemeColor("muted");
-  const accentColor = useThemeColor("accent");
   const foregroundColor = useThemeColor("foreground");
-  const dangerColor = useThemeColor("danger");
apps/cli/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs (1)

68-70: Consider removing unused theme colors.

accentColor and dangerColor are defined but never used. The component relies on Tailwind classes (bg-accent, text-danger) instead. Removing these unused hooks can reduce unnecessary re-renders.

Apply this diff:

   const mutedColor = useThemeColor("muted");
-  const accentColor = useThemeColor("accent");
   const foregroundColor = useThemeColor("foreground");
-  const dangerColor = useThemeColor("danger");
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ddad5ea and 2b547ed.

📒 Files selected for processing (20)
  • .cursor/rules/better-t-stack-repo.mdc (1 hunks)
  • apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs (3 hunks)
  • apps/cli/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs (1 hunks)
  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs (1 hunks)
  • apps/cli/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs (1 hunks)
  • apps/cli/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/+not-found.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/app/modal.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/+not-found.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/modal.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{hbs,handlebars}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

In Handlebars templates, avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle")).

Files:

  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs
  • apps/cli/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs
🧠 Learnings (9)
📚 Learning: 2025-09-11T04:31:24.508Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Applies to **/*.{hbs,handlebars} : In Handlebars templates, avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle")).

Applied to files:

  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs
  • .cursor/rules/better-t-stack-repo.mdc
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Use query/mutation/action for public API; use internalQuery/internalMutation/internalAction for private functions; do not register via api/internal objects

Applied to files:

  • apps/cli/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Minimize action calls to queries/mutations to avoid transactional race conditions

Applied to files:

  • apps/cli/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs
  • apps/cli/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs
📚 Learning: 2025-09-11T04:31:24.508Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Applies to **/*.{ts,tsx} : Do not use explicit return types in TypeScript.

Applied to files:

  • .cursor/rules/better-t-stack-repo.mdc
📚 Learning: 2025-09-11T04:31:24.508Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Define functions using the standard function declaration syntax, not arrow functions.

Applied to files:

  • .cursor/rules/better-t-stack-repo.mdc
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to convex/**/*.ts : Always use the new Convex function syntax (query/mutation/action/internal*) with args/returns/handler

Applied to files:

  • .cursor/rules/better-t-stack-repo.mdc
📚 Learning: 2025-09-11T04:31:24.508Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Always use functional programming; avoid object-oriented programming.

Applied to files:

  • .cursor/rules/better-t-stack-repo.mdc
📚 Learning: 2025-09-11T04:31:24.508Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-09-11T04:31:24.508Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript type aliases instead of interface declarations.

Applied to files:

  • .cursor/rules/better-t-stack-repo.mdc
📚 Learning: 2025-08-24T18:00:39.152Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-08-24T18:00:39.152Z
Learning: Applies to **/*.{ts,tsx} : Use 'as const' for string literals in discriminated unions

Applied to files:

  • .cursor/rules/better-t-stack-repo.mdc
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (10)
.cursor/rules/better-t-stack-repo.mdc (1)

9-10: Clarify inconsistency: summary claims line 9 was removed, but it appears in the current code.

The AI summary states the guideline "Do not use explicit return types" was removed, yet line 9 still contains this rule. Please verify whether this line was modified, moved, or if the summary is inaccurate.

apps/cli/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs (2)

1-4: LGTM!

Imports are clean and well-organized with appropriate use of absolute path aliases.


26-42: LGTM!

StyleSheet definitions are well-structured and follow React Native best practices with appropriate spacing and typography.

apps/cli/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs (1)

59-90: Conditional rendering logic is correct.

The {{#unless (eq api "none")}} wrapper ensures the API Status section is only rendered when api queries are defined (orpc or trpc), preventing undefined variable references. This change properly aligns the UI rendering with data availability.

apps/cli/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs (1)

46-51: LGTM! QueryClient guards are now correct.

The queryClient.refetchQueries() calls are properly wrapped in conditional blocks that match the import guards. This resolves the previous concern about runtime crashes when api = "none".

apps/cli/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs (1)

23-48: LGTM! Auth flow is correctly implemented.

The handleSignUp function properly uses async/await to handle the authentication promise, and the lifecycle callbacks (onError, onSuccess, onFinished) correctly manage state transitions. The Convex-only setup appropriately omits query client refetch calls.

apps/cli/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs (1)

46-51: LGTM! QueryClient guards are correct.

The queryClient.refetchQueries() calls are now properly wrapped in conditional blocks matching the import guards, resolving the previous concern about crashes when api = "none".

apps/cli/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs (1)

30-163: LGTM! Template conditionals and style expressions are correct.

The Handlebars conditionals properly follow the guideline to use explicit conditions (e.g., {{#if (eq api "orpc")}} and {{else if (eq api "trpc")}}). Style expressions correctly use either array syntax for combining styles or escaped braces for single objects. The guards around API-dependent code prevent undefined variable references when api = "none".

Based on coding guidelines

apps/cli/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs (1)

17-123: LGTM! API guards prevent undefined variable references.

The template correctly guards all API-dependent code:

  • Lines 18-29: healthCheck and privateData queries only defined when api is "trpc" or "orpc"
  • Lines 68-113: UI consuming these variables guarded by {{#unless (eq api "none")}}
  • Lines 55-60: queryClient.invalidateQueries() calls properly wrapped in conditional blocks

This prevents ReferenceErrors when api = "none" and resolves the previous concern.

apps/cli/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs (1)

17-111: LGTM! Proper guards for API-dependent code.

The template correctly handles optional API integration:

  • Lines 20-31: Query definitions conditional on api type
  • Lines 67-99: UI using query results guarded by {{#unless (eq api "none")}}
  • Lines 54-59: queryClient.invalidateQueries() calls wrapped in matching conditionals

All variable references are safe regardless of API configuration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/cli/src/helpers/core/auth-setup.ts (1)

102-130: Eliminate duplicate variable declarations.

The native variant checks (hasNativeBare, hasNativeUniwind, hasUnistyles) are declared twice—once at lines 102-104 and again at lines 124-126—with identical logic. This creates unnecessary duplication and maintenance burden.

Refactor by defining these variables once at the beginning of the Convex backend block:

 	try {
 		if (backend === "convex") {
+			const hasNativeBare = frontend.includes("native-bare");
+			const hasNativeUniwind = frontend.includes("native-uniwind");
+			const hasUnistyles = frontend.includes("native-unistyles");
+
 			if (auth === "clerk" && clientDirExists) {
 				const hasNextJs = frontend.includes("next");

Then remove the duplicate declarations at lines 102-104 and 124-126.

🧹 Nitpick comments (2)
apps/cli/src/helpers/core/auth-setup.ts (2)

54-57: Consider extracting native variant checks to helper variables for consistency.

While the inline checks are functionally correct, lines 102-104 and 124-126 use explicit helper variables (hasNativeBare, hasNativeUniwind, hasUnistyles) for the same checks. Consider refactoring this section to match that pattern for consistency.

+				const hasNativeBare = frontend.includes("native-bare");
+				const hasNativeUniwind = frontend.includes("native-uniwind");
+				const hasUnistyles = frontend.includes("native-unistyles");
 				const hasNativeForBA =
-					frontend.includes("native-bare") ||
-					frontend.includes("native-uniwind") ||
-					frontend.includes("native-unistyles");
+					hasNativeBare || hasNativeUniwind || hasUnistyles;

171-174: Consider using helper variables for consistency.

Similar to the comment on lines 54-57, consider extracting the native variant checks to helper variables for consistency with the pattern used elsewhere in the file.

+		const hasNativeBare = frontend.includes("native-bare");
+		const hasNativeUniwind = frontend.includes("native-uniwind");
+		const hasUnistyles = frontend.includes("native-unistyles");
+
 		if (
-			(frontend.includes("native-bare") ||
-				frontend.includes("native-uniwind") ||
-				frontend.includes("native-unistyles")) &&
+			(hasNativeBare || hasNativeUniwind || hasUnistyles) &&
 			nativeDirExists
 		) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b547ed and 9527d4c.

📒 Files selected for processing (5)
  • apps/cli/src/helpers/core/auth-setup.ts (4 hunks)
  • apps/cli/src/utils/compatibility-rules.ts (3 hunks)
  • apps/cli/test/api.test.ts (3 hunks)
  • apps/web/src/app/(home)/new/_components/utils.ts (6 hunks)
  • apps/web/src/lib/constant.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/cli/test/api.test.ts
  • apps/cli/src/utils/compatibility-rules.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

**/*.{ts,tsx}: Use Id from './_generated/dataModel' to type document ids (e.g., Id<'users'>)
Ensure Record key/value types align with validators (e.g., v.record(v.id('users'), v.string()) => Record<Id<'users'>, string>)
Be strict with types for document ids; prefer Id<'table'> over string
Use 'as const' for string literals in discriminated unions
When using Array and Record types, declare with explicit generic types (e.g., const arr: Array = ...)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations.
Do not use explicit return types in TypeScript.

Files:

  • apps/web/src/app/(home)/new/_components/utils.ts
  • apps/web/src/lib/constant.ts
  • apps/cli/src/helpers/core/auth-setup.ts
**/*.{js,jsx,ts,tsx,mjs,cjs}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{js,jsx,ts,tsx,mjs,cjs}: Do not use dotenv; Bun auto-loads .env
Use Bun.serve() for HTTP/WebSockets; do not use express
Use bun:sqlite for SQLite; do not use better-sqlite3
Use Bun.redis for Redis; do not use ioredis
Use Bun.sql for Postgres; do not use pg or postgres.js
Use built-in WebSocket; do not use ws
Prefer Bun.file over node:fs readFile/writeFile
Use Bun.$ instead of execa for shelling out

Files:

  • apps/web/src/app/(home)/new/_components/utils.ts
  • apps/web/src/lib/constant.ts
  • apps/cli/src/helpers/core/auth-setup.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions.

Files:

  • apps/web/src/app/(home)/new/_components/utils.ts
  • apps/web/src/lib/constant.ts
  • apps/cli/src/helpers/core/auth-setup.ts
🧠 Learnings (2)
📚 Learning: 2025-08-24T18:01:11.544Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-08-24T18:01:11.544Z
Learning: Applies to **/*.{js,jsx,ts,tsx,mjs,cjs} : Use `bun:sqlite` for SQLite; do not use `better-sqlite3`

Applied to files:

  • apps/web/src/lib/constant.ts
📚 Learning: 2025-08-24T18:01:11.544Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-08-24T18:01:11.544Z
Learning: Applies to {**/package.json,**/webpack.config.@(js|ts|mjs|cjs),**/esbuild.config.@(js|ts|mjs|cjs)} : Use `bun build <file>` instead of `webpack` or `esbuild`

Applied to files:

  • apps/web/src/lib/constant.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (9)
apps/cli/src/helpers/core/auth-setup.ts (1)

54-189: Migration to new native tokens completed successfully.

The migration from native-nativewind to the new native variants (native-bare, native-uniwind, native-unistyles) is complete and correct across all authentication flows. The logic properly:

  • Detects all three new native variants in both Convex and non-Convex backend paths
  • Adds appropriate dependencies for BetterAuth (@better-auth/expo) and Clerk (@clerk/clerk-expo) when native frontends are present
  • Maintains backward compatibility with native-unistyles which was already supported

The suggested refactors above are for code quality and maintainability, but the core logic is sound.

apps/web/src/app/(home)/new/_components/utils.ts (5)

107-109: LGTM!

The native frontend compatibility check for Clerk auth with Convex backend has been correctly updated to recognize the new native frontend options.


115-117: LGTM!

Better-Auth compatibility check correctly updated to include all three native frontend variants.


884-886: LGTM!

Auth compatibility checks and user-facing messages correctly updated to recognize and communicate the new native frontend options. The message clearly indicates the supported variants.

Also applies to: 908-934


1261-1267: LGTM!

The disabled reason check for Better-Auth with Convex correctly recognizes the new native frontend options and provides a clear user-facing message.


1347-1375: LGTM!

The final compatibility checks in getDisabledReason are correctly updated with the new native frontend options and provide clear, user-friendly error messages.

apps/web/src/lib/constant.ts (3)

108-144: LGTM!

The native frontend options have been properly restructured to offer three distinct styling approaches:

  • Bare (default): StyleSheet with no additional styling library
  • Uniwind: Tailwind CSS for React Native
  • Unistyles: Type-safe styling

The descriptions are clear and help users understand the differences between the options. The default flag is appropriately set for the bare option.


733-758: LGTM!

The "Mobile App" preset template correctly uses the new native-bare option as the default native frontend choice, which aligns with the architectural changes.


785-811: LGTM!

The "Full Featured" preset template is consistently updated to use native-bare, maintaining alignment with the other preset templates.

<Ionicons name="add-outline" size={24} color={themeColorForeground} />
</Pressable>
</Link>
),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Theme Toggle Vanishes on Tabs

The headerRight override for the tabs screen replaces the global renderThemeToggle from screenOptions, causing the theme toggle button to disappear on this screen while remaining visible on other screens. The tabs screen should render both the theme toggle and the modal button together, not just the modal button alone.

Fix in Cursor Fix in Web

@AmanVarshney01 AmanVarshney01 merged commit fc77367 into main Nov 9, 2025
3 of 4 checks passed
@AmanVarshney01 AmanVarshney01 deleted the expo-overhaul branch November 9, 2025 18:53
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/web/src/app/(home)/analytics/_components/stack-configuration-charts.tsx (1)

154-164: Color mappings updated correctly; consider refactoring for readability.

The color assignments for the new native frontend options (native-bare, native-uniwind) are consistent with the configuration in types.ts. However, the deeply nested ternary operators make this code harder to maintain.

Consider refactoring to a more maintainable approach:

 <Bar dataKey="value" radius={4}>
   {frontendData.map((entry) => (
     <Cell
       key={`frontend-${entry.name}`}
-      fill={
-        entry.name === "react-router"
-          ? "hsl(var(--chart-1))"
-          : entry.name === "tanstack-router"
-            ? "hsl(var(--chart-2))"
-            : entry.name === "tanstack-start"
-              ? "hsl(var(--chart-3))"
-              : entry.name === "next"
-                ? "hsl(var(--chart-4))"
-                : entry.name === "nuxt"
-                  ? "hsl(var(--chart-5))"
-                  : entry.name === "native-bare"
-                    ? "hsl(var(--chart-6))"
-                    : entry.name === "native-uniwind"
-                      ? "hsl(var(--chart-7))"
-                      : entry.name === "native-unistyles"
-                        ? "hsl(var(--chart-1))"
-                        : entry.name === "svelte"
-                          ? "hsl(var(--chart-3))"
-                          : entry.name === "solid"
-                            ? "hsl(var(--chart-4))"
-                            : "hsl(var(--chart-7))"
-      }
+      fill={frontendConfig[entry.name as keyof typeof frontendConfig]?.color ?? "hsl(var(--chart-7))"}
     />
   ))}
 </Bar>

This leverages the existing frontendConfig from types.ts and eliminates the nested ternary.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9527d4c and 22f93ed.

📒 Files selected for processing (5)
  • apps/cli/src/constants.ts (1 hunks)
  • apps/cli/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs (1 hunks)
  • apps/web/src/app/(home)/analytics/_components/stack-configuration-charts.tsx (1 hunks)
  • apps/web/src/app/(home)/analytics/_components/types.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/cli/templates/frontend/native/bare/components/header-button.tsx.hbs
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)

**/*.{ts,tsx}: Use Id from './_generated/dataModel' to type document ids (e.g., Id<'users'>)
Ensure Record key/value types align with validators (e.g., v.record(v.id('users'), v.string()) => Record<Id<'users'>, string>)
Be strict with types for document ids; prefer Id<'table'> over string
Use 'as const' for string literals in discriminated unions
When using Array and Record types, declare with explicit generic types (e.g., const arr: Array = ...)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations.
Do not use explicit return types in TypeScript.

Files:

  • apps/web/src/app/(home)/analytics/_components/types.ts
  • apps/cli/src/constants.ts
  • apps/web/src/app/(home)/analytics/_components/stack-configuration-charts.tsx
**/*.{js,jsx,ts,tsx,mjs,cjs}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{js,jsx,ts,tsx,mjs,cjs}: Do not use dotenv; Bun auto-loads .env
Use Bun.serve() for HTTP/WebSockets; do not use express
Use bun:sqlite for SQLite; do not use better-sqlite3
Use Bun.redis for Redis; do not use ioredis
Use Bun.sql for Postgres; do not use pg or postgres.js
Use built-in WebSocket; do not use ws
Prefer Bun.file over node:fs readFile/writeFile
Use Bun.$ instead of execa for shelling out

Files:

  • apps/web/src/app/(home)/analytics/_components/types.ts
  • apps/cli/src/constants.ts
  • apps/web/src/app/(home)/analytics/_components/stack-configuration-charts.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions.

Files:

  • apps/web/src/app/(home)/analytics/_components/types.ts
  • apps/cli/src/constants.ts
  • apps/web/src/app/(home)/analytics/_components/stack-configuration-charts.tsx
**/*.{hbs,handlebars}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

In Handlebars templates, avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle")).

Files:

  • apps/cli/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (9)
apps/cli/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs (7)

1-30: LGTM! Conditional imports follow explicit Handlebars patterns.

The import structure correctly branches on backend and API choices, using explicit eq checks as required by the coding guidelines.


37-67: LGTM! Convex integration is correct.

The async/await pattern for mutations and direct array access align with Convex's reactive query model.


69-143: LGTM! Non-Convex paths correctly use TanStack Query patterns.

The mutation callbacks with onSuccess refetch logic and .data access are appropriate for ORPC/TRPC with TanStack Query.


146-235: LGTM! Input UI correctly adapts to backend differences.

The conditional editable prop and loading indicators appropriately reflect each backend's mutation state exposure.


237-324: LGTM! Convex rendering paths correctly handle loading, empty, and list states.

The data access patterns (direct array, _id field) and conditional rendering align with Convex's reactive model.


326-412: LGTM! Non-Convex rendering correctly accesses todos?.data and uses numeric IDs.

The conditional rendering and data access patterns are appropriate for TanStack Query's result structure.


419-521: LGTM! StyleSheet definitions follow React Native conventions.

The styles are well-organized and use appropriate layout properties for the Todo list UI.

apps/web/src/app/(home)/analytics/_components/types.ts (1)

243-254: LGTM! Frontend config updated correctly.

The frontend configuration has been properly updated to replace native-nativewind with the new native-bare and native-uniwind options. The color assignments are consistent with the chart rendering logic in stack-configuration-charts.tsx, and the labels clearly distinguish between the different Expo variants.

apps/cli/src/constants.ts (1)

158-158: No issues found with alchemy version update.

The version bump from ^0.75.1 to ^0.77.0 includes only bug fixes and additive features (container bindings support and improved secret encryption) with no breaking changes. The codebase's usage of alchemy—through module imports, CLI commands, and framework integration—is compatible with v0.77.0, and no configuration updates are necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants