virastack 0.0.1 → 1.0.1

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 (447) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +94 -18
  3. package/bin/virastack.js +7 -0
  4. package/package.json +43 -9
  5. package/src/commands/add.js +64 -0
  6. package/src/commands/init.js +286 -0
  7. package/src/i18n.js +231 -0
  8. package/src/index.js +64 -0
  9. package/src/utils/args.js +60 -0
  10. package/src/utils/copy-template.js +81 -0
  11. package/src/utils/exec.js +29 -0
  12. package/src/utils/git.js +38 -0
  13. package/src/utils/is-online.js +14 -0
  14. package/src/utils/package-info.js +12 -0
  15. package/src/utils/package-manager.js +33 -0
  16. package/src/utils/setup-env.js +25 -0
  17. package/src/utils/telemetry.js +86 -0
  18. package/src/utils/tools.js +48 -0
  19. package/src/utils/update-package-json.js +44 -0
  20. package/src/utils/update-readme.js +25 -0
  21. package/src/utils/validate-project-name.js +26 -0
  22. package/templates/nextjs/.changeset/README.md +8 -0
  23. package/templates/nextjs/.changeset/config.json +11 -0
  24. package/templates/nextjs/.env.example +6 -0
  25. package/templates/nextjs/.env.local +6 -0
  26. package/templates/nextjs/.eslintcache +1 -0
  27. package/templates/nextjs/.github/workflows/ci.yml +41 -0
  28. package/templates/nextjs/.husky/commit-msg +1 -0
  29. package/templates/nextjs/.husky/pre-commit +1 -0
  30. package/templates/nextjs/.husky/pre-push +1 -0
  31. package/templates/nextjs/.prettierignore +6 -0
  32. package/templates/nextjs/.prettierrc +42 -0
  33. package/templates/nextjs/.vscode/extensions.json +7 -0
  34. package/templates/nextjs/.vscode/settings.json +20 -0
  35. package/templates/nextjs/LICENSE +21 -0
  36. package/templates/nextjs/README.md +202 -0
  37. package/templates/nextjs/_gitignore +45 -0
  38. package/templates/nextjs/commitlint.config.js +6 -0
  39. package/templates/nextjs/eslint.config.mjs +27 -0
  40. package/templates/nextjs/knip.config.js +25 -0
  41. package/templates/nextjs/next-env.d.ts +6 -0
  42. package/templates/nextjs/next.config.ts +39 -0
  43. package/templates/nextjs/package.json +115 -0
  44. package/templates/nextjs/pnpm-lock.yaml +6467 -0
  45. package/templates/nextjs/pnpm-workspace.yaml +3 -0
  46. package/templates/nextjs/postcss.config.mjs +7 -0
  47. package/templates/nextjs/public/favicon.ico +0 -0
  48. package/templates/nextjs/public/llms.txt +96 -0
  49. package/templates/nextjs/public/logo.png +0 -0
  50. package/templates/nextjs/public/logo.webp +0 -0
  51. package/templates/nextjs/public/og.png +0 -0
  52. package/templates/nextjs/src/app/error.tsx +34 -0
  53. package/templates/nextjs/src/app/favicon.ico +0 -0
  54. package/templates/nextjs/src/app/global-error.tsx +32 -0
  55. package/templates/nextjs/src/app/layout.tsx +37 -0
  56. package/templates/nextjs/src/app/loading.tsx +12 -0
  57. package/templates/nextjs/src/app/manifest.ts +22 -0
  58. package/templates/nextjs/src/app/not-found.tsx +18 -0
  59. package/templates/nextjs/src/app/page.tsx +5 -0
  60. package/templates/nextjs/src/app/robots.ts +13 -0
  61. package/templates/nextjs/src/app/sitemap.ts +14 -0
  62. package/templates/nextjs/src/components/shared/ThemeToggle.tsx +30 -0
  63. package/templates/nextjs/src/components/ui/avatar.tsx +54 -0
  64. package/templates/nextjs/src/components/ui/button.tsx +46 -0
  65. package/templates/nextjs/src/components/ui/dialog.tsx +107 -0
  66. package/templates/nextjs/src/components/ui/field.tsx +24 -0
  67. package/templates/nextjs/src/components/ui/index.ts +27 -0
  68. package/templates/nextjs/src/components/ui/input.tsx +23 -0
  69. package/templates/nextjs/src/components/ui/label.tsx +17 -0
  70. package/templates/nextjs/src/components/ui/skeleton.tsx +13 -0
  71. package/templates/nextjs/src/components/ui/table.tsx +94 -0
  72. package/templates/nextjs/src/components/ui/tabs.tsx +46 -0
  73. package/templates/nextjs/src/config/seo.config.ts +37 -0
  74. package/templates/nextjs/src/config/site.config.ts +15 -0
  75. package/templates/nextjs/src/constants/index.ts +5 -0
  76. package/templates/nextjs/src/env.ts +41 -0
  77. package/templates/nextjs/src/features/landing/api/get-users.api.ts +7 -0
  78. package/templates/nextjs/src/features/landing/api/index.ts +2 -0
  79. package/templates/nextjs/src/features/landing/api/query-keys.ts +7 -0
  80. package/templates/nextjs/src/features/landing/components/CartDemo.tsx +66 -0
  81. package/templates/nextjs/src/features/landing/components/Features.tsx +39 -0
  82. package/templates/nextjs/src/features/landing/components/Hero.tsx +65 -0
  83. package/templates/nextjs/src/features/landing/components/LandingPage.tsx +17 -0
  84. package/templates/nextjs/src/features/landing/components/ProjectFormDemo.tsx +62 -0
  85. package/templates/nextjs/src/features/landing/components/Reveal.tsx +83 -0
  86. package/templates/nextjs/src/features/landing/components/Showcase.tsx +66 -0
  87. package/templates/nextjs/src/features/landing/components/UsersDemo.tsx +188 -0
  88. package/templates/nextjs/src/features/landing/data/features.data.tsx +47 -0
  89. package/templates/nextjs/src/features/landing/data/index.ts +1 -0
  90. package/templates/nextjs/src/features/landing/helpers/get-initials.ts +15 -0
  91. package/templates/nextjs/src/features/landing/helpers/index.ts +7 -0
  92. package/templates/nextjs/src/features/landing/helpers/motion.ts +21 -0
  93. package/templates/nextjs/src/features/landing/hooks/index.ts +1 -0
  94. package/templates/nextjs/src/features/landing/hooks/use-users.ts +16 -0
  95. package/templates/nextjs/src/features/landing/icons/index.ts +6 -0
  96. package/templates/nextjs/src/features/landing/icons/nextjs.tsx +68 -0
  97. package/templates/nextjs/src/features/landing/icons/react-hook-form.tsx +18 -0
  98. package/templates/nextjs/src/features/landing/icons/react.tsx +20 -0
  99. package/templates/nextjs/src/features/landing/icons/tailwind.tsx +14 -0
  100. package/templates/nextjs/src/features/landing/icons/tanstack.tsx +321 -0
  101. package/templates/nextjs/src/features/landing/icons/typescript.tsx +16 -0
  102. package/templates/nextjs/src/features/landing/index.ts +1 -0
  103. package/templates/nextjs/src/features/landing/schemas/index.ts +1 -0
  104. package/templates/nextjs/src/features/landing/schemas/project.schema.ts +7 -0
  105. package/templates/nextjs/src/features/landing/stores/counter.store.ts +18 -0
  106. package/templates/nextjs/src/features/landing/stores/index.ts +1 -0
  107. package/templates/nextjs/src/features/landing/types/index.ts +1 -0
  108. package/templates/nextjs/src/features/landing/types/user.types.ts +9 -0
  109. package/templates/nextjs/src/helpers/format-date.ts +13 -0
  110. package/templates/nextjs/src/helpers/index.ts +1 -0
  111. package/templates/nextjs/src/hooks/index.ts +5 -0
  112. package/templates/nextjs/src/lib/api.ts +97 -0
  113. package/templates/nextjs/src/lib/query-client.ts +18 -0
  114. package/templates/nextjs/src/lib/utils.ts +12 -0
  115. package/templates/nextjs/src/providers/Providers.tsx +15 -0
  116. package/templates/nextjs/src/providers/QueryProvider.tsx +19 -0
  117. package/templates/nextjs/src/providers/ThemeProvider.tsx +9 -0
  118. package/templates/nextjs/src/providers/index.ts +1 -0
  119. package/templates/nextjs/src/proxy.ts +6 -0
  120. package/templates/nextjs/src/schemas/index.ts +5 -0
  121. package/templates/nextjs/src/stores/index.ts +5 -0
  122. package/templates/nextjs/src/styles/tailwind.css +122 -0
  123. package/templates/nextjs/src/types/site-config.types.ts +10 -0
  124. package/templates/nextjs/tsconfig.json +45 -0
  125. package/templates/nextjs/tsconfig.tsbuildinfo +1 -0
  126. package/templates/tanstack/.changeset/README.md +8 -0
  127. package/templates/tanstack/.changeset/config.json +11 -0
  128. package/templates/tanstack/.env.example +6 -0
  129. package/templates/tanstack/.env.local +6 -0
  130. package/templates/tanstack/.eslintcache +1 -0
  131. package/templates/tanstack/.github/workflows/ci.yml +41 -0
  132. package/templates/tanstack/.husky/commit-msg +1 -0
  133. package/templates/tanstack/.husky/pre-commit +1 -0
  134. package/templates/tanstack/.husky/pre-push +1 -0
  135. package/templates/tanstack/.prettierignore +7 -0
  136. package/templates/tanstack/.prettierrc +41 -0
  137. package/templates/tanstack/.vscode/extensions.json +7 -0
  138. package/templates/tanstack/.vscode/settings.json +22 -0
  139. package/templates/tanstack/LICENSE +21 -0
  140. package/templates/tanstack/README.md +204 -0
  141. package/templates/tanstack/_gitignore +52 -0
  142. package/templates/tanstack/commitlint.config.js +6 -0
  143. package/templates/tanstack/eslint.config.js +28 -0
  144. package/templates/tanstack/knip.config.js +22 -0
  145. package/templates/tanstack/package.json +130 -0
  146. package/templates/tanstack/pnpm-lock.yaml +5835 -0
  147. package/templates/tanstack/pnpm-workspace.yaml +3 -0
  148. package/templates/tanstack/public/favicon.ico +0 -0
  149. package/templates/tanstack/public/llms.txt +86 -0
  150. package/templates/tanstack/public/logo.png +0 -0
  151. package/templates/tanstack/public/logo.webp +0 -0
  152. package/templates/tanstack/public/og.png +0 -0
  153. package/templates/tanstack/src/components/shared/DefaultCatchBoundary.tsx +36 -0
  154. package/templates/tanstack/src/components/shared/NotFound.tsx +18 -0
  155. package/templates/tanstack/src/components/shared/Pending.tsx +13 -0
  156. package/templates/tanstack/src/components/shared/ThemeToggle.tsx +31 -0
  157. package/templates/tanstack/src/components/ui/avatar.tsx +52 -0
  158. package/templates/tanstack/src/components/ui/button.tsx +47 -0
  159. package/templates/tanstack/src/components/ui/dialog.tsx +107 -0
  160. package/templates/tanstack/src/components/ui/field.tsx +24 -0
  161. package/templates/tanstack/src/components/ui/index.ts +27 -0
  162. package/templates/tanstack/src/components/ui/input.tsx +23 -0
  163. package/templates/tanstack/src/components/ui/label.tsx +17 -0
  164. package/templates/tanstack/src/components/ui/skeleton.tsx +13 -0
  165. package/templates/tanstack/src/components/ui/table.tsx +94 -0
  166. package/templates/tanstack/src/components/ui/tabs.tsx +46 -0
  167. package/templates/tanstack/src/config/seo.config.ts +52 -0
  168. package/templates/tanstack/src/config/site.config.ts +15 -0
  169. package/templates/tanstack/src/constants/index.ts +5 -0
  170. package/templates/tanstack/src/env.ts +47 -0
  171. package/templates/tanstack/src/features/landing/api/get-users.api.ts +7 -0
  172. package/templates/tanstack/src/features/landing/api/index.ts +2 -0
  173. package/templates/tanstack/src/features/landing/api/query-keys.ts +7 -0
  174. package/templates/tanstack/src/features/landing/components/CartDemo.tsx +66 -0
  175. package/templates/tanstack/src/features/landing/components/Features.tsx +39 -0
  176. package/templates/tanstack/src/features/landing/components/Hero.tsx +63 -0
  177. package/templates/tanstack/src/features/landing/components/LandingPage.tsx +17 -0
  178. package/templates/tanstack/src/features/landing/components/ProjectFormDemo.tsx +63 -0
  179. package/templates/tanstack/src/features/landing/components/Reveal.tsx +83 -0
  180. package/templates/tanstack/src/features/landing/components/Showcase.tsx +66 -0
  181. package/templates/tanstack/src/features/landing/components/UsersDemo.tsx +191 -0
  182. package/templates/tanstack/src/features/landing/data/features.data.tsx +45 -0
  183. package/templates/tanstack/src/features/landing/data/index.ts +1 -0
  184. package/templates/tanstack/src/features/landing/helpers/get-initials.ts +15 -0
  185. package/templates/tanstack/src/features/landing/helpers/index.ts +7 -0
  186. package/templates/tanstack/src/features/landing/helpers/motion.ts +21 -0
  187. package/templates/tanstack/src/features/landing/hooks/index.ts +1 -0
  188. package/templates/tanstack/src/features/landing/hooks/use-users.ts +19 -0
  189. package/templates/tanstack/src/features/landing/icons/index.ts +5 -0
  190. package/templates/tanstack/src/features/landing/icons/react-hook-form.tsx +18 -0
  191. package/templates/tanstack/src/features/landing/icons/react.tsx +20 -0
  192. package/templates/tanstack/src/features/landing/icons/tailwind.tsx +14 -0
  193. package/templates/tanstack/src/features/landing/icons/tanstack.tsx +321 -0
  194. package/templates/tanstack/src/features/landing/icons/typescript.tsx +16 -0
  195. package/templates/tanstack/src/features/landing/index.ts +1 -0
  196. package/templates/tanstack/src/features/landing/schemas/index.ts +1 -0
  197. package/templates/tanstack/src/features/landing/schemas/project.schema.ts +7 -0
  198. package/templates/tanstack/src/features/landing/stores/counter.store.ts +18 -0
  199. package/templates/tanstack/src/features/landing/stores/index.ts +1 -0
  200. package/templates/tanstack/src/features/landing/types/index.ts +1 -0
  201. package/templates/tanstack/src/features/landing/types/user.types.ts +9 -0
  202. package/templates/tanstack/src/helpers/format-date.ts +13 -0
  203. package/templates/tanstack/src/helpers/index.ts +1 -0
  204. package/templates/tanstack/src/hooks/index.ts +5 -0
  205. package/templates/tanstack/src/lib/api.ts +97 -0
  206. package/templates/tanstack/src/lib/query-client.ts +18 -0
  207. package/templates/tanstack/src/lib/utils.ts +13 -0
  208. package/templates/tanstack/src/providers/Providers.tsx +12 -0
  209. package/templates/tanstack/src/providers/ThemeProvider.tsx +98 -0
  210. package/templates/tanstack/src/providers/devtools.tsx +6 -0
  211. package/templates/tanstack/src/providers/index.ts +1 -0
  212. package/templates/tanstack/src/providers/root-provider.ts +9 -0
  213. package/templates/tanstack/src/routeTree.gen.ts +123 -0
  214. package/templates/tanstack/src/router.tsx +27 -0
  215. package/templates/tanstack/src/routes/__root.tsx +78 -0
  216. package/templates/tanstack/src/routes/index.tsx +13 -0
  217. package/templates/tanstack/src/routes/robots[.]txt.ts +21 -0
  218. package/templates/tanstack/src/routes/site[.]webmanifest.ts +32 -0
  219. package/templates/tanstack/src/routes/sitemap[.]xml.ts +27 -0
  220. package/templates/tanstack/src/schemas/index.ts +5 -0
  221. package/templates/tanstack/src/start.ts +20 -0
  222. package/templates/tanstack/src/stores/index.ts +5 -0
  223. package/templates/tanstack/src/styles/tailwind.css +123 -0
  224. package/templates/tanstack/src/types/site-config.types.ts +10 -0
  225. package/templates/tanstack/tsconfig.json +25 -0
  226. package/templates/tanstack/tsr.config.json +3 -0
  227. package/templates/tanstack/vite.config.ts +12 -0
  228. package/templates-i18n/nextjs/.changeset/README.md +8 -0
  229. package/templates-i18n/nextjs/.changeset/config.json +11 -0
  230. package/templates-i18n/nextjs/.env.example +6 -0
  231. package/templates-i18n/nextjs/.eslintcache +1 -0
  232. package/templates-i18n/nextjs/.github/workflows/ci.yml +41 -0
  233. package/templates-i18n/nextjs/.husky/commit-msg +1 -0
  234. package/templates-i18n/nextjs/.husky/pre-commit +1 -0
  235. package/templates-i18n/nextjs/.husky/pre-push +1 -0
  236. package/templates-i18n/nextjs/.prettierignore +6 -0
  237. package/templates-i18n/nextjs/.prettierrc +42 -0
  238. package/templates-i18n/nextjs/.vscode/extensions.json +7 -0
  239. package/templates-i18n/nextjs/.vscode/settings.json +20 -0
  240. package/templates-i18n/nextjs/LICENSE +21 -0
  241. package/templates-i18n/nextjs/README.md +202 -0
  242. package/templates-i18n/nextjs/_gitignore +45 -0
  243. package/templates-i18n/nextjs/commitlint.config.js +6 -0
  244. package/templates-i18n/nextjs/eslint.config.mjs +27 -0
  245. package/templates-i18n/nextjs/knip.config.js +29 -0
  246. package/templates-i18n/nextjs/next-env.d.ts +6 -0
  247. package/templates-i18n/nextjs/next.config.ts +42 -0
  248. package/templates-i18n/nextjs/package.json +117 -0
  249. package/templates-i18n/nextjs/pnpm-lock.yaml +6854 -0
  250. package/templates-i18n/nextjs/pnpm-workspace.yaml +3 -0
  251. package/templates-i18n/nextjs/postcss.config.mjs +7 -0
  252. package/templates-i18n/nextjs/public/favicon.ico +0 -0
  253. package/templates-i18n/nextjs/public/llms.txt +96 -0
  254. package/templates-i18n/nextjs/public/logo.png +0 -0
  255. package/templates-i18n/nextjs/public/logo.webp +0 -0
  256. package/templates-i18n/nextjs/public/og.png +0 -0
  257. package/templates-i18n/nextjs/src/app/[locale]/error.tsx +34 -0
  258. package/templates-i18n/nextjs/src/app/[locale]/layout.tsx +60 -0
  259. package/templates-i18n/nextjs/src/app/[locale]/loading.tsx +12 -0
  260. package/templates-i18n/nextjs/src/app/[locale]/not-found.tsx +18 -0
  261. package/templates-i18n/nextjs/src/app/[locale]/page.tsx +10 -0
  262. package/templates-i18n/nextjs/src/app/favicon.ico +0 -0
  263. package/templates-i18n/nextjs/src/app/global-error.tsx +32 -0
  264. package/templates-i18n/nextjs/src/app/manifest.ts +22 -0
  265. package/templates-i18n/nextjs/src/app/robots.ts +13 -0
  266. package/templates-i18n/nextjs/src/app/sitemap.ts +14 -0
  267. package/templates-i18n/nextjs/src/components/shared/LanguageSwitcher.tsx +48 -0
  268. package/templates-i18n/nextjs/src/components/shared/ThemeToggle.tsx +30 -0
  269. package/templates-i18n/nextjs/src/components/ui/avatar.tsx +54 -0
  270. package/templates-i18n/nextjs/src/components/ui/button.tsx +46 -0
  271. package/templates-i18n/nextjs/src/components/ui/dialog.tsx +107 -0
  272. package/templates-i18n/nextjs/src/components/ui/field.tsx +24 -0
  273. package/templates-i18n/nextjs/src/components/ui/index.ts +27 -0
  274. package/templates-i18n/nextjs/src/components/ui/input.tsx +23 -0
  275. package/templates-i18n/nextjs/src/components/ui/label.tsx +17 -0
  276. package/templates-i18n/nextjs/src/components/ui/skeleton.tsx +13 -0
  277. package/templates-i18n/nextjs/src/components/ui/table.tsx +94 -0
  278. package/templates-i18n/nextjs/src/components/ui/tabs.tsx +46 -0
  279. package/templates-i18n/nextjs/src/config/seo.config.ts +37 -0
  280. package/templates-i18n/nextjs/src/config/site.config.ts +15 -0
  281. package/templates-i18n/nextjs/src/constants/index.ts +5 -0
  282. package/templates-i18n/nextjs/src/env.ts +41 -0
  283. package/templates-i18n/nextjs/src/features/landing/api/get-users.api.ts +7 -0
  284. package/templates-i18n/nextjs/src/features/landing/api/index.ts +2 -0
  285. package/templates-i18n/nextjs/src/features/landing/api/query-keys.ts +7 -0
  286. package/templates-i18n/nextjs/src/features/landing/components/CartDemo.tsx +68 -0
  287. package/templates-i18n/nextjs/src/features/landing/components/Features.tsx +84 -0
  288. package/templates-i18n/nextjs/src/features/landing/components/Hero.tsx +76 -0
  289. package/templates-i18n/nextjs/src/features/landing/components/LandingPage.tsx +17 -0
  290. package/templates-i18n/nextjs/src/features/landing/components/ProjectFormDemo.tsx +64 -0
  291. package/templates-i18n/nextjs/src/features/landing/components/Reveal.tsx +83 -0
  292. package/templates-i18n/nextjs/src/features/landing/components/Showcase.tsx +83 -0
  293. package/templates-i18n/nextjs/src/features/landing/components/UsersDemo.tsx +191 -0
  294. package/templates-i18n/nextjs/src/features/landing/data/features.data.tsx +47 -0
  295. package/templates-i18n/nextjs/src/features/landing/data/index.ts +1 -0
  296. package/templates-i18n/nextjs/src/features/landing/helpers/get-initials.ts +15 -0
  297. package/templates-i18n/nextjs/src/features/landing/helpers/index.ts +7 -0
  298. package/templates-i18n/nextjs/src/features/landing/helpers/motion.ts +21 -0
  299. package/templates-i18n/nextjs/src/features/landing/hooks/index.ts +1 -0
  300. package/templates-i18n/nextjs/src/features/landing/hooks/use-users.ts +16 -0
  301. package/templates-i18n/nextjs/src/features/landing/icons/index.ts +6 -0
  302. package/templates-i18n/nextjs/src/features/landing/icons/nextjs.tsx +68 -0
  303. package/templates-i18n/nextjs/src/features/landing/icons/react-hook-form.tsx +18 -0
  304. package/templates-i18n/nextjs/src/features/landing/icons/react.tsx +20 -0
  305. package/templates-i18n/nextjs/src/features/landing/icons/tailwind.tsx +14 -0
  306. package/templates-i18n/nextjs/src/features/landing/icons/tanstack.tsx +321 -0
  307. package/templates-i18n/nextjs/src/features/landing/icons/typescript.tsx +16 -0
  308. package/templates-i18n/nextjs/src/features/landing/index.ts +1 -0
  309. package/templates-i18n/nextjs/src/features/landing/schemas/index.ts +1 -0
  310. package/templates-i18n/nextjs/src/features/landing/schemas/project.schema.ts +9 -0
  311. package/templates-i18n/nextjs/src/features/landing/stores/counter.store.ts +18 -0
  312. package/templates-i18n/nextjs/src/features/landing/stores/index.ts +1 -0
  313. package/templates-i18n/nextjs/src/features/landing/types/index.ts +1 -0
  314. package/templates-i18n/nextjs/src/features/landing/types/user.types.ts +9 -0
  315. package/templates-i18n/nextjs/src/helpers/format-date.ts +13 -0
  316. package/templates-i18n/nextjs/src/helpers/index.ts +1 -0
  317. package/templates-i18n/nextjs/src/hooks/index.ts +5 -0
  318. package/templates-i18n/nextjs/src/i18n/request.ts +16 -0
  319. package/templates-i18n/nextjs/src/i18n/routing.ts +11 -0
  320. package/templates-i18n/nextjs/src/lib/api.ts +97 -0
  321. package/templates-i18n/nextjs/src/lib/query-client.ts +18 -0
  322. package/templates-i18n/nextjs/src/lib/utils.ts +12 -0
  323. package/templates-i18n/nextjs/src/messages/en.json +55 -0
  324. package/templates-i18n/nextjs/src/messages/tr.json +55 -0
  325. package/templates-i18n/nextjs/src/providers/Providers.tsx +15 -0
  326. package/templates-i18n/nextjs/src/providers/QueryProvider.tsx +19 -0
  327. package/templates-i18n/nextjs/src/providers/ThemeProvider.tsx +9 -0
  328. package/templates-i18n/nextjs/src/providers/index.ts +1 -0
  329. package/templates-i18n/nextjs/src/proxy.ts +16 -0
  330. package/templates-i18n/nextjs/src/schemas/index.ts +5 -0
  331. package/templates-i18n/nextjs/src/stores/index.ts +5 -0
  332. package/templates-i18n/nextjs/src/styles/tailwind.css +122 -0
  333. package/templates-i18n/nextjs/src/types/site-config.types.ts +10 -0
  334. package/templates-i18n/nextjs/tsconfig.json +45 -0
  335. package/templates-i18n/nextjs/tsconfig.tsbuildinfo +1 -0
  336. package/templates-i18n/tanstack/.changeset/README.md +8 -0
  337. package/templates-i18n/tanstack/.changeset/config.json +11 -0
  338. package/templates-i18n/tanstack/.env.example +6 -0
  339. package/templates-i18n/tanstack/.eslintcache +1 -0
  340. package/templates-i18n/tanstack/.github/workflows/ci.yml +41 -0
  341. package/templates-i18n/tanstack/.husky/commit-msg +1 -0
  342. package/templates-i18n/tanstack/.husky/pre-commit +1 -0
  343. package/templates-i18n/tanstack/.husky/pre-push +1 -0
  344. package/templates-i18n/tanstack/.prettierignore +7 -0
  345. package/templates-i18n/tanstack/.prettierrc +41 -0
  346. package/templates-i18n/tanstack/.vscode/extensions.json +7 -0
  347. package/templates-i18n/tanstack/.vscode/settings.json +22 -0
  348. package/templates-i18n/tanstack/LICENSE +21 -0
  349. package/templates-i18n/tanstack/README.md +204 -0
  350. package/templates-i18n/tanstack/_gitignore +52 -0
  351. package/templates-i18n/tanstack/commitlint.config.js +6 -0
  352. package/templates-i18n/tanstack/eslint.config.js +29 -0
  353. package/templates-i18n/tanstack/knip.config.js +26 -0
  354. package/templates-i18n/tanstack/messages/en.json +65 -0
  355. package/templates-i18n/tanstack/messages/tr.json +65 -0
  356. package/templates-i18n/tanstack/package.json +132 -0
  357. package/templates-i18n/tanstack/pnpm-lock.yaml +5998 -0
  358. package/templates-i18n/tanstack/pnpm-workspace.yaml +3 -0
  359. package/templates-i18n/tanstack/project.inlang/README.md +157 -0
  360. package/templates-i18n/tanstack/project.inlang/settings.json +9 -0
  361. package/templates-i18n/tanstack/public/favicon.ico +0 -0
  362. package/templates-i18n/tanstack/public/llms.txt +86 -0
  363. package/templates-i18n/tanstack/public/logo.png +0 -0
  364. package/templates-i18n/tanstack/public/logo.webp +0 -0
  365. package/templates-i18n/tanstack/public/og.png +0 -0
  366. package/templates-i18n/tanstack/src/components/shared/DefaultCatchBoundary.tsx +36 -0
  367. package/templates-i18n/tanstack/src/components/shared/LanguageSwitcher.tsx +57 -0
  368. package/templates-i18n/tanstack/src/components/shared/NotFound.tsx +18 -0
  369. package/templates-i18n/tanstack/src/components/shared/Pending.tsx +13 -0
  370. package/templates-i18n/tanstack/src/components/shared/ThemeToggle.tsx +31 -0
  371. package/templates-i18n/tanstack/src/components/ui/avatar.tsx +52 -0
  372. package/templates-i18n/tanstack/src/components/ui/button.tsx +47 -0
  373. package/templates-i18n/tanstack/src/components/ui/dialog.tsx +107 -0
  374. package/templates-i18n/tanstack/src/components/ui/field.tsx +24 -0
  375. package/templates-i18n/tanstack/src/components/ui/index.ts +27 -0
  376. package/templates-i18n/tanstack/src/components/ui/input.tsx +23 -0
  377. package/templates-i18n/tanstack/src/components/ui/label.tsx +17 -0
  378. package/templates-i18n/tanstack/src/components/ui/skeleton.tsx +13 -0
  379. package/templates-i18n/tanstack/src/components/ui/table.tsx +94 -0
  380. package/templates-i18n/tanstack/src/components/ui/tabs.tsx +46 -0
  381. package/templates-i18n/tanstack/src/config/seo.config.ts +52 -0
  382. package/templates-i18n/tanstack/src/config/site.config.ts +15 -0
  383. package/templates-i18n/tanstack/src/constants/index.ts +5 -0
  384. package/templates-i18n/tanstack/src/env.ts +47 -0
  385. package/templates-i18n/tanstack/src/features/landing/api/get-users.api.ts +7 -0
  386. package/templates-i18n/tanstack/src/features/landing/api/index.ts +2 -0
  387. package/templates-i18n/tanstack/src/features/landing/api/query-keys.ts +7 -0
  388. package/templates-i18n/tanstack/src/features/landing/components/CartDemo.tsx +67 -0
  389. package/templates-i18n/tanstack/src/features/landing/components/Features.tsx +79 -0
  390. package/templates-i18n/tanstack/src/features/landing/components/Hero.tsx +68 -0
  391. package/templates-i18n/tanstack/src/features/landing/components/LandingPage.tsx +17 -0
  392. package/templates-i18n/tanstack/src/features/landing/components/ProjectFormDemo.tsx +64 -0
  393. package/templates-i18n/tanstack/src/features/landing/components/Reveal.tsx +83 -0
  394. package/templates-i18n/tanstack/src/features/landing/components/Showcase.tsx +81 -0
  395. package/templates-i18n/tanstack/src/features/landing/components/UsersDemo.tsx +191 -0
  396. package/templates-i18n/tanstack/src/features/landing/data/features.data.tsx +45 -0
  397. package/templates-i18n/tanstack/src/features/landing/data/index.ts +1 -0
  398. package/templates-i18n/tanstack/src/features/landing/helpers/get-initials.ts +15 -0
  399. package/templates-i18n/tanstack/src/features/landing/helpers/index.ts +7 -0
  400. package/templates-i18n/tanstack/src/features/landing/helpers/motion.ts +21 -0
  401. package/templates-i18n/tanstack/src/features/landing/hooks/index.ts +1 -0
  402. package/templates-i18n/tanstack/src/features/landing/hooks/use-users.ts +19 -0
  403. package/templates-i18n/tanstack/src/features/landing/icons/index.ts +5 -0
  404. package/templates-i18n/tanstack/src/features/landing/icons/react-hook-form.tsx +18 -0
  405. package/templates-i18n/tanstack/src/features/landing/icons/react.tsx +20 -0
  406. package/templates-i18n/tanstack/src/features/landing/icons/tailwind.tsx +14 -0
  407. package/templates-i18n/tanstack/src/features/landing/icons/tanstack.tsx +321 -0
  408. package/templates-i18n/tanstack/src/features/landing/icons/typescript.tsx +16 -0
  409. package/templates-i18n/tanstack/src/features/landing/index.ts +1 -0
  410. package/templates-i18n/tanstack/src/features/landing/schemas/index.ts +1 -0
  411. package/templates-i18n/tanstack/src/features/landing/schemas/project.schema.ts +10 -0
  412. package/templates-i18n/tanstack/src/features/landing/stores/counter.store.ts +18 -0
  413. package/templates-i18n/tanstack/src/features/landing/stores/index.ts +1 -0
  414. package/templates-i18n/tanstack/src/features/landing/types/index.ts +1 -0
  415. package/templates-i18n/tanstack/src/features/landing/types/user.types.ts +9 -0
  416. package/templates-i18n/tanstack/src/helpers/format-date.ts +13 -0
  417. package/templates-i18n/tanstack/src/helpers/index.ts +1 -0
  418. package/templates-i18n/tanstack/src/hooks/index.ts +5 -0
  419. package/templates-i18n/tanstack/src/lib/api.ts +97 -0
  420. package/templates-i18n/tanstack/src/lib/query-client.ts +18 -0
  421. package/templates-i18n/tanstack/src/lib/utils.ts +13 -0
  422. package/templates-i18n/tanstack/src/paraglide/README.md +162 -0
  423. package/templates-i18n/tanstack/src/providers/Providers.tsx +12 -0
  424. package/templates-i18n/tanstack/src/providers/ThemeProvider.tsx +98 -0
  425. package/templates-i18n/tanstack/src/providers/devtools.tsx +6 -0
  426. package/templates-i18n/tanstack/src/providers/index.ts +1 -0
  427. package/templates-i18n/tanstack/src/providers/root-provider.ts +9 -0
  428. package/templates-i18n/tanstack/src/routeTree.gen.ts +179 -0
  429. package/templates-i18n/tanstack/src/router.tsx +27 -0
  430. package/templates-i18n/tanstack/src/routes/$lang/index.tsx +13 -0
  431. package/templates-i18n/tanstack/src/routes/$lang.tsx +22 -0
  432. package/templates-i18n/tanstack/src/routes/__root.tsx +80 -0
  433. package/templates-i18n/tanstack/src/routes/index.tsx +13 -0
  434. package/templates-i18n/tanstack/src/routes/robots[.]txt.ts +21 -0
  435. package/templates-i18n/tanstack/src/routes/site[.]webmanifest.ts +32 -0
  436. package/templates-i18n/tanstack/src/routes/sitemap[.]xml.ts +27 -0
  437. package/templates-i18n/tanstack/src/schemas/index.ts +5 -0
  438. package/templates-i18n/tanstack/src/server.ts +10 -0
  439. package/templates-i18n/tanstack/src/start.ts +20 -0
  440. package/templates-i18n/tanstack/src/stores/index.ts +5 -0
  441. package/templates-i18n/tanstack/src/styles/tailwind.css +123 -0
  442. package/templates-i18n/tanstack/src/types/site-config.types.ts +10 -0
  443. package/templates-i18n/tanstack/tsconfig.json +26 -0
  444. package/templates-i18n/tanstack/tsr.config.json +3 -0
  445. package/templates-i18n/tanstack/vite.config.ts +31 -0
  446. package/index.js +0 -3
  447. package/public/start.jpg +0 -0
