create-stackr 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +642 -0
  3. package/bin/cli.js +12 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +113 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/config/dependencies.d.ts +82 -0
  9. package/dist/config/dependencies.d.ts.map +1 -0
  10. package/dist/config/dependencies.js +82 -0
  11. package/dist/config/dependencies.js.map +1 -0
  12. package/dist/config/presets.d.ts +3 -0
  13. package/dist/config/presets.d.ts.map +1 -0
  14. package/dist/config/presets.js +174 -0
  15. package/dist/config/presets.js.map +1 -0
  16. package/dist/generators/index.d.ts +40 -0
  17. package/dist/generators/index.d.ts.map +1 -0
  18. package/dist/generators/index.js +130 -0
  19. package/dist/generators/index.js.map +1 -0
  20. package/dist/generators/onboarding.d.ts +8 -0
  21. package/dist/generators/onboarding.d.ts.map +1 -0
  22. package/dist/generators/onboarding.js +141 -0
  23. package/dist/generators/onboarding.js.map +1 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +65 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/prompts/features.d.ts +14 -0
  29. package/dist/prompts/features.d.ts.map +1 -0
  30. package/dist/prompts/features.js +96 -0
  31. package/dist/prompts/features.js.map +1 -0
  32. package/dist/prompts/index.d.ts +3 -0
  33. package/dist/prompts/index.d.ts.map +1 -0
  34. package/dist/prompts/index.js +93 -0
  35. package/dist/prompts/index.js.map +1 -0
  36. package/dist/prompts/onboarding.d.ts +6 -0
  37. package/dist/prompts/onboarding.d.ts.map +1 -0
  38. package/dist/prompts/onboarding.js +37 -0
  39. package/dist/prompts/onboarding.js.map +1 -0
  40. package/dist/prompts/orm.d.ts +3 -0
  41. package/dist/prompts/orm.d.ts.map +1 -0
  42. package/dist/prompts/orm.js +23 -0
  43. package/dist/prompts/orm.js.map +1 -0
  44. package/dist/prompts/packageManager.d.ts +2 -0
  45. package/dist/prompts/packageManager.d.ts.map +1 -0
  46. package/dist/prompts/packageManager.js +18 -0
  47. package/dist/prompts/packageManager.js.map +1 -0
  48. package/dist/prompts/platform.d.ts +3 -0
  49. package/dist/prompts/platform.d.ts.map +1 -0
  50. package/dist/prompts/platform.js +21 -0
  51. package/dist/prompts/platform.js.map +1 -0
  52. package/dist/prompts/preset.d.ts +4 -0
  53. package/dist/prompts/preset.d.ts.map +1 -0
  54. package/dist/prompts/preset.js +165 -0
  55. package/dist/prompts/preset.js.map +1 -0
  56. package/dist/prompts/project.d.ts +2 -0
  57. package/dist/prompts/project.d.ts.map +1 -0
  58. package/dist/prompts/project.js +27 -0
  59. package/dist/prompts/project.js.map +1 -0
  60. package/dist/prompts/sdks.d.ts +2 -0
  61. package/dist/prompts/sdks.d.ts.map +1 -0
  62. package/dist/prompts/sdks.js +46 -0
  63. package/dist/prompts/sdks.js.map +1 -0
  64. package/dist/types/index.d.ts +77 -0
  65. package/dist/types/index.d.ts.map +1 -0
  66. package/dist/types/index.js +25 -0
  67. package/dist/types/index.js.map +1 -0
  68. package/dist/utils/cleanup.d.ts +5 -0
  69. package/dist/utils/cleanup.d.ts.map +1 -0
  70. package/dist/utils/cleanup.js +38 -0
  71. package/dist/utils/cleanup.js.map +1 -0
  72. package/dist/utils/copy.d.ts +10 -0
  73. package/dist/utils/copy.d.ts.map +1 -0
  74. package/dist/utils/copy.js +53 -0
  75. package/dist/utils/copy.js.map +1 -0
  76. package/dist/utils/errors.d.ts +33 -0
  77. package/dist/utils/errors.d.ts.map +1 -0
  78. package/dist/utils/errors.js +136 -0
  79. package/dist/utils/errors.js.map +1 -0
  80. package/dist/utils/git.d.ts +5 -0
  81. package/dist/utils/git.d.ts.map +1 -0
  82. package/dist/utils/git.js +33 -0
  83. package/dist/utils/git.js.map +1 -0
  84. package/dist/utils/logger.d.ts +9 -0
  85. package/dist/utils/logger.d.ts.map +1 -0
  86. package/dist/utils/logger.js +22 -0
  87. package/dist/utils/logger.js.map +1 -0
  88. package/dist/utils/package.d.ts +16 -0
  89. package/dist/utils/package.d.ts.map +1 -0
  90. package/dist/utils/package.js +86 -0
  91. package/dist/utils/package.js.map +1 -0
  92. package/dist/utils/system-validation.d.ts +9 -0
  93. package/dist/utils/system-validation.d.ts.map +1 -0
  94. package/dist/utils/system-validation.js +31 -0
  95. package/dist/utils/system-validation.js.map +1 -0
  96. package/dist/utils/template.d.ts +20 -0
  97. package/dist/utils/template.d.ts.map +1 -0
  98. package/dist/utils/template.js +234 -0
  99. package/dist/utils/template.js.map +1 -0
  100. package/dist/utils/validation.d.ts +8 -0
  101. package/dist/utils/validation.d.ts.map +1 -0
  102. package/dist/utils/validation.js +94 -0
  103. package/dist/utils/validation.js.map +1 -0
  104. package/package.json +96 -0
  105. package/templates/base/backend/.dockerignore.ejs +62 -0
  106. package/templates/base/backend/.env.example.ejs +116 -0
  107. package/templates/base/backend/Dockerfile.ejs +142 -0
  108. package/templates/base/backend/controllers/event-queue/index.ts +20 -0
  109. package/templates/base/backend/controllers/event-queue/workers/user.ts +39 -0
  110. package/templates/base/backend/controllers/rest-api/index.ts +48 -0
  111. package/templates/base/backend/controllers/rest-api/plugins/auth.ts +152 -0
  112. package/templates/base/backend/controllers/rest-api/plugins/config.ts +64 -0
  113. package/templates/base/backend/controllers/rest-api/plugins/error-handler.ts +118 -0
  114. package/templates/base/backend/controllers/rest-api/routes/auth.ts.ejs +180 -0
  115. package/templates/base/backend/controllers/rest-api/routes/device-sessions.ts +197 -0
  116. package/templates/base/backend/controllers/rest-api/routes/oauth-web.ts.ejs +375 -0
  117. package/templates/base/backend/controllers/rest-api/server.ts.ejs +87 -0
  118. package/templates/base/backend/domain/device-session/repository.drizzle.ts +209 -0
  119. package/templates/base/backend/domain/device-session/repository.prisma.ts +248 -0
  120. package/templates/base/backend/domain/device-session/schema.ts +72 -0
  121. package/templates/base/backend/domain/session/repository.drizzle.ts +72 -0
  122. package/templates/base/backend/domain/session/repository.prisma.ts +72 -0
  123. package/templates/base/backend/domain/session/schema.ts +29 -0
  124. package/templates/base/backend/domain/user/repository.drizzle.ts +127 -0
  125. package/templates/base/backend/domain/user/repository.prisma.ts +115 -0
  126. package/templates/base/backend/domain/user/schema.ts +14 -0
  127. package/templates/base/backend/drizzle/schema.drizzle.ts +111 -0
  128. package/templates/base/backend/drizzle.config.drizzle.ts +13 -0
  129. package/templates/base/backend/lib/auth.drizzle.ts.ejs +104 -0
  130. package/templates/base/backend/lib/auth.prisma.ts.ejs +97 -0
  131. package/templates/base/backend/lib/constants.ts.ejs +29 -0
  132. package/templates/base/backend/package.json.ejs +50 -0
  133. package/templates/base/backend/prisma/schema.prisma.ejs +102 -0
  134. package/templates/base/backend/prisma.config.prisma.ts +12 -0
  135. package/templates/base/backend/tsconfig.json +39 -0
  136. package/templates/base/backend/utils/db.drizzle.ts +41 -0
  137. package/templates/base/backend/utils/db.prisma.ts +51 -0
  138. package/templates/base/backend/utils/email.ts.ejs +35 -0
  139. package/templates/base/backend/utils/errors.ts +348 -0
  140. package/templates/base/backend/utils/redis.ts.ejs +279 -0
  141. package/templates/base/mobile/.env.example.ejs +35 -0
  142. package/templates/base/mobile/.gitignore.ejs +167 -0
  143. package/templates/base/mobile/app/+not-found.tsx +85 -0
  144. package/templates/base/mobile/app/_layout.tsx.ejs +71 -0
  145. package/templates/base/mobile/app.json.ejs +88 -0
  146. package/templates/base/mobile/assets/images/adaptive-icon.png +0 -0
  147. package/templates/base/mobile/assets/images/favicon.png +0 -0
  148. package/templates/base/mobile/assets/images/icon.png +0 -0
  149. package/templates/base/mobile/assets/images/onboarding_page_1.png +0 -0
  150. package/templates/base/mobile/assets/images/onboarding_page_2.png +0 -0
  151. package/templates/base/mobile/assets/images/onboarding_page_3.png +0 -0
  152. package/templates/base/mobile/assets/images/paywall_image.png +0 -0
  153. package/templates/base/mobile/assets/images/splash.png +0 -0
  154. package/templates/base/mobile/eas.json.ejs +49 -0
  155. package/templates/base/mobile/metro.config.js +9 -0
  156. package/templates/base/mobile/package.json.ejs +53 -0
  157. package/templates/base/mobile/src/components/ui/Button.tsx +131 -0
  158. package/templates/base/mobile/src/components/ui/Card.tsx +68 -0
  159. package/templates/base/mobile/src/components/ui/IconSymbol.tsx +90 -0
  160. package/templates/base/mobile/src/components/ui/Input.tsx +142 -0
  161. package/templates/base/mobile/src/components/ui/LoadingSpinner.tsx +98 -0
  162. package/templates/base/mobile/src/components/ui/OnboardingLayout.tsx +356 -0
  163. package/templates/base/mobile/src/components/ui/PaywallLayout.tsx +311 -0
  164. package/templates/base/mobile/src/components/ui/Skeleton.tsx +58 -0
  165. package/templates/base/mobile/src/components/ui/index.ts +6 -0
  166. package/templates/base/mobile/src/constants/Theme.ts +163 -0
  167. package/templates/base/mobile/src/context/ThemeContext.tsx +157 -0
  168. package/templates/base/mobile/src/lib/auth-client.ts.ejs +51 -0
  169. package/templates/base/mobile/src/services/api.ts.ejs +71 -0
  170. package/templates/base/mobile/src/services/errorService.ts +179 -0
  171. package/templates/base/mobile/src/services/sdkInitializer.ts.ejs +36 -0
  172. package/templates/base/mobile/src/store/index.ts.ejs +18 -0
  173. package/templates/base/mobile/src/store/ui.store.ts +100 -0
  174. package/templates/base/mobile/src/utils/formatters.ts +105 -0
  175. package/templates/base/mobile/src/utils/logger.ts +73 -0
  176. package/templates/base/mobile/src/utils/responsive.ts +234 -0
  177. package/templates/base/mobile/tsconfig.json +32 -0
  178. package/templates/base/web/.env.example.ejs +26 -0
  179. package/templates/base/web/components.json +22 -0
  180. package/templates/base/web/eslint.config.mjs +18 -0
  181. package/templates/base/web/next.config.ts +7 -0
  182. package/templates/base/web/package.json.ejs +35 -0
  183. package/templates/base/web/postcss.config.mjs +7 -0
  184. package/templates/base/web/public/.gitkeep +0 -0
  185. package/templates/base/web/public/file.svg +1 -0
  186. package/templates/base/web/public/globe.svg +1 -0
  187. package/templates/base/web/public/next.svg +1 -0
  188. package/templates/base/web/public/vercel.svg +1 -0
  189. package/templates/base/web/public/window.svg +1 -0
  190. package/templates/base/web/src/app/favicon.ico +0 -0
  191. package/templates/base/web/src/app/globals.css +152 -0
  192. package/templates/base/web/src/app/layout.tsx.ejs +54 -0
  193. package/templates/base/web/src/app/page.tsx.ejs +92 -0
  194. package/templates/base/web/src/components/auth/auth-hydrator.tsx.ejs +19 -0
  195. package/templates/base/web/src/components/auth/protected-route.tsx.ejs +109 -0
  196. package/templates/base/web/src/components/providers/device-session-setup.tsx.ejs +56 -0
  197. package/templates/base/web/src/components/providers/theme-provider.tsx +17 -0
  198. package/templates/base/web/src/components/theme-toggle.tsx +34 -0
  199. package/templates/base/web/src/components/ui/button.tsx +62 -0
  200. package/templates/base/web/src/components/ui/card.tsx +92 -0
  201. package/templates/base/web/src/components/ui/input.tsx +21 -0
  202. package/templates/base/web/src/components/ui/label.tsx +24 -0
  203. package/templates/base/web/src/components/ui/skeleton.tsx +13 -0
  204. package/templates/base/web/src/components/ui/spinner.tsx +20 -0
  205. package/templates/base/web/src/hooks/use-device-session.ts.ejs +40 -0
  206. package/templates/base/web/src/hooks/use-session.ts.ejs +56 -0
  207. package/templates/base/web/src/lib/auth/actions.ts.ejs +334 -0
  208. package/templates/base/web/src/lib/auth/config.ts.ejs +65 -0
  209. package/templates/base/web/src/lib/auth/cookies.ts.ejs +74 -0
  210. package/templates/base/web/src/lib/auth/index.ts.ejs +40 -0
  211. package/templates/base/web/src/lib/auth/oauth.ts.ejs +72 -0
  212. package/templates/base/web/src/lib/auth/pkce.ts.ejs +48 -0
  213. package/templates/base/web/src/lib/auth/sessions.ts.ejs +135 -0
  214. package/templates/base/web/src/lib/auth/user-agent.ts.ejs +47 -0
  215. package/templates/base/web/src/lib/device/actions.ts.ejs +148 -0
  216. package/templates/base/web/src/lib/device/id.ts.ejs +74 -0
  217. package/templates/base/web/src/lib/utils.ts +6 -0
  218. package/templates/base/web/src/proxy.ts.ejs +66 -0
  219. package/templates/base/web/src/store/auth.store.ts.ejs +89 -0
  220. package/templates/base/web/src/store/deviceSession.store.ts.ejs +141 -0
  221. package/templates/base/web/tsconfig.json +34 -0
  222. package/templates/features/mobile/auth/app/(auth)/_layout.tsx +16 -0
  223. package/templates/features/mobile/auth/app/(auth)/login.tsx +86 -0
  224. package/templates/features/mobile/auth/app/(auth)/register.tsx +86 -0
  225. package/templates/features/mobile/auth/components/auth/LoginForm.tsx.ejs +349 -0
  226. package/templates/features/mobile/auth/components/auth/RegisterForm.tsx.ejs +407 -0
  227. package/templates/features/mobile/auth/components/auth/index.ts +2 -0
  228. package/templates/features/mobile/auth/hooks/index.ts.ejs +1 -0
  229. package/templates/features/mobile/auth/hooks/useAuth.ts.ejs +367 -0
  230. package/templates/features/mobile/auth/services/deviceSession.ts +370 -0
  231. package/templates/features/mobile/auth/store/deviceSession.store.ts +326 -0
  232. package/templates/features/mobile/onboarding/app/(onboarding)/_layout.tsx.ejs +11 -0
  233. package/templates/features/mobile/onboarding/app/(onboarding)/page-1.tsx.ejs +52 -0
  234. package/templates/features/mobile/onboarding/app/(onboarding)/page-2.tsx.ejs +52 -0
  235. package/templates/features/mobile/onboarding/app/(onboarding)/page-3.tsx.ejs +60 -0
  236. package/templates/features/mobile/paywall/app/paywall.tsx +550 -0
  237. package/templates/features/mobile/tabs/app/(tabs)/_layout.tsx +26 -0
  238. package/templates/features/mobile/tabs/app/(tabs)/index.tsx +565 -0
  239. package/templates/features/web/.gitkeep +0 -0
  240. package/templates/features/web/auth/app/(app)/dashboard/dashboard-client.tsx.ejs +166 -0
  241. package/templates/features/web/auth/app/(app)/dashboard/page.tsx.ejs +24 -0
  242. package/templates/features/web/auth/app/(app)/layout.tsx.ejs +43 -0
  243. package/templates/features/web/auth/app/(app)/settings/sessions/page.tsx.ejs +29 -0
  244. package/templates/features/web/auth/app/(app)/settings/sessions/sessions-client.tsx.ejs +77 -0
  245. package/templates/features/web/auth/app/(auth)/forgot-password/page.tsx.ejs +127 -0
  246. package/templates/features/web/auth/app/(auth)/layout.tsx.ejs +32 -0
  247. package/templates/features/web/auth/app/(auth)/login/page.tsx.ejs +35 -0
  248. package/templates/features/web/auth/app/(auth)/register/page.tsx.ejs +19 -0
  249. package/templates/features/web/auth/app/(auth)/reset-password/page.tsx.ejs +40 -0
  250. package/templates/features/web/auth/app/(auth)/verify-email/page.tsx.ejs +198 -0
  251. package/templates/features/web/auth/app/auth/callback/route.ts.ejs +152 -0
  252. package/templates/features/web/auth/components/auth/login-form.tsx.ejs +100 -0
  253. package/templates/features/web/auth/components/auth/oauth-buttons.tsx.ejs +126 -0
  254. package/templates/features/web/auth/components/auth/password-reset-form.tsx.ejs +103 -0
  255. package/templates/features/web/auth/components/auth/register-form.tsx.ejs +139 -0
  256. package/templates/features/web/auth/components/settings/session-card.tsx.ejs +132 -0
  257. package/templates/integrations/mobile/adjust/services/adjustService.ts.ejs +163 -0
  258. package/templates/integrations/mobile/adjust/store/adjust.store.ts +243 -0
  259. package/templates/integrations/mobile/att/services/attService.ts +84 -0
  260. package/templates/integrations/mobile/att/services/trackingPermissions.ts +208 -0
  261. package/templates/integrations/mobile/att/store/att.store.ts +162 -0
  262. package/templates/integrations/mobile/revenuecat/services/revenuecatService.ts.ejs +174 -0
  263. package/templates/integrations/mobile/revenuecat/store/revenuecat.store.ts +286 -0
  264. package/templates/integrations/mobile/scate/services/scateService.ts.ejs +85 -0
  265. package/templates/integrations/mobile/scate/store/scate.store.ts +125 -0
  266. package/templates/integrations/web/.gitkeep +0 -0
  267. package/templates/shared/.env.example.ejs +21 -0
  268. package/templates/shared/.gitignore.ejs +145 -0
  269. package/templates/shared/README.md.ejs +134 -0
  270. package/templates/shared/docker-compose.prod.yml.ejs +120 -0
  271. package/templates/shared/docker-compose.yml.ejs +129 -0
  272. package/templates/shared/scripts/docker-dev.sh.ejs +395 -0
  273. package/templates/shared/scripts/docker-prod.sh.ejs +542 -0
  274. package/templates/shared/scripts/setup.sh.ejs +979 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 itharea
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,642 @@
1
+ # create-stackr
2
+
3
+ [![npm version](https://badge.fury.io/js/create-stackr.svg)](https://www.npmjs.com/package/create-stackr)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Node.js Version](https://img.shields.io/node/v/create-stackr)](https://nodejs.org)
6
+
7
+ > **v0.2.0**: Now with OAuth, Drizzle ORM support, and Next.js for web. Feedback welcome!
8
+
9
+ Create production-ready fullstack apps with Expo (mobile), Next.js (web), and Node.js backend in minutes.
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # npm
15
+ npx create-stackr@latest my-app
16
+
17
+ # yarn
18
+ yarn create stackr my-app
19
+
20
+ # bun
21
+ bunx create-stackr my-app
22
+ ```
23
+
24
+ ## Features
25
+
26
+ - **React Native (Expo)** - Cross-platform mobile development (iOS & Android)
27
+ - **Next.js Web App** - Modern React web application with App Router
28
+ - **Node.js Backend** - Fastify + PostgreSQL + Redis
29
+ - **ORM Flexibility** - Choose between Prisma (default) or Drizzle ORM
30
+ - **BetterAuth Authentication** - Email/password + OAuth providers (Google, Apple, GitHub)
31
+ - **Native OAuth SDKs** - Seamless sign-in with native SDKs and browser fallback
32
+ - **SDK Integrations** - RevenueCat, Adjust, Scate
33
+ - **Onboarding Flows** - Customizable multi-page user onboarding
34
+ - **Subscription Paywalls** - RevenueCat integration for in-app purchases
35
+ - **Docker Support** - Complete development environment with Docker Compose
36
+ - **Analytics** - Adjust attribution and Scate engagement tracking
37
+ - **ATT Support** - App Tracking Transparency for iOS
38
+ - **Two-Factor Auth** - Optional TOTP-based 2FA support
39
+ - **Email Verification** - Built-in email verification and password reset
40
+
41
+ ## Requirements
42
+
43
+ - **Node.js**: >= 18.0.0
44
+ - **npm**: >= 8.0.0 (or yarn/bun equivalent)
45
+ - **Git**: For repository initialization
46
+ - **Docker**: For backend development (optional but recommended)
47
+
48
+ ## Available Presets
49
+
50
+ ### Minimal
51
+ Basic fullstack app with essential features:
52
+ - Email/Password Authentication (BetterAuth)
53
+ - Session Management
54
+ - Tab Navigation
55
+ - PostgreSQL Database (Prisma or Drizzle)
56
+ - Docker Support
57
+
58
+ ### Full-Featured
59
+ All integrations and features included:
60
+ - 3-page Onboarding Flow
61
+ - Full Authentication (Email + Google + Apple OAuth)
62
+ - Email Verification & Password Reset
63
+ - Subscription Paywall
64
+ - Session Management
65
+ - Tab Navigation
66
+ - RevenueCat Integration
67
+ - Adjust Integration
68
+ - Scate Integration
69
+ - ATT (App Tracking Transparency)
70
+ - PostgreSQL (Prisma or Drizzle) + BullMQ Event Queue
71
+ - Docker Support
72
+
73
+ ### Analytics-Focused
74
+ Analytics SDKs with basic features:
75
+ - 2-page Onboarding Flow
76
+ - Email/Password Authentication
77
+ - Session Management
78
+ - Tab Navigation
79
+ - Adjust Integration
80
+ - Scate Integration
81
+ - ATT (App Tracking Transparency)
82
+ - PostgreSQL (Prisma or Drizzle) + BullMQ Event Queue
83
+ - Docker Support
84
+
85
+ ## CLI Usage
86
+
87
+ ```bash
88
+ # Interactive mode
89
+ npx create-stackr my-app
90
+
91
+ # With preset template
92
+ npx create-stackr my-app --template minimal
93
+ npx create-stackr my-app --template full-featured
94
+ npx create-stackr my-app --template analytics-focused
95
+
96
+ # With defaults (minimal preset, no prompts)
97
+ npx create-stackr my-app --defaults
98
+
99
+ # Show help
100
+ npx create-stackr --help
101
+
102
+ # Verbose output
103
+ npx create-stackr my-app --verbose
104
+ ```
105
+
106
+ ## What You Get
107
+
108
+ ### Mobile App (Expo)
109
+ - React Native with Expo Router
110
+ - TypeScript with strict mode
111
+ - Zustand state management
112
+ - File-based routing
113
+ - Native OAuth SDKs (Google, Apple)
114
+ - Ready for EAS Build
115
+
116
+ ### Web App (Next.js)
117
+ - Next.js 14+ with App Router
118
+ - TypeScript with strict mode
119
+ - Shared authentication with mobile
120
+ - Tailwind CSS styling
121
+
122
+ ### Backend
123
+ - Fastify REST API
124
+ - PostgreSQL with Prisma OR Drizzle ORM
125
+ - BetterAuth authentication
126
+ - OAuth providers (Google, Apple, GitHub)
127
+ - Docker development environment
128
+ - Optional BullMQ event queue
129
+
130
+ ### Optional Integrations
131
+ - RevenueCat (subscriptions)
132
+ - Adjust (attribution)
133
+ - Scate (engagement)
134
+ - ATT (iOS tracking transparency)
135
+
136
+ ## Generated Project Structure
137
+
138
+ ```
139
+ my-app/
140
+ ├── mobile/ # React Native (Expo) app
141
+ │ ├── app/ # Expo Router screens
142
+ │ ├── src/ # Components, services, utils
143
+ │ └── assets/ # Images, fonts
144
+ ├── web/ # Next.js web app
145
+ │ ├── app/ # App Router pages
146
+ │ └── src/ # Components, services
147
+ ├── backend/ # Node.js backend
148
+ │ ├── controllers/ # API routes
149
+ │ ├── domain/ # Business logic
150
+ │ ├── prisma/ # Prisma schema (if selected)
151
+ │ └── drizzle/ # Drizzle schema (if selected)
152
+ ├── docker-compose.yml # Local development
153
+ └── scripts/ # Setup utilities
154
+ ```
155
+
156
+ ## Generated Project Setup
157
+
158
+ After generating your project:
159
+
160
+ ### Backend Setup (Required First)
161
+
162
+ ```bash
163
+ # Start services (PostgreSQL, Redis)
164
+ docker-compose up -d
165
+
166
+ # Install dependencies and setup database
167
+ cd backend
168
+ bun install
169
+ bun run db:migrate
170
+ bun run db:generate
171
+ bun start # or bun run dev for watch mode
172
+ ```
173
+
174
+ The backend runs on `http://localhost:8080`.
175
+
176
+ ### Mobile App Setup
177
+
178
+ ```bash
179
+ cd mobile
180
+ bun install
181
+ bun start
182
+ ```
183
+
184
+ Press `i` for iOS simulator or `a` for Android emulator.
185
+
186
+ ### Web App Setup
187
+
188
+ ```bash
189
+ cd web
190
+ bun install
191
+ bun run dev
192
+ ```
193
+
194
+ Open `http://localhost:3000` in your browser.
195
+
196
+ ### Verifying Everything Works
197
+
198
+ 1. **Backend health**: `curl http://localhost:8080/health`
199
+ 2. **Database connection**: Check backend logs for "Database connected"
200
+ 3. **Web app**: Visit `http://localhost:3000` - should show home page
201
+ 4. **Mobile app**: Should load without red error screen
202
+ 5. **Auth flow**: Register a test user on web, verify in database
203
+
204
+ ### Common Setup Issues
205
+
206
+ | Issue | Solution |
207
+ |-------|----------|
208
+ | "Port 8080 in use" | Stop other services or change `PORT` in backend `.env` |
209
+ | "Database connection refused" | Ensure Docker containers are running: `docker ps` |
210
+ | "Module not found" | Delete `node_modules` and reinstall with `bun install` |
211
+ | "CORS error" | Check `CORS_ORIGINS` includes your frontend URL |
212
+ | "Apple Sign In fails" | Apple requires HTTPS - use ngrok or test in production |
213
+
214
+ ### Database Commands (ORM-agnostic)
215
+ Both Prisma and Drizzle use the same npm scripts:
216
+ ```bash
217
+ npm run db:generate # Generate ORM types
218
+ npm run db:push # Push schema changes
219
+ npm run db:migrate # Run migrations
220
+ npm run db:studio # Open visual database browser
221
+ ```
222
+
223
+ ## Web Platform Details
224
+
225
+ ### Project Structure
226
+
227
+ ```
228
+ web/
229
+ ├── src/
230
+ │ ├── app/ # Next.js App Router
231
+ │ │ ├── (auth)/ # Auth pages (login, register, etc.)
232
+ │ │ ├── (app)/ # Protected app pages (dashboard, settings)
233
+ │ │ ├── auth/ # OAuth callback routes
234
+ │ │ ├── globals.css # Global styles with dark mode
235
+ │ │ └── layout.tsx # Root layout with providers
236
+ │ ├── components/
237
+ │ │ ├── ui/ # shadcn/ui components
238
+ │ │ ├── auth/ # Auth forms and buttons
239
+ │ │ ├── settings/ # Settings components
240
+ │ │ └── providers/ # Context providers
241
+ │ ├── lib/
242
+ │ │ ├── auth/ # Auth utilities and actions
243
+ │ │ └── utils.ts # Utility functions
244
+ │ └── store/ # Zustand stores
245
+ ├── public/ # Static assets
246
+ ├── next.config.ts # Next.js configuration
247
+ └── package.json
248
+ ```
249
+
250
+ ### Environment Variables
251
+
252
+ Create a `.env` file in the `web/` directory:
253
+
254
+ ```env
255
+ # Public URL of the web app (used for OAuth callbacks)
256
+ NEXT_PUBLIC_APP_URL=http://localhost:3000
257
+
258
+ # Backend API URL (server-side only, used by server actions)
259
+ BACKEND_URL=http://localhost:8080
260
+ ```
261
+
262
+ ### Running the Web App
263
+
264
+ ```bash
265
+ cd web
266
+ bun install
267
+ bun run dev
268
+ ```
269
+
270
+ The app runs on `http://localhost:3000` by default.
271
+
272
+ ### Authentication on Web
273
+
274
+ The web platform uses **cookie-based sessions** (unlike mobile which uses token storage):
275
+
276
+ | Feature | Mobile | Web |
277
+ |---------|--------|-----|
278
+ | Session Storage | AsyncStorage + Secure Store | HTTP-only Cookies |
279
+ | Token Refresh | Manual refresh | Automatic via cookies |
280
+ | OAuth Flow | Deep links + native SDKs | Browser redirects |
281
+ | CSRF Protection | Not needed | Built into Better Auth |
282
+
283
+ ### OAuth Configuration
284
+
285
+ For OAuth to work on web, ensure your OAuth providers have the correct redirect URIs pointing to the **backend** (Better Auth handles the OAuth callback):
286
+
287
+ **Google Cloud Console:**
288
+ ```
289
+ http://localhost:8080/api/auth/callback/google (development)
290
+ https://api.yourdomain.com/auth/callback/google (production)
291
+ ```
292
+
293
+ **Apple Developer Console:**
294
+
295
+ > **Important:** Apple Sign In requires HTTPS for redirect URIs. It will not work with `http://localhost` in development. You must either:
296
+ > - Use a tunneling service (ngrok, Cloudflare Tunnel) to get an HTTPS URL for the backend
297
+ > - Test Apple Sign In only in production/staging environments with valid HTTPS
298
+ > - Use the mobile app for Apple Sign In testing during development
299
+
300
+ ```
301
+ https://api.yourdomain.com/auth/callback/apple (production only - HTTPS required)
302
+ ```
303
+
304
+ **GitHub OAuth App:**
305
+ ```
306
+ http://localhost:8080/api/auth/callback/github (development)
307
+ https://api.yourdomain.com/auth/callback/github (production)
308
+ ```
309
+
310
+ ### CORS Configuration
311
+
312
+ The backend must allow web origins. In `backend/.env`:
313
+
314
+ ```env
315
+ # Comma-separated list of allowed origins
316
+ CORS_ORIGINS=http://localhost:3000,https://yourdomain.com
317
+ ```
318
+
319
+ ### Dark Mode
320
+
321
+ The web app includes full dark mode support:
322
+
323
+ - Uses `next-themes` for theme management
324
+ - Theme persists in localStorage
325
+ - Respects system preference by default
326
+ - Toggle via the `ThemeToggle` component
327
+
328
+ ### Deploying Web
329
+
330
+ Deploy to any Next.js hosting:
331
+
332
+ - **Vercel** (recommended): `vercel deploy`
333
+ - **Netlify**: Add `netlify.toml` configuration
334
+ - **Docker**: Use the provided Dockerfile
335
+ - **Node.js hosting**: Run `bun run build && bun start`
336
+
337
+ Remember to update environment variables for production:
338
+
339
+ ```env
340
+ NEXT_PUBLIC_APP_URL=https://yourdomain.com
341
+ BACKEND_URL=https://api.yourdomain.com
342
+ ```
343
+
344
+ ## Deployment
345
+
346
+ ### Mobile App
347
+ Use EAS Build for deployment:
348
+
349
+ ```bash
350
+ cd mobile
351
+ npm install -g eas-cli
352
+ eas build --platform ios
353
+ eas build --platform android
354
+ ```
355
+
356
+ ### Backend
357
+ Deploy to any Node.js hosting:
358
+ - Heroku
359
+ - Railway
360
+ - Render
361
+ - AWS/GCP/Azure
362
+ - Your own VPS
363
+
364
+ Configure environment variables from `.env.example`.
365
+
366
+ ## Development
367
+
368
+ ```bash
369
+ # Install dependencies
370
+ npm install
371
+
372
+ # Build
373
+ npm run build
374
+
375
+ # Run tests
376
+ npm test
377
+
378
+ # Test with coverage
379
+ npm run test:coverage
380
+
381
+ # Run unit tests
382
+ npm run test:unit
383
+
384
+ # Run integration tests
385
+ npm run test:integration
386
+
387
+ # Run e2e tests
388
+ npm run test:e2e
389
+
390
+ # Lint code
391
+ npm run lint
392
+
393
+ # Format code
394
+ npm run format
395
+
396
+ # Type checking
397
+ npm run typecheck
398
+ ```
399
+
400
+ ## Troubleshooting
401
+
402
+ ### "Command not found: create-stackr"
403
+
404
+ Make sure npx is working:
405
+ ```bash
406
+ npx --version
407
+ ```
408
+
409
+ Try with explicit version:
410
+ ```bash
411
+ npx create-stackr@latest my-app
412
+ ```
413
+
414
+ ### "EACCES: permission denied"
415
+
416
+ Don't use sudo with npx. If you get permission errors:
417
+ ```bash
418
+ mkdir ~/.npm-global
419
+ npm config set prefix '~/.npm-global'
420
+ export PATH=~/.npm-global/bin:$PATH
421
+ ```
422
+
423
+ ### Generated project TypeScript errors
424
+
425
+ Make sure you're using Node.js >= 18:
426
+ ```bash
427
+ node --version
428
+ ```
429
+
430
+ ### Docker issues
431
+
432
+ Ensure Docker is running:
433
+ ```bash
434
+ docker --version
435
+ docker ps
436
+ ```
437
+
438
+ ### Web: Hydration mismatch errors
439
+
440
+ If you see "Hydration failed because the initial UI does not match" errors:
441
+
442
+ 1. **Theme-related**: Ensure `suppressHydrationWarning` is on the `<html>` tag in `layout.tsx`
443
+ 2. **Auth state**: The `AuthHydrator` component handles this - don't access auth state in server components
444
+ 3. **Date/time rendering**: Use `useEffect` for time-sensitive content
445
+
446
+ ```tsx
447
+ // Bad - causes hydration mismatch
448
+ const date = new Date().toLocaleDateString();
449
+
450
+ // Good - renders client-side only
451
+ const [date, setDate] = useState<string>();
452
+ useEffect(() => {
453
+ setDate(new Date().toLocaleDateString());
454
+ }, []);
455
+ ```
456
+
457
+ ### Web: OAuth callback fails
458
+
459
+ 1. **Check redirect URI**: Must exactly match what's configured in OAuth provider
460
+ 2. **Check CORS**: Backend must allow your web origin
461
+ 3. **Check cookies**: Ensure you're not blocking third-party cookies in development
462
+ 4. **Apple Sign In**: Remember that Apple requires HTTPS - won't work on localhost
463
+
464
+ Debug with:
465
+ ```bash
466
+ # Check backend logs
467
+ docker logs backend-container
468
+
469
+ # Verify CORS headers
470
+ curl -I http://localhost:8080/api/auth/session
471
+ ```
472
+
473
+ ### Web: Apple Sign In not working in development
474
+
475
+ Apple Sign In requires HTTPS redirect URIs and will not work with `http://localhost`. Options:
476
+
477
+ 1. **Use ngrok or Cloudflare Tunnel**: Create an HTTPS tunnel to your backend
478
+ ```bash
479
+ ngrok http 8080
480
+ # Use the https://xxx.ngrok.io/api/auth/callback/apple URL as your redirect URI
481
+ ```
482
+ 2. **Skip Apple in dev**: Test Apple Sign In only in staging/production environments
483
+ 3. **Use mobile**: Apple Sign In works in development on the mobile app via native SDKs
484
+
485
+ ### Web: Session not persisting
486
+
487
+ 1. **Cookie settings**: In development, cookies require `SameSite=Lax` and `Secure=false`
488
+ 2. **Domain mismatch**: Ensure frontend and backend are on the same domain (or properly configured for cross-domain)
489
+ 3. **Check browser DevTools**: Network tab -> Cookies to see if session cookie is being set
490
+
491
+ ### Web: 404 on refresh (deployed)
492
+
493
+ If routes work initially but 404 on refresh:
494
+
495
+ 1. **Vercel**: Should work out of the box
496
+ 2. **Netlify**: Install the `@netlify/plugin-nextjs` plugin. Do NOT use SPA-style redirects - Next.js uses SSR:
497
+ ```toml
498
+ # netlify.toml
499
+ [[plugins]]
500
+ package = "@netlify/plugin-nextjs"
501
+ ```
502
+ 3. **Self-hosted Node.js**: Ensure you're running `next start` (not serving static files)
503
+ 4. **Docker/Nginx**: Use a reverse proxy to the Node.js server, not static file serving
504
+
505
+ ### Web: Build fails with module errors
506
+
507
+ ```bash
508
+ # Clear Next.js cache
509
+ rm -rf web/.next
510
+
511
+ # Reinstall dependencies
512
+ rm -rf web/node_modules
513
+ bun install
514
+ ```
515
+
516
+ ## FAQ
517
+
518
+ **Q: What's the difference between presets?**
519
+ A: Minimal has basic features, Full-Featured has everything including OAuth and all SDKs, Analytics-Focused has Adjust + Scate for attribution.
520
+
521
+ **Q: Can I add features later?**
522
+ A: Yes, but it's easier to start with more features and remove what you don't need.
523
+
524
+ **Q: Is this production-ready?**
525
+ A: The generated code is production-quality. Test thoroughly before deploying.
526
+
527
+ **Q: What about web support?**
528
+ A: Yes! We support both Expo for mobile (iOS & Android) and Next.js for web. Both share the same backend and authentication.
529
+
530
+ **Q: Which ORM should I choose?**
531
+ A: **Prisma** (default) is great for most projects with its auto-generated client and migrations. **Drizzle** is lighter-weight, SQL-first, and better for serverless environments. Both work identically with BetterAuth.
532
+
533
+ **Q: What OAuth providers are supported?**
534
+ A: Google, Apple, and GitHub. Google and Apple have native SDK support on mobile with automatic browser fallback. GitHub uses browser-based OAuth only.
535
+
536
+ **Q: Can I customize the templates?**
537
+ A: Not yet, but template customization is planned for future versions.
538
+
539
+ **Q: Can I use the web app without mobile?**
540
+ A: Yes! During CLI setup, select "web" as your only platform. This generates just the web app and backend, without any mobile code.
541
+
542
+ **Q: Why does web use cookies instead of tokens?**
543
+ A: Cookie-based sessions are more secure for web applications - they're HTTP-only (no JavaScript access), automatically included in requests, and protected against XSS attacks. Mobile apps use secure token storage because they don't have cookie support.
544
+
545
+ **Q: Can I share authentication between web and mobile?**
546
+ A: Yes, both platforms authenticate against the same backend and share the same user database. However, sessions are separate - logging in on web doesn't log you in on mobile and vice versa.
547
+
548
+ **Q: Why doesn't Apple Sign In work on localhost?**
549
+ A: Apple requires HTTPS for OAuth redirect URIs. Use ngrok or a similar tunneling service for local development, or test Apple Sign In in a staging environment with a valid SSL certificate.
550
+
551
+ **Q: How do I add more pages to the web app?**
552
+ A: Create new files in `web/src/app/`. For protected pages, put them in `(app)/`. For public pages, put them directly in `app/`. See the [Next.js App Router docs](https://nextjs.org/docs/app/building-your-application/routing).
553
+
554
+ **Q: How do I customize the web design?**
555
+ A: The web app uses Tailwind CSS and shadcn/ui components. Edit `globals.css` for color scheme changes, or modify individual components in `src/components/ui/`.
556
+
557
+ **Q: Does the web app support SSR?**
558
+ A: Yes, Next.js App Router uses React Server Components by default. Client components (marked with `"use client"`) handle interactive features like forms and auth state.
559
+
560
+ ## Roadmap
561
+
562
+ ### Completed in v0.2.0
563
+ - [x] OAuth support (Google, Apple, GitHub)
564
+ - [x] BetterAuth authentication framework
565
+ - [x] Drizzle ORM as alternative to Prisma
566
+ - [x] Next.js web app support
567
+ - [x] Native OAuth SDKs with browser fallback
568
+ - [x] Two-factor authentication (TOTP)
569
+ - [x] Email verification & password reset
570
+
571
+ ### Upcoming
572
+ - [ ] v0.3.0: Additional template customization
573
+ - [ ] v0.4.0: More SDK integrations (Firebase, Supabase)
574
+ - [ ] v1.0.0: Stable API, production-ready
575
+
576
+ ## Technology Stack
577
+
578
+ ### CLI Framework
579
+ - **Commander.js** - Command-line interface framework
580
+ - **Inquirer.js** - Interactive prompts
581
+ - **chalk** - Terminal colors
582
+ - **ora** - Loading spinners
583
+ - **boxen** - Terminal boxes
584
+ - **EJS** - Template rendering
585
+
586
+ ### Generated Stack
587
+ - **Expo** - React Native mobile framework
588
+ - **Next.js** - React web framework
589
+ - **Fastify** - Node.js backend
590
+ - **BetterAuth** - Authentication framework
591
+ - **Prisma** - Type-safe ORM (default)
592
+ - **Drizzle** - SQL-first ORM (alternative)
593
+ - **PostgreSQL** - Database
594
+ - **Redis** - Caching & queues
595
+
596
+ ### Development
597
+ - **TypeScript** - Type safety
598
+ - **Vitest** - Testing framework
599
+ - **ESLint** - Linting
600
+ - **Prettier** - Code formatting
601
+
602
+ ## Project Status
603
+
604
+ ### Completed Features
605
+
606
+ - [x] CLI framework using Commander.js
607
+ - [x] Interactive prompts using Inquirer.js
608
+ - [x] Input validation and error handling
609
+ - [x] Three preset templates (Minimal, Full-Featured, Analytics-Focused)
610
+ - [x] Custom configuration flow
611
+ - [x] Comprehensive unit tests
612
+ - [x] Type-safe configuration schema
613
+ - [x] Package manager selection
614
+ - [x] Template system using EJS
615
+ - [x] File generation and copying
616
+ - [x] Project scaffolding
617
+ - [x] Conditional feature integration
618
+ - [x] BetterAuth authentication integration
619
+ - [x] OAuth providers (Google, Apple, GitHub)
620
+ - [x] Native OAuth SDKs with browser fallback
621
+ - [x] Drizzle ORM support as Prisma alternative
622
+ - [x] Two-factor authentication (TOTP)
623
+ - [x] Email verification & password reset
624
+ - [x] Next.js web app support
625
+
626
+ ## Contributing
627
+
628
+ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
629
+
630
+ ## Security
631
+
632
+ See [SECURITY.md](SECURITY.md) for vulnerability reporting.
633
+
634
+ ## License
635
+
636
+ MIT © itharea
637
+
638
+ ## Support
639
+
640
+ - [Documentation](https://github.com/itharea/create-stackr)
641
+ - [Discussions](https://github.com/itharea/create-stackr/discussions)
642
+ - [Issues](https://github.com/itharea/create-stackr/issues)
package/bin/cli.js ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * CLI entry point
5
+ * This file is the executable that gets called when running:
6
+ * npx create-fullstack-app
7
+ */
8
+
9
+ import('../dist/index.js').catch((error) => {
10
+ console.error('Failed to load CLI:', error);
11
+ process.exit(1);
12
+ });
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { CLIOptions } from './types/index.js';
2
+ export declare function runCLI(projectName: string | undefined, options: CLIOptions): Promise<void>;
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAiB,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAElE,wBAAsB,MAAM,CAC1B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CAuEf"}