Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 88 additions & 88 deletions apps/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,90 +1,90 @@
{
"name": "create-better-t-stack",
"version": "2.44.0",
"description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
"type": "module",
"license": "MIT",
"author": "Aman Varshney",
"bin": {
"create-better-t-stack": "dist/cli.js"
},
"files": [
"templates",
"dist"
],
"keywords": [
"better-t-stack",
"typescript",
"boilerplate",
"starter",
"cli",
"turborepo",
"trpc",
"better-auth",
"monorepo",
"fullstack",
"type-safety",
"react",
"react-native",
"expo",
"hono",
"elysia",
"drizzle",
"prisma",
"tanstack",
"tailwind",
"shadcn",
"pwa",
"tauri",
"biome"
],
"repository": {
"type": "git",
"url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git",
"directory": "apps/cli"
},
"publishConfig": {
"access": "public"
},
"homepage": "https://better-t-stack.dev/",
"scripts": {
"build": "tsdown",
"dev": "tsdown --watch",
"check-types": "tsc --noEmit",
"check": "biome check --write .",
"test": "bun run build && vitest run",
"test:ui": "bun run build && vitest --ui",
"test:with-build": "bun run build && WITH_BUILD=1 vitest --ui",
"prepublishOnly": "npm run build"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"dependencies": {
"@biomejs/js-api": "^3.0.0",
"@biomejs/wasm-nodejs": "^2.2.4",
"@clack/prompts": "^1.0.0-alpha.4",
"consola": "^3.4.2",
"execa": "^9.6.0",
"fs-extra": "^11.3.1",
"gradient-string": "^3.0.0",
"handlebars": "^4.7.8",
"jsonc-parser": "^3.3.1",
"picocolors": "^1.1.1",
"tinyglobby": "^0.2.15",
"trpc-cli": "^0.10.2",
"ts-morph": "^27.0.0",
"zod": "^4.1.5"
},
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"@types/node": "^24.3.1",
"@vitest/ui": "^3.2.4",
"tsdown": "^0.14.2",
"typescript": "^5.9.2",
"vitest": "^3.2.4"
}
"name": "create-better-t-stack",
"version": "2.44.0",
"description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
"type": "module",
"license": "MIT",
"author": "Aman Varshney",
"bin": {
"create-better-t-stack": "dist/cli.js"
},
"files": [
"templates",
"dist"
],
"keywords": [
"better-t-stack",
"typescript",
"boilerplate",
"starter",
"cli",
"turborepo",
"trpc",
"better-auth",
"monorepo",
"fullstack",
"type-safety",
"react",
"react-native",
"expo",
"hono",
"elysia",
"drizzle",
"prisma",
"tanstack",
"tailwind",
"shadcn",
"pwa",
"tauri",
"biome"
],
"repository": {
"type": "git",
"url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git",
"directory": "apps/cli"
},
"publishConfig": {
"access": "public"
},
"homepage": "https://better-t-stack.dev/",
"scripts": {
"build": "tsdown",
"dev": "tsdown --watch",
"check-types": "tsc --noEmit",
"check": "biome check --write .",
"test": "bun run build && vitest run",
"test:ui": "bun run build && vitest --ui",
"test:with-build": "bun run build && WITH_BUILD=1 vitest --ui",
"prepublishOnly": "npm run build"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"dependencies": {
"@biomejs/js-api": "^3.0.0",
"@biomejs/wasm-nodejs": "^2.2.4",
"@clack/prompts": "^1.0.0-alpha.4",
"consola": "^3.4.2",
"execa": "^9.6.0",
"fs-extra": "^11.3.1",
"gradient-string": "^3.0.0",
"handlebars": "^4.7.8",
"jsonc-parser": "^3.3.1",
"picocolors": "^1.1.1",
"tinyglobby": "^0.2.15",
"trpc-cli": "^0.10.2",
"ts-morph": "^27.0.0",
"zod": "^4.1.5"
},
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"@types/node": "^24.3.1",
"@vitest/ui": "^3.2.4",
"tsdown": "^0.14.2",
"typescript": "^5.9.2",
"vitest": "^3.2.4"
}
}
2 changes: 1 addition & 1 deletion apps/cli/src/helpers/core/template-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ export async function handleExtras(projectDir: string, context: ProjectConfig) {
const pnpmWorkspaceSrc = path.join(extrasDir, "pnpm-workspace.yaml");
const pnpmWorkspaceDest = path.join(projectDir, "pnpm-workspace.yaml");
if (await fs.pathExists(pnpmWorkspaceSrc)) {
await fs.copy(pnpmWorkspaceSrc, pnpmWorkspaceDest);
await processTemplate(pnpmWorkspaceSrc, pnpmWorkspaceDest, context);
}
}

Expand Down
14 changes: 14 additions & 0 deletions apps/cli/src/utils/template-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ import handlebars from "handlebars";
import type { ProjectConfig } from "../types";
import { formatFileWithBiome } from "./biome-formatter";

const BINARY_EXTENSIONS = new Set([
".png", ".ico", ".svg",
]);

function isBinaryFile(filePath: string): boolean {
const ext = path.extname(filePath).toLowerCase();
return BINARY_EXTENSIONS.has(ext);
}

