@better-t-stack/template-generator 3.13.2-dev.6c6cffb

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 (425) hide show
  1. package/dist/fs-writer.d.mts +8 -0
  2. package/dist/fs-writer.d.mts.map +1 -0
  3. package/dist/fs-writer.mjs +50 -0
  4. package/dist/fs-writer.mjs.map +1 -0
  5. package/dist/index.d.mts +182 -0
  6. package/dist/index.d.mts.map +1 -0
  7. package/dist/index.mjs +26727 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/dist/template-reader.d.mts +30 -0
  10. package/dist/template-reader.d.mts.map +1 -0
  11. package/dist/template-reader.mjs +2860 -0
  12. package/dist/template-reader.mjs.map +1 -0
  13. package/dist/types-BubFnV2d.d.mts +36 -0
  14. package/dist/types-BubFnV2d.d.mts.map +1 -0
  15. package/package.json +66 -0
  16. package/scripts/generate-templates.ts +97 -0
  17. package/templates/addons/biome/biome.json.hbs +96 -0
  18. package/templates/addons/husky/.husky/pre-commit +1 -0
  19. package/templates/addons/pwa/apps/web/next/public/favicon/apple-touch-icon.png +0 -0
  20. package/templates/addons/pwa/apps/web/next/public/favicon/favicon-96x96.png +0 -0
  21. package/templates/addons/pwa/apps/web/next/public/favicon/favicon.svg +6 -0
  22. package/templates/addons/pwa/apps/web/next/public/favicon/site.webmanifest.hbs +21 -0
  23. package/templates/addons/pwa/apps/web/next/public/favicon/web-app-manifest-192x192.png +0 -0
  24. package/templates/addons/pwa/apps/web/next/public/favicon/web-app-manifest-512x512.png +0 -0
  25. package/templates/addons/pwa/apps/web/next/src/app/manifest.ts.hbs +26 -0
  26. package/templates/addons/pwa/apps/web/vite/public/logo.png +0 -0
  27. package/templates/addons/pwa/apps/web/vite/pwa-assets.config.ts.hbs +12 -0
  28. package/templates/addons/ruler/.ruler/bts.md.hbs +142 -0
  29. package/templates/addons/ruler/.ruler/ruler.toml.hbs +80 -0
  30. package/templates/addons/turborepo/turbo.json.hbs +74 -0
  31. package/templates/addons/ultracite/biome.json.hbs +26 -0
  32. package/templates/api/orpc/fullstack/next/src/app/api/rpc/[[...rest]]/route.ts.hbs +50 -0
  33. package/templates/api/orpc/fullstack/tanstack-start/src/routes/api/rpc/$.ts.hbs +58 -0
  34. package/templates/api/orpc/native/utils/orpc.ts.hbs +39 -0
  35. package/templates/api/orpc/server/_gitignore +34 -0
  36. package/templates/api/orpc/server/package.json.hbs +15 -0
  37. package/templates/api/orpc/server/src/context.ts.hbs +148 -0
  38. package/templates/api/orpc/server/src/index.ts.hbs +21 -0
  39. package/templates/api/orpc/server/src/routers/index.ts.hbs +55 -0
  40. package/templates/api/orpc/server/tsconfig.json.hbs +10 -0
  41. package/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs +32 -0
  42. package/templates/api/orpc/web/nuxt/app/plugins/vue-query.ts.hbs +44 -0
  43. package/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs +113 -0
  44. package/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs +30 -0
  45. package/templates/api/orpc/web/svelte/src/lib/orpc.ts.hbs +30 -0
  46. package/templates/api/trpc/fullstack/next/src/app/api/trpc/[trpc]/route.ts.hbs +14 -0
  47. package/templates/api/trpc/fullstack/tanstack-start/src/routes/api/trpc/$.ts.hbs +22 -0
  48. package/templates/api/trpc/native/utils/trpc.ts.hbs +37 -0
  49. package/templates/api/trpc/server/_gitignore +34 -0
  50. package/templates/api/trpc/server/package.json.hbs +14 -0
  51. package/templates/api/trpc/server/src/context.ts.hbs +148 -0
  52. package/templates/api/trpc/server/src/index.ts.hbs +26 -0
  53. package/templates/api/trpc/server/src/routers/index.ts.hbs +55 -0
  54. package/templates/api/trpc/server/tsconfig.json.hbs +10 -0
  55. package/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs +97 -0
  56. package/templates/auth/better-auth/convex/backend/convex/auth.config.ts.hbs +6 -0
  57. package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +68 -0
  58. package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +12 -0
  59. package/templates/auth/better-auth/convex/backend/convex/privateData.ts.hbs +17 -0
  60. package/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs +127 -0
  61. package/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs +138 -0
  62. package/templates/auth/better-auth/convex/native/base/lib/auth-client.ts.hbs +18 -0
  63. package/templates/auth/better-auth/convex/native/unistyles/components/sign-in.tsx.hbs +127 -0
  64. package/templates/auth/better-auth/convex/native/unistyles/components/sign-up.tsx.hbs +145 -0
  65. package/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs +73 -0
  66. package/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs +85 -0
  67. package/templates/auth/better-auth/convex/web/react/next/src/app/api/auth/[...all]/route.ts.hbs +3 -0
  68. package/templates/auth/better-auth/convex/web/react/next/src/app/dashboard/page.tsx.hbs +40 -0
  69. package/templates/auth/better-auth/convex/web/react/next/src/components/sign-in-form.tsx.hbs +129 -0
  70. package/templates/auth/better-auth/convex/web/react/next/src/components/sign-up-form.tsx.hbs +154 -0
  71. package/templates/auth/better-auth/convex/web/react/next/src/components/user-menu.tsx.hbs +48 -0
  72. package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-client.ts.hbs +6 -0
  73. package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs +16 -0
  74. package/templates/auth/better-auth/convex/web/react/tanstack-router/src/components/sign-in-form.tsx.hbs +133 -0
  75. package/templates/auth/better-auth/convex/web/react/tanstack-router/src/components/sign-up-form.tsx.hbs +158 -0
  76. package/templates/auth/better-auth/convex/web/react/tanstack-router/src/components/user-menu.tsx.hbs +52 -0
  77. package/templates/auth/better-auth/convex/web/react/tanstack-router/src/lib/auth-client.ts.hbs +11 -0
  78. package/templates/auth/better-auth/convex/web/react/tanstack-router/src/routes/dashboard.tsx.hbs +43 -0
  79. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/components/sign-in-form.tsx.hbs +133 -0
  80. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/components/sign-up-form.tsx.hbs +158 -0
  81. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/components/user-menu.tsx.hbs +47 -0
  82. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-client.ts.hbs +6 -0
  83. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs +13 -0
  84. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/routes/api/auth/$.ts.hbs +11 -0
  85. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/routes/dashboard.tsx.hbs +43 -0
  86. package/templates/auth/better-auth/fullstack/next/src/app/api/auth/[...all]/route.ts.hbs +4 -0
  87. package/templates/auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs +15 -0
  88. package/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs +186 -0
  89. package/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs +131 -0
  90. package/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs +150 -0
  91. package/templates/auth/better-auth/native/base/lib/auth-client.ts.hbs +16 -0
  92. package/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs +187 -0
  93. package/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs +139 -0
  94. package/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs +157 -0
  95. package/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs +123 -0
  96. package/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs +87 -0
  97. package/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs +128 -0
  98. package/templates/auth/better-auth/server/base/_gitignore +34 -0
  99. package/templates/auth/better-auth/server/base/package.json.hbs +14 -0
  100. package/templates/auth/better-auth/server/base/src/index.ts.hbs +304 -0
  101. package/templates/auth/better-auth/server/base/tsconfig.json.hbs +10 -0
  102. package/templates/auth/better-auth/server/db/drizzle/mysql/src/schema/auth.ts.hbs +100 -0
  103. package/templates/auth/better-auth/server/db/drizzle/postgres/src/schema/auth.ts.hbs +93 -0
  104. package/templates/auth/better-auth/server/db/drizzle/sqlite/src/schema/auth.ts.hbs +107 -0
  105. package/templates/auth/better-auth/server/db/mongoose/mongodb/src/models/auth.model.ts.hbs +68 -0
  106. package/templates/auth/better-auth/server/db/prisma/mongodb/prisma/schema/auth.prisma.hbs +62 -0
  107. package/templates/auth/better-auth/server/db/prisma/mysql/prisma/schema/auth.prisma.hbs +62 -0
  108. package/templates/auth/better-auth/server/db/prisma/postgres/prisma/schema/auth.prisma.hbs +62 -0
  109. package/templates/auth/better-auth/server/db/prisma/sqlite/prisma/schema/auth.prisma.hbs +62 -0
  110. package/templates/auth/better-auth/web/nuxt/app/components/SignInForm.vue.hbs +82 -0
  111. package/templates/auth/better-auth/web/nuxt/app/components/SignUpForm.vue.hbs +91 -0
  112. package/templates/auth/better-auth/web/nuxt/app/components/UserMenu.vue.hbs +42 -0
  113. package/templates/auth/better-auth/web/nuxt/app/middleware/auth.ts.hbs +14 -0
  114. package/templates/auth/better-auth/web/nuxt/app/pages/dashboard.vue.hbs +99 -0
  115. package/templates/auth/better-auth/web/nuxt/app/pages/login.vue.hbs +27 -0
  116. package/templates/auth/better-auth/web/nuxt/app/plugins/auth-client.ts.hbs +21 -0
  117. package/templates/auth/better-auth/web/react/base/src/lib/auth-client.ts.hbs +16 -0
  118. package/templates/auth/better-auth/web/react/next/src/app/dashboard/dashboard.tsx.hbs +60 -0
  119. package/templates/auth/better-auth/web/react/next/src/app/dashboard/page.tsx.hbs +42 -0
  120. package/templates/auth/better-auth/web/react/next/src/app/login/page.tsx.hbs +16 -0
  121. package/templates/auth/better-auth/web/react/next/src/components/sign-in-form.tsx.hbs +135 -0
  122. package/templates/auth/better-auth/web/react/next/src/components/sign-up-form.tsx.hbs +160 -0
  123. package/templates/auth/better-auth/web/react/next/src/components/user-menu.tsx.hbs +62 -0
  124. package/templates/auth/better-auth/web/react/react-router/src/components/sign-in-form.tsx.hbs +135 -0
  125. package/templates/auth/better-auth/web/react/react-router/src/components/sign-up-form.tsx.hbs +160 -0
  126. package/templates/auth/better-auth/web/react/react-router/src/components/user-menu.tsx.hbs +61 -0
  127. package/templates/auth/better-auth/web/react/react-router/src/routes/dashboard.tsx.hbs +80 -0
  128. package/templates/auth/better-auth/web/react/react-router/src/routes/login.tsx.hbs +13 -0
  129. package/templates/auth/better-auth/web/react/tanstack-router/src/components/sign-in-form.tsx.hbs +135 -0
  130. package/templates/auth/better-auth/web/react/tanstack-router/src/components/sign-up-form.tsx.hbs +160 -0
  131. package/templates/auth/better-auth/web/react/tanstack-router/src/components/user-menu.tsx.hbs +63 -0
  132. package/templates/auth/better-auth/web/react/tanstack-router/src/routes/dashboard.tsx.hbs +71 -0
  133. package/templates/auth/better-auth/web/react/tanstack-router/src/routes/login.tsx.hbs +18 -0
  134. package/templates/auth/better-auth/web/react/tanstack-start/src/components/sign-in-form.tsx.hbs +135 -0
  135. package/templates/auth/better-auth/web/react/tanstack-start/src/components/sign-up-form.tsx.hbs +160 -0
  136. package/templates/auth/better-auth/web/react/tanstack-start/src/components/user-menu.tsx.hbs +63 -0
  137. package/templates/auth/better-auth/web/react/tanstack-start/src/functions/get-user.ts.hbs +6 -0
  138. package/templates/auth/better-auth/web/react/tanstack-start/src/middleware/auth.ts.hbs +31 -0
  139. package/templates/auth/better-auth/web/react/tanstack-start/src/routes/dashboard.tsx.hbs +84 -0
  140. package/templates/auth/better-auth/web/react/tanstack-start/src/routes/login.tsx.hbs +18 -0
  141. package/templates/auth/better-auth/web/solid/src/components/sign-in-form.tsx.hbs +124 -0
  142. package/templates/auth/better-auth/web/solid/src/components/sign-up-form.tsx.hbs +148 -0
  143. package/templates/auth/better-auth/web/solid/src/components/user-menu.tsx.hbs +55 -0
  144. package/templates/auth/better-auth/web/solid/src/lib/auth-client.ts.hbs +12 -0
  145. package/templates/auth/better-auth/web/solid/src/routes/dashboard.tsx.hbs +67 -0
  146. package/templates/auth/better-auth/web/solid/src/routes/login.tsx.hbs +23 -0
  147. package/templates/auth/better-auth/web/svelte/src/components/SignInForm.svelte.hbs +109 -0
  148. package/templates/auth/better-auth/web/svelte/src/components/SignUpForm.svelte.hbs +142 -0
  149. package/templates/auth/better-auth/web/svelte/src/components/UserMenu.svelte.hbs +52 -0
  150. package/templates/auth/better-auth/web/svelte/src/lib/auth-client.ts.hbs +12 -0
  151. package/templates/auth/better-auth/web/svelte/src/routes/dashboard/+page.svelte.hbs +59 -0
  152. package/templates/auth/better-auth/web/svelte/src/routes/login/+page.svelte.hbs +12 -0
  153. package/templates/auth/clerk/convex/backend/convex/auth.config.ts.hbs +12 -0
  154. package/templates/auth/clerk/convex/backend/convex/privateData.ts.hbs +16 -0
  155. package/templates/auth/clerk/convex/native/base/app/(auth)/_layout.tsx.hbs +12 -0
  156. package/templates/auth/clerk/convex/native/base/app/(auth)/sign-in.tsx.hbs +67 -0
  157. package/templates/auth/clerk/convex/native/base/app/(auth)/sign-up.tsx.hbs +110 -0
  158. package/templates/auth/clerk/convex/native/base/components/sign-out-button.tsx.hbs +27 -0
  159. package/templates/auth/clerk/convex/web/react/next/src/app/dashboard/page.tsx.hbs +29 -0
  160. package/templates/auth/clerk/convex/web/react/next/src/middleware.ts.hbs +12 -0
  161. package/templates/auth/clerk/convex/web/react/react-router/src/routes/dashboard.tsx.hbs +32 -0
  162. package/templates/auth/clerk/convex/web/react/tanstack-router/src/routes/dashboard.tsx.hbs +37 -0
  163. package/templates/auth/clerk/convex/web/react/tanstack-start/src/routes/dashboard.tsx.hbs +37 -0
  164. package/templates/auth/clerk/convex/web/react/tanstack-start/src/start.ts.hbs +8 -0
  165. package/templates/backend/convex/packages/backend/_gitignore +2 -0
  166. package/templates/backend/convex/packages/backend/convex/README.md +90 -0
  167. package/templates/backend/convex/packages/backend/convex/convex.config.ts.hbs +17 -0
  168. package/templates/backend/convex/packages/backend/convex/healthCheck.ts.hbs +7 -0
  169. package/templates/backend/convex/packages/backend/convex/schema.ts.hbs +11 -0
  170. package/templates/backend/convex/packages/backend/convex/tsconfig.json.hbs +25 -0
  171. package/templates/backend/convex/packages/backend/package.json.hbs +15 -0
  172. package/templates/backend/server/base/_gitignore +55 -0
  173. package/templates/backend/server/base/package.json.hbs +17 -0
  174. package/templates/backend/server/base/tsconfig.json.hbs +13 -0
  175. package/templates/backend/server/base/tsdown.config.ts.hbs +9 -0
  176. package/templates/backend/server/elysia/src/index.ts.hbs +122 -0
  177. package/templates/backend/server/express/src/index.ts.hbs +126 -0
  178. package/templates/backend/server/fastify/src/index.ts.hbs +187 -0
  179. package/templates/backend/server/hono/src/index.ts.hbs +171 -0
  180. package/templates/base/_gitignore +50 -0
  181. package/templates/base/package.json.hbs +10 -0
  182. package/templates/base/tsconfig.json.hbs +3 -0
  183. package/templates/db/base/_gitignore +35 -0
  184. package/templates/db/base/package.json.hbs +14 -0
  185. package/templates/db/base/tsconfig.json.hbs +10 -0
  186. package/templates/db/drizzle/base/src/schema/index.ts.hbs +7 -0
  187. package/templates/db/drizzle/mysql/drizzle.config.ts.hbs +19 -0
  188. package/templates/db/drizzle/mysql/src/index.ts.hbs +54 -0
  189. package/templates/db/drizzle/postgres/drizzle.config.ts.hbs +19 -0
  190. package/templates/db/drizzle/postgres/src/index.ts.hbs +44 -0
  191. package/templates/db/drizzle/sqlite/drizzle.config.ts.hbs +28 -0
  192. package/templates/db/drizzle/sqlite/src/index.ts.hbs +39 -0
  193. package/templates/db/mongoose/mongodb/src/index.ts.hbs +10 -0
  194. package/templates/db/prisma/mongodb/prisma/schema/schema.prisma.hbs +19 -0
  195. package/templates/db/prisma/mongodb/prisma.config.ts.hbs +18 -0
  196. package/templates/db/prisma/mongodb/src/index.ts.hbs +5 -0
  197. package/templates/db/prisma/mysql/prisma/schema/schema.prisma.hbs +21 -0
  198. package/templates/db/prisma/mysql/prisma.config.ts.hbs +21 -0
  199. package/templates/db/prisma/mysql/src/index.ts.hbs +55 -0
  200. package/templates/db/prisma/postgres/prisma/schema/schema.prisma.hbs +21 -0
  201. package/templates/db/prisma/postgres/prisma.config.ts.hbs +21 -0
  202. package/templates/db/prisma/postgres/src/index.ts.hbs +69 -0
  203. package/templates/db/prisma/sqlite/prisma/schema/schema.prisma.hbs +18 -0
  204. package/templates/db/prisma/sqlite/prisma.config.ts.hbs +25 -0
  205. package/templates/db/prisma/sqlite/src/index.ts.hbs +25 -0
  206. package/templates/db-setup/docker-compose/mongodb/docker-compose.yml.hbs +23 -0
  207. package/templates/db-setup/docker-compose/mysql/docker-compose.yml.hbs +24 -0
  208. package/templates/db-setup/docker-compose/postgres/docker-compose.yml.hbs +23 -0
  209. package/templates/examples/ai/convex/packages/backend/convex/agent.ts.hbs +9 -0
  210. package/templates/examples/ai/convex/packages/backend/convex/chat.ts.hbs +67 -0
  211. package/templates/examples/ai/fullstack/next/src/app/api/ai/route.ts.hbs +20 -0
  212. package/templates/examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbs +36 -0
  213. package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +586 -0
  214. package/templates/examples/ai/native/bare/polyfills.js +22 -0
  215. package/templates/examples/ai/native/unistyles/app/(drawer)/ai.tsx.hbs +588 -0
  216. package/templates/examples/ai/native/unistyles/polyfills.js +22 -0
  217. package/templates/examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs +331 -0
  218. package/templates/examples/ai/native/uniwind/polyfills.js +22 -0
  219. package/templates/examples/ai/web/nuxt/app/pages/ai.vue.hbs +54 -0
  220. package/templates/examples/ai/web/react/next/src/app/ai/page.tsx.hbs +267 -0
  221. package/templates/examples/ai/web/react/react-router/src/routes/ai.tsx.hbs +235 -0
  222. package/templates/examples/ai/web/react/tanstack-router/src/routes/ai.tsx.hbs +242 -0
  223. package/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs +243 -0
  224. package/templates/examples/ai/web/svelte/src/routes/ai/+page.svelte.hbs +107 -0
  225. package/templates/examples/todo/convex/packages/backend/convex/todos.ts.hbs +42 -0
  226. package/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs +521 -0
  227. package/templates/examples/todo/native/unistyles/app/(drawer)/todos.tsx.hbs +340 -0
  228. package/templates/examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs +282 -0
  229. package/templates/examples/todo/server/drizzle/base/src/routers/todo.ts.hbs +75 -0
  230. package/templates/examples/todo/server/drizzle/mysql/src/schema/todo.ts +7 -0
  231. package/templates/examples/todo/server/drizzle/postgres/src/schema/todo.ts +7 -0
  232. package/templates/examples/todo/server/drizzle/sqlite/src/schema/todo.ts +7 -0
  233. package/templates/examples/todo/server/mongoose/base/src/routers/todo.ts.hbs +66 -0
  234. package/templates/examples/todo/server/mongoose/mongodb/src/models/todo.model.ts.hbs +24 -0
  235. package/templates/examples/todo/server/prisma/base/src/routers/todo.ts.hbs +116 -0
  236. package/templates/examples/todo/server/prisma/mongodb/prisma/schema/todo.prisma.hbs +7 -0
  237. package/templates/examples/todo/server/prisma/mysql/prisma/schema/todo.prisma.hbs +7 -0
  238. package/templates/examples/todo/server/prisma/postgres/prisma/schema/todo.prisma.hbs +7 -0
  239. package/templates/examples/todo/server/prisma/sqlite/prisma/schema/todo.prisma.hbs +7 -0
  240. package/templates/examples/todo/web/nuxt/app/pages/todos.vue.hbs +220 -0
  241. package/templates/examples/todo/web/react/next/src/app/todos/page.tsx.hbs +245 -0
  242. package/templates/examples/todo/web/react/react-router/src/routes/todos.tsx.hbs +242 -0
  243. package/templates/examples/todo/web/react/tanstack-router/src/routes/todos.tsx.hbs +247 -0
  244. package/templates/examples/todo/web/react/tanstack-start/src/routes/todos.tsx.hbs +272 -0
  245. package/templates/examples/todo/web/solid/src/routes/todos.tsx.hbs +132 -0
  246. package/templates/examples/todo/web/svelte/src/routes/todos/+page.svelte.hbs +317 -0
  247. package/templates/extras/_npmrc.hbs +5 -0
  248. package/templates/extras/bunfig.toml.hbs +6 -0
  249. package/templates/extras/pnpm-workspace.yaml +3 -0
  250. package/templates/frontend/native/bare/_gitignore +18 -0
  251. package/templates/frontend/native/bare/app/(drawer)/(tabs)/_layout.tsx.hbs +41 -0
  252. package/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs +43 -0
  253. package/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs +43 -0
  254. package/templates/frontend/native/bare/app/(drawer)/_layout.tsx.hbs +90 -0
  255. package/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs +234 -0
  256. package/templates/frontend/native/bare/app/+not-found.tsx.hbs +65 -0
  257. package/templates/frontend/native/bare/app/_layout.tsx.hbs +165 -0
  258. package/templates/frontend/native/bare/app/modal.tsx.hbs +34 -0
  259. package/templates/frontend/native/bare/app.json.hbs +50 -0
  260. package/templates/frontend/native/bare/components/container.tsx.hbs +25 -0
  261. package/templates/frontend/native/bare/components/header-button.tsx.hbs +47 -0
  262. package/templates/frontend/native/bare/components/tabbar-icon.tsx.hbs +9 -0
  263. package/templates/frontend/native/bare/lib/android-navigation-bar.tsx.hbs +12 -0
  264. package/templates/frontend/native/bare/lib/constants.ts.hbs +19 -0
  265. package/templates/frontend/native/bare/lib/use-color-scheme.ts.hbs +20 -0
  266. package/templates/frontend/native/bare/metro.config.js.hbs +9 -0
  267. package/templates/frontend/native/bare/package.json.hbs +51 -0
  268. package/templates/frontend/native/bare/tsconfig.json.hbs +11 -0
  269. package/templates/frontend/native/base/assets/images/android-icon-background.png +0 -0
  270. package/templates/frontend/native/base/assets/images/android-icon-foreground.png +0 -0
  271. package/templates/frontend/native/base/assets/images/android-icon-monochrome.png +0 -0
  272. package/templates/frontend/native/base/assets/images/favicon.png +0 -0
  273. package/templates/frontend/native/base/assets/images/icon.png +0 -0
  274. package/templates/frontend/native/base/assets/images/partial-react-logo.png +0 -0
  275. package/templates/frontend/native/base/assets/images/react-logo.png +0 -0
  276. package/templates/frontend/native/base/assets/images/react-logo@2x.png +0 -0
  277. package/templates/frontend/native/base/assets/images/react-logo@3x.png +0 -0
  278. package/templates/frontend/native/base/assets/images/splash-icon.png +0 -0
  279. package/templates/frontend/native/unistyles/_gitignore +24 -0
  280. package/templates/frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx.hbs +39 -0
  281. package/templates/frontend/native/unistyles/app/(drawer)/(tabs)/index.tsx.hbs +37 -0
  282. package/templates/frontend/native/unistyles/app/(drawer)/(tabs)/two.tsx.hbs +37 -0
  283. package/templates/frontend/native/unistyles/app/(drawer)/_layout.tsx.hbs +87 -0
  284. package/templates/frontend/native/unistyles/app/(drawer)/index.tsx.hbs +333 -0
  285. package/templates/frontend/native/unistyles/app/+not-found.tsx.hbs +65 -0
  286. package/templates/frontend/native/unistyles/app/_layout.tsx.hbs +169 -0
  287. package/templates/frontend/native/unistyles/app/modal.tsx.hbs +33 -0
  288. package/templates/frontend/native/unistyles/app.json.hbs +49 -0
  289. package/templates/frontend/native/unistyles/babel.config.js.hbs +21 -0
  290. package/templates/frontend/native/unistyles/breakpoints.ts.hbs +9 -0
  291. package/templates/frontend/native/unistyles/components/container.tsx.hbs +15 -0
  292. package/templates/frontend/native/unistyles/components/header-button.tsx.hbs +36 -0
  293. package/templates/frontend/native/unistyles/components/tabbar-icon.tsx.hbs +8 -0
  294. package/templates/frontend/native/unistyles/index.js.hbs +2 -0
  295. package/templates/frontend/native/unistyles/metro.config.js.hbs +5 -0
  296. package/templates/frontend/native/unistyles/package.json.hbs +51 -0
  297. package/templates/frontend/native/unistyles/theme.ts.hbs +98 -0
  298. package/templates/frontend/native/unistyles/tsconfig.json.hbs +12 -0
  299. package/templates/frontend/native/unistyles/unistyles.ts.hbs +27 -0
  300. package/templates/frontend/native/uniwind/_gitignore +21 -0
  301. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs +46 -0
  302. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs +15 -0
  303. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs +15 -0
  304. package/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs +91 -0
  305. package/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs +191 -0
  306. package/templates/frontend/native/uniwind/app/+not-found.tsx.hbs +27 -0
  307. package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +132 -0
  308. package/templates/frontend/native/uniwind/app/modal.tsx.hbs +37 -0
  309. package/templates/frontend/native/uniwind/app.json.hbs +19 -0
  310. package/templates/frontend/native/uniwind/components/container.tsx.hbs +33 -0
  311. package/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs +35 -0
  312. package/templates/frontend/native/uniwind/contexts/app-theme-context.tsx.hbs +62 -0
  313. package/templates/frontend/native/uniwind/global.css +5 -0
  314. package/templates/frontend/native/uniwind/metro.config.js.hbs +13 -0
  315. package/templates/frontend/native/uniwind/package.json.hbs +54 -0
  316. package/templates/frontend/native/uniwind/tsconfig.json.hbs +14 -0
  317. package/templates/frontend/nuxt/_gitignore +27 -0
  318. package/templates/frontend/nuxt/app/app.config.ts.hbs +15 -0
  319. package/templates/frontend/nuxt/app/app.vue.hbs +17 -0
  320. package/templates/frontend/nuxt/app/assets/css/main.css +2 -0
  321. package/templates/frontend/nuxt/app/components/Header.vue.hbs +40 -0
  322. package/templates/frontend/nuxt/app/layouts/default.vue.hbs +10 -0
  323. package/templates/frontend/nuxt/app/pages/index.vue.hbs +97 -0
  324. package/templates/frontend/nuxt/nuxt.config.ts.hbs +29 -0
  325. package/templates/frontend/nuxt/package.json.hbs +24 -0
  326. package/templates/frontend/nuxt/public/favicon.ico +0 -0
  327. package/templates/frontend/nuxt/public/robots.txt +2 -0
  328. package/templates/frontend/nuxt/server/tsconfig.json +3 -0
  329. package/templates/frontend/nuxt/tsconfig.json.hbs +18 -0
  330. package/templates/frontend/react/next/next-env.d.ts.hbs +5 -0
  331. package/templates/frontend/react/next/next.config.ts.hbs +22 -0
  332. package/templates/frontend/react/next/package.json.hbs +34 -0
  333. package/templates/frontend/react/next/postcss.config.mjs.hbs +5 -0
  334. package/templates/frontend/react/next/src/app/favicon.ico +0 -0
  335. package/templates/frontend/react/next/src/app/layout.tsx.hbs +76 -0
  336. package/templates/frontend/react/next/src/app/page.tsx.hbs +79 -0
  337. package/templates/frontend/react/next/src/components/mode-toggle.tsx.hbs +37 -0
  338. package/templates/frontend/react/next/src/components/providers.tsx.hbs +89 -0
  339. package/templates/frontend/react/next/src/components/theme-provider.tsx.hbs +11 -0
  340. package/templates/frontend/react/next/tsconfig.json.hbs +41 -0
  341. package/templates/frontend/react/react-router/package.json.hbs +42 -0
  342. package/templates/frontend/react/react-router/public/favicon.ico +0 -0
  343. package/templates/frontend/react/react-router/react-router.config.ts +6 -0
  344. package/templates/frontend/react/react-router/src/components/mode-toggle.tsx.hbs +29 -0
  345. package/templates/frontend/react/react-router/src/components/theme-provider.tsx.hbs +11 -0
  346. package/templates/frontend/react/react-router/src/root.tsx.hbs +190 -0
  347. package/templates/frontend/react/react-router/src/routes/_index.tsx.hbs +85 -0
  348. package/templates/frontend/react/react-router/src/routes.ts +4 -0
  349. package/templates/frontend/react/react-router/tsconfig.json.hbs +27 -0
  350. package/templates/frontend/react/react-router/vite.config.ts.hbs +12 -0
  351. package/templates/frontend/react/tanstack-router/index.html.hbs +13 -0
  352. package/templates/frontend/react/tanstack-router/package.json.hbs +41 -0
  353. package/templates/frontend/react/tanstack-router/src/components/mode-toggle.tsx.hbs +29 -0
  354. package/templates/frontend/react/tanstack-router/src/components/theme-provider.tsx.hbs +11 -0
  355. package/templates/frontend/react/tanstack-router/src/main.tsx.hbs +90 -0
  356. package/templates/frontend/react/tanstack-router/src/routes/__root.tsx.hbs +103 -0
  357. package/templates/frontend/react/tanstack-router/src/routes/index.tsx.hbs +85 -0
  358. package/templates/frontend/react/tanstack-router/tsconfig.json.hbs +18 -0
  359. package/templates/frontend/react/tanstack-router/vite.config.ts.hbs +21 -0
  360. package/templates/frontend/react/tanstack-start/package.json.hbs +43 -0
  361. package/templates/frontend/react/tanstack-start/public/robots.txt +3 -0
  362. package/templates/frontend/react/tanstack-start/src/router.tsx.hbs +144 -0
  363. package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +208 -0
  364. package/templates/frontend/react/tanstack-start/src/routes/index.tsx.hbs +85 -0
  365. package/templates/frontend/react/tanstack-start/tsconfig.json.hbs +28 -0
  366. package/templates/frontend/react/tanstack-start/vite.config.ts.hbs +22 -0
  367. package/templates/frontend/react/web-base/_gitignore +60 -0
  368. package/templates/frontend/react/web-base/components.json +24 -0
  369. package/templates/frontend/react/web-base/src/components/header.tsx.hbs +78 -0
  370. package/templates/frontend/react/web-base/src/components/loader.tsx.hbs +9 -0
  371. package/templates/frontend/react/web-base/src/components/ui/button.tsx.hbs +57 -0
  372. package/templates/frontend/react/web-base/src/components/ui/card.tsx.hbs +103 -0
  373. package/templates/frontend/react/web-base/src/components/ui/checkbox.tsx.hbs +26 -0
  374. package/templates/frontend/react/web-base/src/components/ui/dropdown-menu.tsx.hbs +262 -0
  375. package/templates/frontend/react/web-base/src/components/ui/input.tsx.hbs +20 -0
  376. package/templates/frontend/react/web-base/src/components/ui/label.tsx.hbs +20 -0
  377. package/templates/frontend/react/web-base/src/components/ui/skeleton.tsx.hbs +13 -0
  378. package/templates/frontend/react/web-base/src/components/ui/sonner.tsx.hbs +44 -0
  379. package/templates/frontend/react/web-base/src/index.css.hbs +131 -0
  380. package/templates/frontend/react/web-base/src/lib/utils.ts.hbs +6 -0
  381. package/templates/frontend/solid/_gitignore +11 -0
  382. package/templates/frontend/solid/index.html +13 -0
  383. package/templates/frontend/solid/package.json.hbs +24 -0
  384. package/templates/frontend/solid/public/robots.txt +3 -0
  385. package/templates/frontend/solid/src/components/header.tsx.hbs +38 -0
  386. package/templates/frontend/solid/src/components/loader.tsx +9 -0
  387. package/templates/frontend/solid/src/main.tsx.hbs +41 -0
  388. package/templates/frontend/solid/src/routes/__root.tsx.hbs +34 -0
  389. package/templates/frontend/solid/src/routes/index.tsx.hbs +72 -0
  390. package/templates/frontend/solid/src/styles.css +5 -0
  391. package/templates/frontend/solid/tsconfig.json.hbs +29 -0
  392. package/templates/frontend/solid/vite.config.ts.hbs +21 -0
  393. package/templates/frontend/svelte/_gitignore +24 -0
  394. package/templates/frontend/svelte/_npmrc +1 -0
  395. package/templates/frontend/svelte/package.json.hbs +27 -0
  396. package/templates/frontend/svelte/src/app.css +5 -0
  397. package/templates/frontend/svelte/src/app.d.ts +13 -0
  398. package/templates/frontend/svelte/src/app.html +12 -0
  399. package/templates/frontend/svelte/src/components/Header.svelte.hbs +40 -0
  400. package/templates/frontend/svelte/src/lib/index.ts +2 -0
  401. package/templates/frontend/svelte/src/routes/+layout.svelte.hbs +54 -0
  402. package/templates/frontend/svelte/src/routes/+page.svelte.hbs +92 -0
  403. package/templates/frontend/svelte/static/favicon.png +0 -0
  404. package/templates/frontend/svelte/svelte.config.js.hbs +18 -0
  405. package/templates/frontend/svelte/tsconfig.json.hbs +19 -0
  406. package/templates/frontend/svelte/vite.config.ts.hbs +7 -0
  407. package/templates/packages/config/package.json.hbs +5 -0
  408. package/templates/packages/config/tsconfig.base.json.hbs +33 -0
  409. package/templates/packages/env/env.d.ts.hbs +16 -0
  410. package/templates/packages/env/package.json.hbs +7 -0
  411. package/templates/packages/env/src/native.ts.hbs +21 -0
  412. package/templates/packages/env/src/server.ts.hbs +39 -0
  413. package/templates/packages/env/src/web.ts.hbs +98 -0
  414. package/templates/packages/env/tsconfig.json.hbs +3 -0
  415. package/templates/packages/infra/alchemy.run.ts.hbs +271 -0
  416. package/templates/packages/infra/package.json.hbs +10 -0
  417. package/templates/payments/polar/server/base/src/lib/payments.ts.hbs +7 -0
  418. package/templates/payments/polar/web/nuxt/app/pages/success.vue.hbs +11 -0
  419. package/templates/payments/polar/web/react/next/src/app/success/page.tsx.hbs +15 -0
  420. package/templates/payments/polar/web/react/react-router/src/routes/success.tsx.hbs +13 -0
  421. package/templates/payments/polar/web/react/tanstack-router/src/routes/success.tsx.hbs +19 -0
  422. package/templates/payments/polar/web/react/tanstack-start/src/functions/get-payment.ts.hbs +15 -0
  423. package/templates/payments/polar/web/react/tanstack-start/src/routes/success.tsx.hbs +19 -0
  424. package/templates/payments/polar/web/solid/src/routes/success.tsx.hbs +23 -0
  425. package/templates/payments/polar/web/svelte/src/routes/success/+page.svelte.hbs +12 -0