@@ -0,0 +1,3 @@
1
+ allowBuilds:
2
+ esbuild: true
3
+ lightningcss: true
@@ -0,0 +1,157 @@
1
+ ## What is this folder?
2
+
3
+ This is an [unpacked (git-friendly)](https://inlang.com/docs/unpacked-project) inlang project.
4
+
5
+ ## At a glance
6
+
7
+ Purpose:
8
+
9
+ - This folder is the Git-friendly representation of an `.inlang` project.
10
+ - The canonical `.inlang` format is a single binary file; this directory is the unpacked version for Git.
11
+ - This folder stores project configuration and plugin cache data.
12
+ - Translation files live outside this folder and are referenced from `settings.json`.
13
+
14
+ Safe to edit:
15
+
16
+ - `settings.json`
17
+
18
+ Do not edit:
19
+
20
+ - `cache/`
21
+ - `.gitignore`
22
+
23
+ Key files:
24
+
25
+ - `settings.json` — locales, plugins, file patterns
26
+ - `cache/` — plugin caches (safe to delete)
27
+ - `.gitignore` — generated
28
+ - `README.md` — generated, explains this folder
29
+ - `.meta.json` — generated SDK metadata
30
+
31
+ ```
32
+ *.inlang/
33
+ ├── settings.json # Locales, plugins, and file patterns; kept in Git
34
+ ├── .gitignore # Ignores everything except settings.json
35
+ ├── README.md # Generated, explains this folder
36
+ ├── .meta.json # Generated SDK metadata
37
+ └── cache/ # Plugin caches, usually cache/plugins/
38
+ ```
39
+
40
+ Translation files (like `messages/en.json`) live **outside** this folder and are referenced via plugins in `settings.json`.
41
+
42
+ ## What is inlang?
43
+
44
+ [Inlang](https://inlang.com) is an open project file format for localization. An `.inlang` project is canonically a single binary file: a SQLite database with version control via [lix](https://lix.dev). Like `.sqlite` for relational data, `.inlang` packages localization data into one file that tools can share.
45
+
46
+ For Git repositories, that binary file can be unpacked into a directory of plain files. The packed file is the canonical format; this directory is the Git-friendly representation.
47
+
48
+ Use inlang when multiple tools, teams, automations, or agents need to use the same localization data. The `@inlang/sdk` is the reference implementation for reading and writing `.inlang` projects.
49
+
50
+ `.inlang` is the canonical project format. Plugins import and export external translation files for compatibility with existing runtimes and workflows. Messages, variants, and locale data live in the `.inlang` database; translation files such as `messages/en.json` live outside this folder and are connected through plugins. Version control via lix adds file-level history, merging, and change proposals to `.inlang` projects.
51
+
52
+ It provides:
53
+
54
+ - **CRUD API** — Read and write translations programmatically via SQL
55
+ - **Plugin system** — Import/export external translation files (JSON, XLIFF, etc.)
56
+ - **Version control** — Version control via [lix](https://lix.dev)
57
+
58
+ Core data model:
59
+
60
+ - **Bundle** — one translatable unit across locales
61
+ - **Message** — locale-specific translation for a bundle
62
+ - **Variant** — text pattern plus selector matches
63
+
64
+ ```
65
+ ┌──────────┐ ┌───────────┐ ┌────────────┐
66
+ │ i18n lib │ │Translation│ │ CI/CD │
67
+ │ │ │ Tool │ │ Automation │
68
+ └────┬─────┘ └─────┬─────┘ └─────┬──────┘
69
+ │ │ │
70
+ └─────────┐ │ ┌──────────┘
71
+ ▼ ▼ ▼
72
+ ┌──────────────────────────────────┐
73
+ │ *.inlang file │
74
+ └──────────────────────────────────┘
75
+ ```
76
+
77
+ ## Quick start
78
+
79
+ ```bash
80
+ npm install @inlang/sdk
81
+ ```
82
+
83
+ ```ts
84
+ import fs from "node:fs";
85
+
86
+ import { loadProjectFromDirectory, saveProjectToDirectory } from "@inlang/sdk";
87
+
88
+ const project = await loadProjectFromDirectory({
89
+ path: "./project.inlang",
90
+ fs,
91
+ });
92
+ // Query messages with the SDK.
93
+ const messages = await project.db.selectFrom("message").selectAll().execute();
94
+
95
+ // Use project.db to update messages.
96
+ await saveProjectToDirectory({
97
+ path: "./project.inlang",
98
+ fs,
99
+ project,
100
+ });
101
+
102
+ await project.close();
103
+ ```
104
+
105
+ `loadProjectFromDirectory()` and `saveProjectToDirectory()` both accept `node:fs`. `saveProjectToDirectory()` writes translation files through import/export plugins. If no exporter plugin is configured, save the canonical packed file with `project.toBlob()` instead.
106
+
107
+ ## For coding agents and tool builders
108
+
109
+ Target `.inlang` instead of inventing a custom JSON schema.
110
+
111
+ Why target `.inlang`?
112
+
113
+ - One file gives every tool the same data model for bundles, messages, variants, locales, metadata, and settings.
114
+ - CRUD operations are available through the SDK instead of custom parsing and rewriting.
115
+ - Version control via [lix](https://lix.dev) keeps localization changes reviewable and mergeable.
116
+ - Plugins handle JSON, ICU, i18next, XLIFF, and other formats for compatibility.
117
+
118
+ Do not:
119
+
120
+ - Invent a custom `locales/en.json` schema as the project format.
121
+ - Create a new localization config when a `.inlang` project already exists.
122
+ - Edit generated or cached files in this directory.
123
+ - Bypass `@inlang/sdk` when reading or writing `.inlang`.
124
+
125
+ ## Ideas for custom tooling
126
+
127
+ - Translation health dashboard (missing/empty/stale messages)
128
+ - Locale coverage report in CI
129
+ - Auto-PR for new keys with placeholders
130
+ - Migration tool between file formats via plugins
131
+ - Glossary/term consistency checker
132
+
133
+ ## Data model ([docs](https://inlang.com/docs/data-model))
134
+
135
+ ```
136
+ bundle (a concept, e.g., "welcome_header")
137
+ └── message (per locale, e.g., "en", "de")
138
+ └── variant (plural forms, gender, etc.)
139
+ ```
140
+
141
+ - **bundle**: Groups messages by ID (e.g., `welcome_header`)
142
+ - **message**: A translation for a specific locale
143
+ - **variant**: Handles pluralization/selectors (most messages have one variant)
144
+
145
+ ## Common tasks
146
+
147
+ - List bundles: `project.db.selectFrom("bundle").selectAll().execute()`
148
+ - List messages for locale: `project.db.selectFrom("message").where("locale", "=", "en").selectAll().execute()`
149
+ - Find missing translations: compare message counts across locales
150
+ - Update a message: `project.db.updateTable("message").set({ ... }).where("id", "=", "...").execute()`
151
+
152
+ ## Links
153
+
154
+ - [SDK documentation](https://inlang.com/docs)
155
+ - [inlang.com](https://inlang.com)
156
+ - [List of plugins](https://inlang.com/c/plugins)
157
+ - [List of tools](https://inlang.com/c/tools)
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "https://inlang.com/schema/project-settings",
3
+ "sourceLanguageTag": "en",
4
+ "languageTags": ["en", "tr"],
5
+ "modules": ["https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@3/dist/index.js"],
6
+ "plugin.inlang.messageFormat": {
7
+ "pathPattern": "./messages/{languageTag}.json"
8
+ }
9
+ }
@@ -0,0 +1,86 @@
1
+ # ViraStack Start — TanStack Start Edition
2
+
3
+ > Premium TanStack Start + React 19 + Tailwind CSS 4 boilerplate focused on clean architecture, UI/UX, and agent-ready developer experience. Auth, database/ORM, i18n, and testing are intentionally omitted — bring the solution that fits your project.
4
+
5
+ Built on TanStack Router file-based routing with type-safe loaders, nested layouts, and SSR via TanStack Start. UI primitives use **Base UI** (unstyled, accessible) styled with Tailwind CSS 4 design tokens. State is split by job: TanStack Query for server state, Zustand for client state, `nuqs` for URL state. Forms use React Hook Form + Zod. The home route renders a deletable `features/landing` demo that follows the canonical ViraStack feature tree. **ViraStack AI** (`@virastack/ai`) adds agent rules on scaffold; design skills come from [emilkowalski/skills](https://github.com/emilkowalski/skills) and [make-interfaces-feel-better](https://github.com/jakubkrehel/make-interfaces-feel-better).
6
+
7
+ - Tech stack: TanStack Start, TanStack Router, React 19, Tailwind CSS 4, TypeScript (strict + `noUncheckedIndexedAccess`), Node.js `>=20.9`
8
+ - UI: Base UI, Framer Motion, Sonner, Lucide React, `next-themes`, `class-variance-authority`
9
+ - Data & state: TanStack Query 5, Zustand, `nuqs`
10
+ - Forms: React Hook Form + Zod (+ `@hookform/resolvers`)
11
+ - API: Native `fetch` wrapper in `src/lib/api.ts` (`ApiError` with `message`, `status`, `data`); Axios is optional, not installed
12
+ - Env: Hand-rolled Zod schema in `src/env.ts` (`VITE_*` public vars)
13
+ - Tooling: ESLint 9, Prettier 3, Husky, Knip, Commitlint, Changesets, Vite 8
14
+ - Quality scripts: `pnpm typecheck`, `pnpm lint` / `lint:ci`, `pnpm knip`, `pnpm build`
15
+ - ViraStack AI (via `npx @virastack/ai init`): `AGENTS.md`, `CLAUDE.md`, `.cursor/rules/*.mdc`, `docs/*`
16
+ - Not included by default: Auth, DB/ORM, i18n, test runner, CSP
17
+
18
+ ## Docs
19
+ - [Repository (GitHub)](https://github.com/virastack/start): CLI and templates
20
+ - [README](https://github.com/virastack/start/tree/main/templates/tanstack): Features, structure, and conventions
21
+ - [Architecture guide](https://github.com/virastack/ai/blob/main/templates/core/docs/architecture-guide.md): Placement rules and import conventions
22
+ - [Product docs](https://www.virastack.com/): ViraStack
23
+
24
+ ## Key Files & Entry Points
25
+ - [`src/routes/__root.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/routes/__root.tsx): Root route, document shell, providers, SEO head
26
+ - [`src/routes/index.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/routes/index.tsx): Home route → `<LandingPage />`
27
+ - [`src/routes/robots[.]txt.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/routes/robots%5B.%5Dtxt.ts): Dynamic robots.txt from `siteConfig`
28
+ - [`src/routes/sitemap[.]xml.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/routes/sitemap%5B.%5Dxml.ts): Dynamic sitemap from `siteConfig`
29
+ - [`src/routes/site[.]webmanifest.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/routes/site%5B.%5Dwebmanifest.ts): Dynamic web manifest from `siteConfig`
30
+ - [`src/start.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/start.ts): Global request middleware (baseline security headers)
31
+ - [`src/router.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/router.tsx): Router factory + TanStack Query SSR integration
32
+ - [`src/env.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/env.ts): Zod-validated environment schema (`VITE_*` public vars)
33
+ - [`src/config/site.config.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/config/site.config.ts): Site config (name, URL, links)
34
+ - [`src/config/seo.config.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/config/seo.config.ts): Default SEO meta helpers
35
+ - [`src/lib/api.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/lib/api.ts): Native `fetch` wrapper with retry & typed `ApiError`
36
+ - [`src/lib/query-client.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/lib/query-client.ts): QueryClient factory & defaults
37
+ - [`src/providers/Providers.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/providers/Providers.tsx): App-wide providers (Theme, Nuqs, Toaster)
38
+ - [`vite.config.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/vite.config.ts): Vite + TanStack Start + Tailwind
39
+
40
+ ## Landing Feature (demo — delete when building)
41
+ Canonical tree under `src/features/landing/`. Home route composes `LandingPage`.
42
+
43
+ - [`src/features/landing/index.ts`](https://github.com/virastack/start/blob/main/templates/tanstack/src/features/landing/index.ts): Public export (`LandingPage`)
44
+ - [`src/features/landing/components/LandingPage.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/features/landing/components/LandingPage.tsx): Page composition (Header + sections + Footer)
45
+ - [`src/features/landing/components/Hero.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/features/landing/components/Hero.tsx): Hero section
46
+ - [`src/features/landing/components/Features.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/features/landing/components/Features.tsx): Feature grid
47
+ - [`src/features/landing/components/Showcase.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/features/landing/components/Showcase.tsx): Stack demos host (Query, Zustand, forms, nuqs)
48
+ - [`src/features/landing/components/UsersDemo.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/features/landing/components/UsersDemo.tsx): TanStack Query + `nuqs` demo
49
+ - [`src/features/landing/components/CartDemo.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/features/landing/components/CartDemo.tsx): Zustand demo
50
+ - [`src/features/landing/components/ProjectFormDemo.tsx`](https://github.com/virastack/start/blob/main/templates/tanstack/src/features/landing/components/ProjectFormDemo.tsx): RHF + Zod demo
51
+
52
+ Quick start: delete `src/features/landing`, replace `src/routes/index.tsx`, keep `components/layout` if you still want chrome.
53
+
54
+ ## UI & Shared Layers
55
+ - [`src/components/ui`](https://github.com/virastack/start/tree/main/templates/tanstack/src/components/ui): Base UI primitives (Button, Input, Field, Dialog, Tabs, Skeleton, Label, Avatar, Table)
56
+ - [`src/components/layout`](https://github.com/virastack/start/tree/main/templates/tanstack/src/components/layout): Header / Footer (reusable; Header accepts optional `links`)
57
+ - [`src/components/shared`](https://github.com/virastack/start/tree/main/templates/tanstack/src/components/shared): Cross-feature components (ThemeToggle, NotFound, DefaultCatchBoundary)
58
+ - [`src/hooks`](https://github.com/virastack/start/tree/main/templates/tanstack/src/hooks), [`src/stores`](https://github.com/virastack/start/tree/main/templates/tanstack/src/stores), [`src/schemas`](https://github.com/virastack/start/tree/main/templates/tanstack/src/schemas): Shared barrels (promote via Rule of Three)
59
+ - [`src/helpers`](https://github.com/virastack/start/tree/main/templates/tanstack/src/helpers): Shared helpers
60
+ - [`src/styles/tailwind.css`](https://github.com/virastack/start/blob/main/templates/tanstack/src/styles/tailwind.css): Tailwind v4 entry + design tokens
61
+ - Assets: [`public/logo.webp`](https://github.com/virastack/start/blob/main/templates/tanstack/public/logo.webp), [`public/og.png`](https://github.com/virastack/start/blob/main/templates/tanstack/public/og.png), [`public/favicon.ico`](https://github.com/virastack/start/blob/main/templates/tanstack/public/favicon.ico)
62
+
63
+ ## Customization & Imports
64
+ - Search the project for `FIXME:` (site config, auth attachment on the API client).
65
+ - Prefer short path aliases: `@/ui`, `@/hooks`, `@/schemas`, `@/layout` over long forms. Prefer feature-local imports under `@/features/[feature]/…` for demo-scoped code.
66
+ - Default scope is `features/[feature]/` — promote to global `src/` only when a second feature needs it. No cross-feature imports.
67
+
68
+ ## ViraStack AI
69
+ - Install or refresh: `npx @virastack/ai init --force`
70
+ - `AGENTS.md`: Agent operating guide (all agents)
71
+ - `CLAUDE.md`: Claude Code entry point (`@AGENTS.md`)
72
+ - `.cursor/rules/*.mdc`: Scoped coding rules (Cursor auto-loads)
73
+ - `docs/architecture-guide.md`, `docs/MEMORIES.md`: Architecture and project memory
74
+ - Skills: [emilkowalski/skills](https://github.com/emilkowalski/skills) (7 design-engineering skills) + [make-interfaces-feel-better](https://github.com/jakubkrehel/make-interfaces-feel-better)
75
+ - Package: [`@virastack/ai`](https://github.com/virastack/ai)
76
+
77
+ ## External References
78
+ - [TanStack Start Docs](https://tanstack.com/start/latest): Routing, SSR, server functions
79
+ - [TanStack Router](https://tanstack.com/router/latest): File-based routing, loaders, type safety
80
+ - [React](https://react.dev/): Modern React APIs
81
+ - [Tailwind CSS v4](https://tailwindcss.com/): Design tokens & utility-first styling
82
+ - [Base UI](https://base-ui.com/): Unstyled, accessible React components
83
+ - [TanStack Query](https://tanstack.com/query/latest): Server-state syncing & caching
84
+ - [nuqs](https://nuqs.dev/): Type-safe URL search param state
85
+ - [Zod](https://zod.dev/): Runtime validation and parsing
86
+ - [ViraStack AI](https://github.com/virastack/ai): Shared agent rules package (`@virastack/ai`)
@@ -0,0 +1,36 @@
1
+ import type { ErrorComponentProps } from "@tanstack/react-router";
2
+ import { Link, rootRouteId, useMatch, useRouter } from "@tanstack/react-router";
3
+
4
+ import { Button } from "@/components/ui/button";
5
+
6
+ export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
7
+ const router = useRouter();
8
+ const isRoot = useMatch({
9
+ strict: false,
10
+ select: (state) => state.id === rootRouteId,
11
+ });
12
+
13
+ console.error(error);
14
+
15
+ return (
16
+ <div className="mx-auto flex flex-1 flex-col items-center justify-center gap-4 px-6 py-24 text-center">
17
+ <h1 className="text-2xl font-semibold tracking-tight">Something went wrong</h1>
18
+ <p className="max-w-md text-sm text-muted-foreground">
19
+ An unexpected error occurred while rendering this page. You can try again, or head back to
20
+ the homepage.
21
+ </p>
22
+ <div className="flex gap-3">
23
+ <Button onClick={() => router.invalidate()}>Try again</Button>
24
+ {isRoot ? (
25
+ <Button variant="outline" nativeButton={false} render={<Link to="/" />}>
26
+ Go home
27
+ </Button>
28
+ ) : (
29
+ <Button variant="outline" onClick={() => window.history.back()}>
30
+ Go back
31
+ </Button>
32
+ )}
33
+ </div>
34
+ </div>
35
+ );
36
+ }
@@ -0,0 +1,57 @@
1
+ import { useRouter } from "@tanstack/react-router";
2
+
3
+ import { getLocale, setLocale } from "@/paraglide/runtime.js";
4
+
5
+ export function LanguageSwitcher() {
6
+ const router = useRouter();
7
+ const currentLang = getLocale();
8
+
9
+ const onChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
10
+ const nextLocale = e.target.value as "en" | "tr";
11
+
12
+ // Geçici olarak as-needed kapatıldı. Her dil için prefix eklenecek.
13
+ // Issue çözüldüğünde eski localizeUrl mantığına dönülebilir.
14
+ const url = new URL(window.location.href);
15
+ const pathSegments = url.pathname.split("/").filter(Boolean);
16
+
17
+ if (pathSegments.length > 0 && (pathSegments[0] === "en" || pathSegments[0] === "tr")) {
18
+ pathSegments[0] = nextLocale;
19
+ } else {
20
+ pathSegments.unshift(nextLocale);
21
+ }
22
+
23
+ const newPath = "/" + pathSegments.join("/");
24
+
25
+ setLocale(nextLocale, { reload: false });
26
+ void router.navigate({
27
+ to: `${newPath}${url.search}${url.hash}`,
28
+ replace: true,
29
+ });
30
+ };
31
+
32
+ return (
33
+ <div className="relative">
34
+ <select
35
+ value={currentLang}
36
+ onChange={onChange}
37
+ className="h-10 cursor-pointer appearance-none rounded-md border border-input bg-background pr-8 pl-3 text-sm text-foreground focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none disabled:opacity-50"
38
+ >
39
+ <option value="en">EN</option>
40
+ <option value="tr">TR</option>
41
+ </select>
42
+ <div className="pointer-events-none absolute top-[11px] right-2.5 h-4 w-4 text-muted-foreground">
43
+ <svg
44
+ xmlns="http://www.w3.org/2000/svg"
45
+ viewBox="0 0 24 24"
46
+ fill="none"
47
+ stroke="currentColor"
48
+ strokeWidth="2"
49
+ strokeLinecap="round"
50
+ strokeLinejoin="round"
51
+ >
52
+ <path d="m6 9 6 6 6-6" />
53
+ </svg>
54
+ </div>
55
+ </div>
56
+ );
57
+ }
@@ -0,0 +1,18 @@
1
+ import { Link } from "@tanstack/react-router";
2
+
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ export function NotFound() {
6
+ return (
7
+ <div className="mx-auto flex flex-1 flex-col items-center justify-center gap-4 px-6 py-24 text-center">
8
+ <p className="text-sm font-medium text-muted-foreground">404</p>
9
+ <h1 className="text-2xl font-semibold tracking-tight">Page not found</h1>
10
+ <p className="max-w-md text-sm text-muted-foreground">
11
+ The page you&apos;re looking for doesn&apos;t exist or has been moved.
12
+ </p>
13
+ <Button nativeButton={false} render={<Link to="/" />}>
14
+ Go home
15
+ </Button>
16
+ </div>
17
+ );
18
+ }
@@ -0,0 +1,13 @@
1
+ import { Skeleton } from "@/components/ui/skeleton";
2
+
3
+ /** Route-level pending UI (TanStack equivalent of Next.js `loading.tsx`). */
4
+ export function Pending() {
5
+ return (
6
+ <div className="mx-auto flex w-full max-w-3xl flex-1 flex-col items-center gap-4 px-6 py-24">
7
+ <Skeleton className="h-10 w-2/3" />
8
+ <Skeleton className="h-4 w-full" />
9
+ <Skeleton className="h-4 w-5/6" />
10
+ <Skeleton className="mt-6 h-40 w-full" />
11
+ </div>
12
+ );
13
+ }
@@ -0,0 +1,31 @@
1
+ "use client";
2
+
3
+ import { MoonIcon, SunIcon } from "lucide-react";
4
+ import { useIsClient } from "usehooks-ts";
5
+
6
+ import { useTheme } from "@/providers/ThemeProvider";
7
+
8
+ import { Button } from "@/components/ui/button";
9
+
10
+ export function ThemeToggle() {
11
+ const { resolvedTheme, setTheme } = useTheme();
12
+ const isClient = useIsClient();
13
+
14
+ if (!isClient) {
15
+ return <Button variant="outline" size="icon" aria-hidden className="size-8 opacity-0" />;
16
+ }
17
+
18
+ const isDark = resolvedTheme === "dark";
19
+
20
+ return (
21
+ <Button
22
+ variant="outline"
23
+ size="icon"
24
+ className="size-8"
25
+ aria-label={isDark ? "Switch to light theme" : "Switch to dark theme"}
26
+ onClick={() => setTheme(isDark ? "light" : "dark")}
27
+ >
28
+ {isDark ? <SunIcon className="size-3.5" /> : <MoonIcon className="size-3.5" />}
29
+ </Button>
30
+ );
31
+ }
@@ -0,0 +1,52 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "@/lib/utils";
4
+
5
+ const Avatar = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
6
+ ({ className, ...props }, ref) => (
7
+ <div
8
+ ref={ref}
9
+ className={cn("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", className)}
10
+ {...props}
11
+ />
12
+ ),
13
+ );
14
+ Avatar.displayName = "Avatar";
15
+
16
+ const AvatarImage = React.forwardRef<
17
+ HTMLImageElement,
18
+ React.ImgHTMLAttributes<HTMLImageElement> & {
19
+ onLoadingStatusChange?: (status: "loading" | "loaded" | "error") => void;
20
+ }
21
+ >(({ className, src, alt = "", ...props }, ref) => {
22
+ const [status, setStatus] = React.useState<"loading" | "loaded" | "error">("loading");
23
+
24
+ return (
25
+ <img
26
+ ref={ref}
27
+ src={src}
28
+ alt={alt}
29
+ className={cn("aspect-square h-full w-full", status !== "loaded" && "hidden", className)}
30
+ onLoad={() => setStatus("loaded")}
31
+ onError={() => setStatus("error")}
32
+ {...props}
33
+ />
34
+ );
35
+ });
36
+ AvatarImage.displayName = "AvatarImage";
37
+
38
+ const AvatarFallback = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
39
+ ({ className, ...props }, ref) => (
40
+ <div
41
+ ref={ref}
42
+ className={cn(
43
+ "flex h-full w-full items-center justify-center rounded-full bg-muted text-xs",
44
+ className,
45
+ )}
46
+ {...props}
47
+ />
48
+ ),
49
+ );
50
+ AvatarFallback.displayName = "AvatarFallback";
51
+
52
+ export { Avatar, AvatarImage, AvatarFallback };
@@ -0,0 +1,47 @@
1
+ import type { ComponentProps } from "react";
2
+
3
+ import { Button as BaseButton } from "@base-ui/react/button";
4
+ import { cva } from "class-variance-authority";
5
+ import type { VariantProps } from "class-variance-authority";
6
+
7
+ import { cn } from "@/lib/utils";
8
+
9
+ export const buttonVariants = cva(
10
+ "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
11
+ {
12
+ variants: {
13
+ variant: {
14
+ default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
15
+ destructive:
16
+ "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20",
17
+ outline:
18
+ "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
19
+ secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
20
+ ghost: "hover:bg-accent hover:text-accent-foreground",
21
+ link: "text-primary underline-offset-4 hover:underline",
22
+ },
23
+ size: {
24
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
25
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
26
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
27
+ icon: "size-9",
28
+ },
29
+ },
30
+ defaultVariants: {
31
+ variant: "default",
32
+ size: "default",
33
+ },
34
+ },
35
+ );
36
+
37
+ export type ButtonProps = ComponentProps<typeof BaseButton> & VariantProps<typeof buttonVariants>;
38
+
39
+ export function Button({ className, variant, size, ...props }: ButtonProps) {
40
+ return (
41
+ <BaseButton
42
+ data-slot="button"
43
+ className={cn(buttonVariants({ variant, size, className }))}
44
+ {...props}
45
+ />
46
+ );
47
+ }
@@ -0,0 +1,107 @@
1
+ import type { ComponentProps } from "react";
2
+
3
+ import { XIcon } from "lucide-react";
4
+ import { Dialog as BaseDialog } from "@base-ui/react/dialog";
5
+
6
+ import { cn } from "@/lib/utils";
7
+
8
+ export function Dialog(props: ComponentProps<typeof BaseDialog.Root>) {
9
+ return <BaseDialog.Root data-slot="dialog" {...props} />;
10
+ }
11
+
12
+ export function DialogTrigger(props: ComponentProps<typeof BaseDialog.Trigger>) {
13
+ return <BaseDialog.Trigger data-slot="dialog-trigger" {...props} />;
14
+ }
15
+
16
+ export function DialogClose(props: ComponentProps<typeof BaseDialog.Close>) {
17
+ return <BaseDialog.Close data-slot="dialog-close" {...props} />;
18
+ }
19
+
20
+ export function DialogContent({
21
+ className,
22
+ children,
23
+ showCloseButton = true,
24
+ ...props
25
+ }: ComponentProps<typeof BaseDialog.Popup> & { showCloseButton?: boolean }) {
26
+ return (
27
+ <BaseDialog.Portal>
28
+ <BaseDialog.Backdrop
29
+ data-slot="dialog-backdrop"
30
+ className={cn(
31
+ "fixed inset-0 z-50 bg-black/50",
32
+ "data-[ending-style]:opacity-0 data-[starting-style]:opacity-0",
33
+ "transition-opacity duration-150",
34
+ )}
35
+ />
36
+ <BaseDialog.Popup
37
+ data-slot="dialog-content"
38
+ className={cn(
39
+ "fixed top-1/2 left-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4",
40
+ "rounded-lg border border-border bg-background p-6 shadow-lg",
41
+ "data-[starting-style]:scale-95 data-[starting-style]:opacity-0",
42
+ "data-[ending-style]:scale-95 data-[ending-style]:opacity-0",
43
+ "transition-all duration-150",
44
+ className,
45
+ )}
46
+ {...props}
47
+ >
48
+ {children}
49
+ {showCloseButton && (
50
+ <BaseDialog.Close
51
+ data-slot="dialog-close"
52
+ className={cn(
53
+ "absolute top-4 right-4 rounded-xs opacity-70 transition-opacity outline-none",
54
+ "hover:opacity-100 focus-visible:ring-[3px] focus-visible:ring-ring/50",
55
+ )}
56
+ >
57
+ <XIcon className="size-4" />
58
+ <span className="sr-only">Close</span>
59
+ </BaseDialog.Close>
60
+ )}
61
+ </BaseDialog.Popup>
62
+ </BaseDialog.Portal>
63
+ );
64
+ }
65
+
66
+ export function DialogHeader({ className, ...props }: ComponentProps<"div">) {
67
+ return (
68
+ <div
69
+ data-slot="dialog-header"
70
+ className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
71
+ {...props}
72
+ />
73
+ );
74
+ }
75
+
76
+ export function DialogFooter({ className, ...props }: ComponentProps<"div">) {
77
+ return (
78
+ <div
79
+ data-slot="dialog-footer"
80
+ className={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)}
81
+ {...props}
82
+ />
83
+ );
84
+ }
85
+
86
+ export function DialogTitle({ className, ...props }: ComponentProps<typeof BaseDialog.Title>) {
87
+ return (
88
+ <BaseDialog.Title
89
+ data-slot="dialog-title"
90
+ className={cn("text-lg leading-none font-semibold", className)}
91
+ {...props}
92
+ />
93
+ );
94
+ }
95
+
96
+ export function DialogDescription({
97
+ className,
98
+ ...props
99
+ }: ComponentProps<typeof BaseDialog.Description>) {
100
+ return (
101
+ <BaseDialog.Description
102
+ data-slot="dialog-description"
103
+ className={cn("text-sm text-muted-foreground", className)}
104
+ {...props}
105
+ />
106
+ );
107
+ }