export async function processTemplate(
srcPath: string,
destPath: string,
Expand All @@ -13,6 +22,11 @@ export async function processTemplate(
try {
await fs.ensureDir(path.dirname(destPath));

if (isBinaryFile(srcPath) && !srcPath.endsWith(".hbs")) {
await fs.copy(srcPath, destPath);
return;
}

let content: string;

if (srcPath.endsWith(".hbs")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { createAuthClient } from "better-auth/react";
import { expoClient } from "@better-auth/expo/client";
import { createAuthClient } from "better-auth/react";
import * as SecureStore from "expo-secure-store";

export const authClient = createAuthClient({
baseURL: process.env.EXPO_PUBLIC_SERVER_URL,
plugins: [
expoClient({
storagePrefix: "my-better-t-app",
scheme: "mybettertapp",
storagePrefix: "{{projectName}}",
storage: SecureStore,
}),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const auth = betterAuth({
trustedOrigins: [
process.env.CORS_ORIGIN || "",
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
"my-better-t-app://",
"mybettertapp://", "exp://"
{{/if}}
],
emailAndPassword: {
Expand Down Expand Up @@ -55,7 +55,7 @@ export const auth = betterAuth({
trustedOrigins: [
process.env.CORS_ORIGIN || "",
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
"my-better-t-app://",
"mybettertapp://", "exp://"
{{/if}}
],
emailAndPassword: {
Expand Down Expand Up @@ -124,7 +124,7 @@ export const auth = betterAuth({
trustedOrigins: [
process.env.CORS_ORIGIN || "",
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
"my-better-t-app://",
"mybettertapp://", "exp://"
{{/if}}
],
emailAndPassword: {
Expand Down Expand Up @@ -154,7 +154,7 @@ export const auth = betterAuth({
trustedOrigins: [
process.env.CORS_ORIGIN || "",
{{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
"my-better-t-app://",
"mybettertapp://", "exp://"
{{/if}}
],
emailAndPassword: {
Expand All @@ -171,4 +171,4 @@ export const auth = betterAuth({
, plugins: [expo()]
{{/if}}
});
{{/if}}
{{/if}}
6 changes: 3 additions & 3 deletions apps/cli/templates/backend/server/next/package.json.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
},
"dependencies": {
"next": "15.5.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react": "19.1.0",
"react-dom": "19.1.0",
"dotenv": "^17.2.1"
},
{{#if (eq dbSetup 'supabase')}}
Expand All @@ -20,7 +20,7 @@
{{/if}}
"devDependencies": {
"@types/node": "^20",
"@types/react": "^19",
"@types/react": "~19.1.10",
"zod": "^4.0.13",
"typescript": "^5"
}
Expand Down
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
2 changes: 0 additions & 2 deletions apps/cli/templates/frontend/native/nativewind/app-env.d.ts

This file was deleted.

46 changes: 0 additions & 46 deletions apps/cli/templates/frontend/native/nativewind/app.json

This file was deleted.

49 changes: 49 additions & 0 deletions apps/cli/templates/frontend/native/nativewind/app.json.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"expo": {
"name": "{{projectName}}",
"slug": "{{projectName}}",
Comment on lines +3 to +4
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

Parameterize identifiers; add iOS bundle identifier; make slug URL‑safe.

Hardcoded scheme/package can collide across apps; slug may be invalid if projectName has spaces. Suggest deriving from a slug-safe helper and setting iOS bundle id.

   "expo": {
-    "name": "{{projectName}}",
-    "slug": "{{projectName}}",
+    "name": "{{projectName}}",
+    "slug": "{{kebabCase projectName}}", // or your slug helper/var
     ...
-    "scheme": "mybettertapp",
+    "scheme": "{{kebabCase projectName}}",
     "ios": {
-      "supportsTablet": true
+      "supportsTablet": true,
+      "bundleIdentifier": "com.anonymous.{{kebabCase projectName}}"
     },
     "android": {
       "adaptiveIcon": {
         ...
       },
       "edgeToEdgeEnabled": true,
       "predictiveBackGestureEnabled": false,
-      "package": "com.anonymous.mybettertapp"
+      "package": "com.anonymous.{{kebabCase projectName}}"
     },

Would you prefer a different org prefix than com.anonymous? I can wire this up to a CLI prompt.

Also applies to: 8-8, 12-13, 23-23

🤖 Prompt for AI Agents
In apps/cli/templates/frontend/native/nativewind/app.json.hbs around lines 3-4
(and also update occurrences at lines 8, 12-13, and 23), the template hardcodes
name/slug and iOS bundle/scheme which can collide or become invalid for project
names with spaces; replace these with parameterized, slug-safe helpers for the
slug and derive identifiers for android.package and ios.bundleIdentifier using a
configurable org prefix (e.g., com.<org>.<slug>) instead of com.anonymous,
ensure the slug is URL-safe (lowercase, hyphens, remove/replace invalid chars)
and use that slug when composing the bundle/package and scheme fields so all
identifiers are consistent and safe; wire the org prefix to a template parameter
(or CLI prompt) and update the template references accordingly.

"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "mybettertapp",
"userInterfaceStyle": "automatic",
"newArchEnabled": true,
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"backgroundColor": "#E6F4FE",
"foregroundImage": "./assets/images/android-icon-foreground.png",
"backgroundImage": "./assets/images/android-icon-background.png",
"monochromeImage": "./assets/images/android-icon-monochrome.png"
},
"edgeToEdgeEnabled": true,
"predictiveBackGestureEnabled": false,
"package": "com.anonymous.mybettertapp"
},
"web": {
"output": "static",
"favicon": "./assets/images/favicon.png"
},
"plugins": [
"expo-router",
[
"expo-splash-screen",
{
"image": "./assets/images/splash-icon.png",
"imageWidth": 200,
"resizeMode": "contain",
"backgroundColor": "#ffffff",
"dark": {
"backgroundColor": "#000000"
}
}
]
],
"experiments": {
"typedRoutes": true,
"reactCompiler": true
}
}
}
Loading