@@ -0,0 +1,15 @@
1
+ import { Container } from "@/components/container";
2
+ import { Text, View } from "react-native";
3
+ import { Card } from "heroui-native";
4
+
5
+ export default function Home() {
6
+ return (
7
+ <Container className="p-6">
8
+ <View className="flex-1 justify-center items-center">
9
+ <Card variant="secondary" className="p-8 items-center">
10
+ <Card.Title className="text-3xl mb-2">Tab One</Card.Title>
11
+ </Card>
12
+ </View>
13
+ </Container>
14
+ );
15
+ }
@@ -0,0 +1,15 @@
1
+ import { Container } from "@/components/container";
2
+ import { Text, View } from "react-native";
3
+ import { Card } from "heroui-native";
4
+
5
+ export default function TabTwo() {
6
+ return (
7
+ <Container className="p-6">
8
+ <View className="flex-1 justify-center items-center">
9
+ <Card variant="secondary" className="p-8 items-center">
10
+ <Card.Title className="text-3xl mb-2">TabTwo</Card.Title>
11
+ </Card>
12
+ </View>
13
+ </Container>
14
+ );
15
+ }
@@ -0,0 +1,91 @@
1
+ import React, { useCallback } from "react";
2
+ import { Ionicons, MaterialIcons } from "@expo/vector-icons";
3
+ import { Link } from "expo-router";
4
+ import { Drawer } from "expo-router/drawer";
5
+ import { useThemeColor } from "heroui-native";
6
+ import { Pressable, Text } from "react-native";
7
+ import { ThemeToggle } from "@/components/theme-toggle";
8
+
9
+ function DrawerLayout() {
10
+ const themeColorForeground = useThemeColor("foreground");
11
+ const themeColorBackground = useThemeColor("background");
12
+
13
+ const renderThemeToggle = useCallback(() => <ThemeToggle />, []);
14
+
15
+ return (
16
+ <Drawer
17
+ screenOptions=\{{
18
+ headerTintColor: themeColorForeground,
19
+ headerStyle: { backgroundColor: themeColorBackground },
20
+ headerTitleStyle: {
21
+ fontWeight: "600",
22
+ color: themeColorForeground,
23
+ },
24
+ headerRight: renderThemeToggle,
25
+ drawerStyle: { backgroundColor: themeColorBackground },
26
+ }}
27
+ >
28
+ <Drawer.Screen
29
+ name="index"
30
+ options=\{{
31
+ headerTitle: "Home",
32
+ drawerLabel: ({ color, focused }) => (
33
+ <Text style=\{{ color: focused ? color : themeColorForeground }}>Home</Text>
34
+ ),
35
+ drawerIcon: ({ size, color, focused }) => (
36
+ <Ionicons name="home-outline" size={size} color={focused ? color : themeColorForeground} />
37
+ ),
38
+ }}
39
+ />
40
+ <Drawer.Screen
41
+ name="(tabs)"
42
+ options=\{{
43
+ headerTitle: "Tabs",
44
+ drawerLabel: ({ color, focused }) => (
45
+ <Text style=\{{ color: focused ? color : themeColorForeground }}>Tabs</Text>
46
+ ),
47
+ drawerIcon: ({ size, color, focused }) => (
48
+ <MaterialIcons name="border-bottom" size={size} color={focused ? color : themeColorForeground} />
49
+ ),
50
+ headerRight: () => (
51
+ <Link href="/modal" asChild>
52
+ <Pressable className="mr-4">
53
+ <Ionicons name="add-outline" size={24} color={themeColorForeground} />
54
+ </Pressable>
55
+ </Link>
56
+ ),
57
+ }}
58
+ />
59
+ {{#if (includes examples "todo")}}
60
+ <Drawer.Screen
61
+ name="todos"
62
+ options=\{{
63
+ headerTitle: "Todos",
64
+ drawerLabel: ({ color, focused }) => (
65
+ <Text style=\{{ color: focused ? color : themeColorForeground }}>Todos</Text>
66
+ ),
67
+ drawerIcon: ({ size, color, focused }) => (
68
+ <Ionicons name="checkbox-outline" size={size} color={focused ? color : themeColorForeground} />
69
+ ),
70
+ }}
71
+ />
72
+ {{/if}}
73
+ {{#if (includes examples "ai")}}
74
+ <Drawer.Screen
75
+ name="ai"
76
+ options=\{{
77
+ headerTitle: "AI",
78
+ drawerLabel: ({ color, focused }) => (
79
+ <Text style=\{{ color: focused ? color : themeColorForeground }}>AI</Text>
80
+ ),
81
+ drawerIcon: ({ size, color, focused }) => (
82
+ <Ionicons name="chatbubble-ellipses-outline" size={size} color={focused ? color : themeColorForeground} />
83
+ ),
84
+ }}
85
+ />
86
+ {{/if}}
87
+ </Drawer>
88
+ );
89
+ }
90
+
91
+ export default DrawerLayout;
@@ -0,0 +1,191 @@
1
+ import { Text, View } from "react-native";
2
+ import { Container } from "@/components/container";
3
+ {{#if (eq api "orpc")}}
4
+ import { useQuery } from "@tanstack/react-query";
5
+ import { orpc } from "@/utils/orpc";
6
+ {{/if}}
7
+ {{#if (eq api "trpc")}}
8
+ import { useQuery } from "@tanstack/react-query";
9
+ import { trpc } from "@/utils/trpc";
10
+ {{/if}}
11
+ {{#if (and (eq backend "convex") (eq auth "clerk"))}}
12
+ import { Link } from "expo-router";
13
+ import { Authenticated, AuthLoading, Unauthenticated, useQuery } from "convex/react";
14
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
15
+ import { useUser } from "@clerk/clerk-expo";
16
+ import { SignOutButton } from "@/components/sign-out-button";
17
+ {{else if (and (eq backend "convex") (eq auth "better-auth"))}}
18
+ import { useConvexAuth, useQuery } from "convex/react";
19
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
20
+ import { authClient } from "@/lib/auth-client";
21
+ import { SignIn } from "@/components/sign-in";
22
+ import { SignUp } from "@/components/sign-up";
23
+ {{else if (eq backend "convex")}}
24
+ import { useQuery } from "convex/react";
25
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
26
+ {{/if}}
27
+ {{#unless (or (eq backend "none") (and (eq backend "convex") (eq auth "better-auth")))}}
28
+ import { Ionicons } from "@expo/vector-icons";
29
+ {{/unless}}
30
+ import { Button, Chip, Divider, Spinner, Surface, useThemeColor } from "heroui-native";
31
+
32
+ export default function Home() {
33
+ {{#if (eq api "orpc")}}
34
+ const healthCheck = useQuery(orpc.healthCheck.queryOptions());
35
+ {{/if}}
36
+ {{#if (eq api "trpc")}}
37
+ const healthCheck = useQuery(trpc.healthCheck.queryOptions());
38
+ {{/if}}
39
+ {{#if (and (eq backend "convex") (eq auth "clerk"))}}
40
+ const { user } = useUser();
41
+ const healthCheck = useQuery(api.healthCheck.get);
42
+ const privateData = useQuery(api.privateData.get);
43
+ {{else if (and (eq backend "convex") (eq auth "better-auth"))}}
44
+ const healthCheck = useQuery(api.healthCheck.get);
45
+ const { isAuthenticated } = useConvexAuth();
46
+ const user = useQuery(api.auth.getCurrentUser, isAuthenticated ? {} : "skip");
47
+ {{else if (eq backend "convex")}}
48
+ const healthCheck = useQuery(api.healthCheck.get);
49
+ {{/if}}
50
+ {{#unless (eq backend "none")}}
51
+ const successColor = useThemeColor("success");
52
+ const dangerColor = useThemeColor("danger");
53
+
54
+ {{#if (eq backend "convex")}}
55
+ const isConnected = healthCheck === "OK";
56
+ const isLoading = healthCheck === undefined;
57
+ {{else}}
58
+ {{#unless (eq api "none")}}
59
+ const isConnected = healthCheck?.data === "OK";
60
+ const isLoading = healthCheck?.isLoading;
61
+ {{/unless}}
62
+ {{/if}}
63
+ {{/unless}}
64
+
65
+ return (
66
+ <Container className="p-4">
67
+ <View className="py-6 mb-4">
68
+ <Text className="text-3xl font-semibold text-foreground tracking-tight">
69
+ Better T Stack
70
+ </Text>
71
+ <Text className="text-muted text-sm mt-1">Full-stack TypeScript starter</Text>
72
+ </View>
73
+
74
+ {{#unless (or (eq backend "none") (and (eq backend "convex") (eq auth "better-auth")))}}
75
+ <Surface variant="secondary" className="p-4 rounded-lg">
76
+ <View className="flex-row items-center justify-between mb-3">
77
+ <Text className="text-foreground font-medium">System Status</Text>
78
+ <Chip variant="secondary" color={isConnected ? "success" : "danger" } size="sm">
79
+ <Chip.Label>
80
+ {isConnected ? "LIVE" : "OFFLINE"}
81
+ </Chip.Label>
82
+ </Chip>
83
+ </View>
84
+
85
+ <Divider className="mb-3" />
86
+
87
+ <Surface variant="tertiary" className="p-3 rounded-md">
88
+ <View className="flex-row items-center">
89
+ <View className={`w-2 h-2 rounded-full mr-3 ${ isConnected ? "bg-success" : "bg-muted" }`} />
90
+ <View className="flex-1">
91
+ <Text className="text-foreground text-sm font-medium">
92
+ {{#if (eq backend "convex")}}
93
+ Convex Backend
94
+ {{else}}
95
+ {{#unless (eq api "none")}}
96
+ {{#if (eq api "orpc")}}ORPC{{else}}TRPC{{/if}} Backend
97
+ {{/unless}}
98
+ {{/if}}
99
+ </Text>
100
+ <Text className="text-muted text-xs mt-0.5">
101
+ {isLoading
102
+ ? "Checking connection..."
103
+ : isConnected
104
+ ? "Connected to API"
105
+ : "API Disconnected"}
106
+ </Text>
107
+ </View>
108
+ {isLoading && <Spinner size="sm" />}
109
+ {!isLoading && isConnected && (
110
+ <Ionicons name="checkmark-circle" size={18} color={successColor} />
111
+ )}
112
+ {!isLoading && !isConnected && (
113
+ <Ionicons name="close-circle" size={18} color={dangerColor} />
114
+ )}
115
+ </View>
116
+ </Surface>
117
+ </Surface>
118
+ {{/unless}}
119
+
120
+ {{#if (and (eq backend "convex") (eq auth "clerk"))}}
121
+ <Authenticated>
122
+ <Surface variant="secondary" className="mt-4 p-4 rounded-lg">
123
+ <View className="flex-row items-center justify-between">
124
+ <View className="flex-1">
125
+ <Text className="text-foreground font-medium">{user?.emailAddresses[0].emailAddress}</Text>
126
+ <Text className="text-muted text-xs mt-0.5">Private: {privateData?.message}</Text>
127
+ </View>
128
+ <SignOutButton />
129
+ </View>
130
+ </Surface>
131
+ </Authenticated>
132
+ <Unauthenticated>
133
+ <View className="mt-4 gap-3">
134
+ <Link href="/(auth)/sign-in" asChild>
135
+ <Button variant="secondary"><Button.Label>Sign In</Button.Label></Button>
136
+ </Link>
137
+ <Link href="/(auth)/sign-up" asChild>
138
+ <Button variant="ghost"><Button.Label>Sign Up</Button.Label></Button>
139
+ </Link>
140
+ </View>
141
+ </Unauthenticated>
142
+ <AuthLoading>
143
+ <View className="mt-4 items-center">
144
+ <Spinner size="sm" />
145
+ </View>
146
+ </AuthLoading>
147
+ {{/if}}
148
+
149
+ {{#if (and (eq backend "convex") (eq auth "better-auth"))}}
150
+ {user ? (
151
+ <Surface variant="secondary" className="mb-4 p-4 rounded-lg">
152
+ <View className="flex-row items-center justify-between">
153
+ <View className="flex-1">
154
+ <Text className="text-foreground font-medium">{user.name}</Text>
155
+ <Text className="text-muted text-xs mt-0.5">{user.email}</Text>
156
+ </View>
157
+ <Button
158
+ variant="destructive"
159
+ size="sm"
160
+ onPress={() => {
161
+ authClient.signOut();
162
+ }}
163
+ >
164
+ Sign Out
165
+ </Button>
166
+ </View>
167
+ </Surface>
168
+ ) : null}
169
+ <Surface variant="secondary" className="p-4 rounded-lg">
170
+ <Text className="text-foreground font-medium mb-2">API Status</Text>
171
+ <View className="flex-row items-center gap-2">
172
+ <View className={`w-2 h-2 rounded-full ${healthCheck==="OK" ? "bg-success" : "bg-danger" }`} />
173
+ <Text className="text-muted text-xs">
174
+ {healthCheck === undefined
175
+ ? "Checking..."
176
+ : healthCheck === "OK"
177
+ ? "Connected to API"
178
+ : "API Disconnected"}
179
+ </Text>
180
+ </View>
181
+ </Surface>
182
+ {!user && (
183
+ <View className="mt-4 gap-4">
184
+ <SignIn />
185
+ <SignUp />
186
+ </View>
187
+ )}
188
+ {{/if}}
189
+ </Container>
190
+ );
191
+ }
@@ -0,0 +1,27 @@
1
+ import { Link, Stack } from "expo-router";
2
+ import { Button, Surface } from "heroui-native";
3
+ import { Text, View } from "react-native";
4
+
5
+ import { Container } from "@/components/container";
6
+
7
+ export default function NotFoundScreen() {
8
+ return (
9
+ <>
10
+ <Stack.Screen options=\{{ title: "Not Found" }} />
11
+ <Container>
12
+ <View className="flex-1 justify-center items-center p-4">
13
+ <Surface variant="secondary" className="items-center p-6 max-w-sm rounded-lg">
14
+ <Text className="text-4xl mb-3">🤔</Text>
15
+ <Text className="text-foreground font-medium text-lg mb-1">Page Not Found</Text>
16
+ <Text className="text-muted text-sm text-center mb-4">
17
+ The page you're looking for doesn't exist.
18
+ </Text>
19
+ <Link href="/" asChild>
20
+ <Button size="sm">Go Home</Button>
21
+ </Link>
22
+ </Surface>
23
+ </View>
24
+ </Container>
25
+ </>
26
+ );
27
+ }
@@ -0,0 +1,132 @@
1
+ {{#if (includes examples "ai")}}
2
+ import "@/polyfills";
3
+ {{/if}}
4
+
5
+ import "@/global.css";
6
+
7
+ {{#if (eq backend "convex")}}
8
+ {{#if (eq auth "better-auth")}}
9
+ import { ConvexReactClient } from "convex/react";
10
+ import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
11
+ import { authClient } from "@/lib/auth-client";
12
+ import { env } from "@{{projectName}}/env/native";
13
+ {{else}}
14
+ import { ConvexProvider, ConvexReactClient } from "convex/react";
15
+ import { env } from "@{{projectName}}/env/native";
16
+ {{/if}}
17
+
18
+ {{#if (eq auth "clerk")}}
19
+ import { ClerkProvider, useAuth } from "@clerk/clerk-expo";
20
+ import { ConvexProviderWithClerk } from "convex/react-clerk";
21
+ import { tokenCache } from "@clerk/clerk-expo/token-cache";
22
+ {{/if}}
23
+ {{else}}
24
+ {{#unless (eq api "none")}}
25
+ import { QueryClientProvider } from "@tanstack/react-query";
26
+ {{/unless}}
27
+ {{/if}}
28
+
29
+ import { Stack } from "expo-router";
30
+ import { HeroUINativeProvider } from "heroui-native";
31
+ import { GestureHandlerRootView } from "react-native-gesture-handler";
32
+ import { KeyboardProvider } from "react-native-keyboard-controller";
33
+ import { AppThemeProvider } from "@/contexts/app-theme-context";
34
+
35
+ {{#if (eq api "trpc")}}
36
+ import { queryClient } from "@/utils/trpc";
37
+ {{/if}}
38
+ {{#if (eq api "orpc")}}
39
+ import { queryClient } from "@/utils/orpc";
40
+ {{/if}}
41
+
42
+ export const unstable_settings = {
43
+ initialRouteName: "(drawer)",
44
+ };
45
+
46
+ {{#if (eq backend "convex")}}
47
+ const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
48
+ unsavedChangesWarning: false,
49
+ });
50
+ {{/if}}
51
+
52
+ function StackLayout() {
53
+ return (
54
+ <Stack screenOptions=\{{}}>
55
+ <Stack.Screen name="(drawer)" options=\{{ headerShown: false }} />
56
+ {{#if (eq auth "clerk")}}
57
+ <Stack.Screen name="(auth)" options=\{{ headerShown: false }} />
58
+ {{/if}}
59
+ <Stack.Screen name="modal" options=\{{ title: "Modal", presentation: "modal" }} />
60
+ </Stack>
61
+ );
62
+ }
63
+
64
+ export default function Layout() {
65
+ return (
66
+ {{#if (eq backend "convex")}}
67
+ {{#if (eq auth "clerk")}}
68
+ <ClerkProvider tokenCache={tokenCache} publishableKey={env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}>
69
+ <ConvexProviderWithClerk client={convex} useAuth={useAuth}>
70
+ <GestureHandlerRootView style=\{{ flex: 1 }}>
71
+ <KeyboardProvider>
72
+ <AppThemeProvider>
73
+ <HeroUINativeProvider>
74
+ <StackLayout />
75
+ </HeroUINativeProvider>
76
+ </AppThemeProvider>
77
+ </KeyboardProvider>
78
+ </GestureHandlerRootView>
79
+ </ConvexProviderWithClerk>
80
+ </ClerkProvider>
81
+ {{else if (eq auth "better-auth")}}
82
+ <ConvexBetterAuthProvider client={convex} authClient={authClient}>
83
+ <GestureHandlerRootView style=\{{ flex: 1 }}>
84
+ <KeyboardProvider>
85
+ <AppThemeProvider>
86
+ <HeroUINativeProvider>
87
+ <StackLayout />
88
+ </HeroUINativeProvider>
89
+ </AppThemeProvider>
90
+ </KeyboardProvider>
91
+ </GestureHandlerRootView>
92
+ </ConvexBetterAuthProvider>
93
+ {{else}}
94
+ <ConvexProvider client={convex}>
95
+ <GestureHandlerRootView style=\{{ flex: 1 }}>
96
+ <KeyboardProvider>
97
+ <AppThemeProvider>
98
+ <HeroUINativeProvider>
99
+ <StackLayout />
100
+ </HeroUINativeProvider>
101
+ </AppThemeProvider>
102
+ </KeyboardProvider>
103
+ </GestureHandlerRootView>
104
+ </ConvexProvider>
105
+ {{/if}}
106
+ {{else}}
107
+ {{#unless (eq api "none")}}
108
+ <QueryClientProvider client={queryClient}>
109
+ <GestureHandlerRootView style=\{{ flex: 1 }}>
110
+ <KeyboardProvider>
111
+ <AppThemeProvider>
112
+ <HeroUINativeProvider>
113
+ <StackLayout />
114
+ </HeroUINativeProvider>
115
+ </AppThemeProvider>
116
+ </KeyboardProvider>
117
+ </GestureHandlerRootView>
118
+ </QueryClientProvider>
119
+ {{else}}
120
+ <GestureHandlerRootView style=\{{ flex: 1 }}>
121
+ <KeyboardProvider>
122
+ <AppThemeProvider>
123
+ <HeroUINativeProvider>
124
+ <StackLayout />
125
+ </HeroUINativeProvider>
126
+ </AppThemeProvider>
127
+ </KeyboardProvider>
128
+ </GestureHandlerRootView>
129
+ {{/unless}}
130
+ {{/if}}
131
+ );
132
+ }
@@ -0,0 +1,37 @@
1
+ import { Ionicons } from "@expo/vector-icons";
2
+ import { router } from "expo-router";
3
+ import { Button, Surface, useThemeColor } from "heroui-native";
4
+ import { Text, View } from "react-native";
5
+
6
+ import { Container } from "@/components/container";
7
+
8
+ function Modal() {
9
+ const accentForegroundColor = useThemeColor("accent-foreground");
10
+
11
+ function handleClose() {
12
+ router.back();
13
+ }
14
+
15
+ return (
16
+ <Container>
17
+ <View className="flex-1 justify-center items-center p-4">
18
+ <Surface variant="secondary" className="p-5 w-full max-w-sm rounded-lg">
19
+ <View className="items-center">
20
+ <View className="w-12 h-12 bg-accent rounded-lg items-center justify-center mb-3">
21
+ <Ionicons name="checkmark" size={24} color={accentForegroundColor} />
22
+ </View>
23
+ <Text className="text-foreground font-medium text-lg mb-1">Modal Screen</Text>
24
+ <Text className="text-muted text-sm text-center mb-4">
25
+ This is an example modal screen for dialogs and confirmations.
26
+ </Text>
27
+ </View>
28
+ <Button onPress={handleClose} className="w-full" size="sm">
29
+ <Button.Label>Close</Button.Label>
30
+ </Button>
31
+ </Surface>
32
+ </View>
33
+ </Container>
34
+ );
35
+ }
36
+
37
+ export default Modal;
@@ -0,0 +1,19 @@
1
+ {
2
+ "expo": {
3
+ "scheme": "{{projectName}}",
4
+ "userInterfaceStyle": "automatic",
5
+ "orientation": "default",
6
+ "web": {
7
+ "bundler": "metro"
8
+ },
9
+ "name": "{{projectName}}",
10
+ "slug": "{{projectName}}",
11
+ "plugins": [
12
+ "expo-font"
13
+ ],
14
+ "experiments": {
15
+ "typedRoutes": true,
16
+ "reactCompiler": true
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,33 @@
1
+ import { cn } from "heroui-native";
2
+ import { type PropsWithChildren } from "react";
3
+ import { ScrollView, View, type ViewProps } from "react-native";
4
+ import Animated, { type AnimatedProps } from "react-native-reanimated";
5
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
6
+
7
+ const AnimatedView = Animated.createAnimatedComponent(View);
8
+
9
+ type Props = AnimatedProps<ViewProps> & {
10
+ className?: string;
11
+ };
12
+
13
+ export function Container({
14
+ children,
15
+ className,
16
+ ...props
17
+ }: PropsWithChildren<Props>) {
18
+ const insets = useSafeAreaInsets();
19
+
20
+ return (
21
+ <AnimatedView
22
+ className={cn("flex-1 bg-background", className)}
23
+ style=\{{
24
+ paddingBottom: insets.bottom,
25
+ }}
26
+ {...props}
27
+ >
28
+ <ScrollView contentContainerStyle=\{{ flexGrow: 1 }}>
29
+ {children}
30
+ </ScrollView>
31
+ </AnimatedView>
32
+ );
33
+ }
@@ -0,0 +1,35 @@
1
+ import { Ionicons } from '@expo/vector-icons';
2
+ import * as Haptics from 'expo-haptics';
3
+ import { Platform, Pressable } from 'react-native';
4
+ import Animated, { FadeOut, ZoomIn } from 'react-native-reanimated';
5
+ import { withUniwind } from 'uniwind';
6
+ import { useAppTheme } from '@/contexts/app-theme-context';
7
+
8
+ const StyledIonicons = withUniwind(Ionicons);
9
+
10
+ export function ThemeToggle() {
11
+ const { toggleTheme, isLight } = useAppTheme();
12
+
13
+ return (
14
+ <Pressable
15
+ onPress={() => {
16
+ if (Platform.OS === 'ios') {
17
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
18
+ }
19
+ toggleTheme();
20
+ }}
21
+ className="px-2.5"
22
+ >
23
+ {isLight ? (
24
+ <Animated.View key="moon" entering={ZoomIn} exiting={FadeOut}>
25
+ <StyledIonicons name="moon" size={20} className="text-foreground" />
26
+ </Animated.View>
27
+ ) : (
28
+ <Animated.View key="sun" entering={ZoomIn} exiting={FadeOut}>
29
+ <StyledIonicons name="sunny" size={20} className="text-foreground" />
30
+ </Animated.View>
31
+ )}
32
+ </Pressable>
33
+ );
34
+ }
35
+
@@ -0,0 +1,62 @@
1
+ import React, { createContext, useCallback, useContext, useMemo } from 'react';
2
+ import { Uniwind, useUniwind } from 'uniwind';
3
+
4
+ type ThemeName = 'light' | 'dark';
5
+
6
+ type AppThemeContextType = {
7
+ currentTheme: string;
8
+ isLight: boolean;
9
+ isDark: boolean;
10
+ setTheme: (theme: ThemeName) => void;
11
+ toggleTheme: () => void;
12
+ }
13
+
14
+ const AppThemeContext = createContext<AppThemeContextType | undefined>(
15
+ undefined
16
+ );
17
+
18
+ export const AppThemeProvider = ({ children }: { children: React.ReactNode }) => {
19
+ const { theme } = useUniwind();
20
+
21
+ const isLight = useMemo(() => {
22
+ return theme === 'light';
23
+ }, [theme]);
24
+
25
+ const isDark = useMemo(() => {
26
+ return theme === 'dark';
27
+ }, [theme]);
28
+
29
+ const setTheme = useCallback((newTheme: ThemeName) => {
30
+ Uniwind.setTheme(newTheme);
31
+ }, []);
32
+
33
+ const toggleTheme = useCallback(() => {
34
+ Uniwind.setTheme(theme === 'light' ? 'dark' : 'light');
35
+ }, [theme]);
36
+
37
+ const value = useMemo(
38
+ () => ({
39
+ currentTheme: theme,
40
+ isLight,
41
+ isDark,
42
+ setTheme,
43
+ toggleTheme,
44
+ }),
45
+ [theme, isLight, isDark, setTheme, toggleTheme]
46
+ );
47
+
48
+ return (
49
+ <AppThemeContext.Provider value={value}>
50
+ {children}
51
+ </AppThemeContext.Provider>
52
+ );
53
+ };
54
+
55
+ export function useAppTheme() {
56
+ const context = useContext(AppThemeContext);
57
+ if (!context) {
58
+ throw new Error('useAppTheme must be used within AppThemeProvider');
59
+ }
60
+ return context;
61
+ }
62
+
@@ -0,0 +1,5 @@
1
+ @import "tailwindcss";
2
+ @import "uniwind";
3
+ @import "heroui-native/styles";
4
+
5
+ @source './node_modules/heroui-native/lib';