@tanstack/create 0.64.0 → 0.66.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/create-app.js +72 -16
  3. package/dist/file-helpers.js +14 -0
  4. package/dist/frameworks/react/add-ons/ai/info.json +1 -1
  5. package/dist/frameworks/react/add-ons/better-auth/info.json +1 -1
  6. package/dist/frameworks/react/add-ons/clerk/README.md +42 -1
  7. package/dist/frameworks/react/add-ons/clerk/assets/src/routes/demo/clerk.tsx +94 -11
  8. package/dist/frameworks/react/add-ons/clerk/info.json +1 -1
  9. package/dist/frameworks/react/add-ons/compiler/info.json +1 -1
  10. package/dist/frameworks/react/add-ons/convex/info.json +1 -1
  11. package/dist/frameworks/react/add-ons/drizzle/info.json +1 -1
  12. package/dist/frameworks/react/add-ons/mcp/info.json +1 -1
  13. package/dist/frameworks/react/add-ons/neon/info.json +1 -1
  14. package/dist/frameworks/react/add-ons/paraglide/info.json +1 -1
  15. package/dist/frameworks/react/add-ons/prisma/info.json +1 -1
  16. package/dist/frameworks/react/add-ons/shadcn/info.json +1 -1
  17. package/dist/frameworks/react/add-ons/shopify/README.md +86 -0
  18. package/dist/frameworks/react/add-ons/shopify/assets/_dot_env.local.append +19 -0
  19. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/account-nav.tsx.ejs +41 -0
  20. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/add-to-cart-button.tsx +48 -0
  21. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/cart-line-item.tsx +94 -0
  22. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/cart-summary.tsx +111 -0
  23. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/empty-state.tsx +29 -0
  24. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/money.tsx +11 -0
  25. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/product-card.tsx +74 -0
  26. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/product-grid.tsx +24 -0
  27. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/shop-image.tsx +57 -0
  28. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/shop.css +58 -0
  29. package/dist/frameworks/react/add-ons/shopify/assets/src/components/shop/variant-selector.tsx +79 -0
  30. package/dist/frameworks/react/add-ons/shopify/assets/src/hooks/use-cart.ts +276 -0
  31. package/dist/frameworks/react/add-ons/shopify/assets/src/hooks/use-customer.ts.ejs +22 -0
  32. package/dist/frameworks/react/add-ons/shopify/assets/src/integrations/shopify/header-cart.tsx +37 -0
  33. package/dist/frameworks/react/add-ons/shopify/assets/src/lib/shopify/customer-queries.ts.ejs +228 -0
  34. package/dist/frameworks/react/add-ons/shopify/assets/src/lib/shopify/format.ts +33 -0
  35. package/dist/frameworks/react/add-ons/shopify/assets/src/lib/shopify/queries.ts +684 -0
  36. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.addresses.tsx.ejs +67 -0
  37. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.callback.tsx.ejs +45 -0
  38. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.index.tsx.ejs +70 -0
  39. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.login.tsx.ejs +59 -0
  40. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.logout.tsx.ejs +16 -0
  41. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.orders.$id.tsx.ejs +126 -0
  42. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.orders.tsx.ejs +50 -0
  43. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.tsx.ejs +34 -0
  44. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.cart.tsx +45 -0
  45. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.collections.$handle.tsx +66 -0
  46. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.index.tsx +36 -0
  47. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.pages.$handle.tsx +39 -0
  48. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.policies.$handle.tsx +30 -0
  49. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.products.$handle.tsx +106 -0
  50. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.search.tsx +75 -0
  51. package/dist/frameworks/react/add-ons/shopify/assets/src/routes/shop.tsx +78 -0
  52. package/dist/frameworks/react/add-ons/shopify/assets/src/server/shopify/cart.functions.ts +207 -0
  53. package/dist/frameworks/react/add-ons/shopify/assets/src/server/shopify/catalog.functions.ts +244 -0
  54. package/dist/frameworks/react/add-ons/shopify/assets/src/server/shopify/cookies.ts +29 -0
  55. package/dist/frameworks/react/add-ons/shopify/assets/src/server/shopify/customer-client.ts.ejs +99 -0
  56. package/dist/frameworks/react/add-ons/shopify/assets/src/server/shopify/customer-cookies.ts.ejs +49 -0
  57. package/dist/frameworks/react/add-ons/shopify/assets/src/server/shopify/customer.functions.ts.ejs +168 -0
  58. package/dist/frameworks/react/add-ons/shopify/assets/src/server/shopify/env.ts +89 -0
  59. package/dist/frameworks/react/add-ons/shopify/assets/src/server/shopify/oauth.ts.ejs +301 -0
  60. package/dist/frameworks/react/add-ons/shopify/assets/src/server/shopify/storefront-client.ts +101 -0
  61. package/dist/frameworks/react/add-ons/shopify/info.json +104 -0
  62. package/dist/frameworks/react/add-ons/shopify/package.json +6 -0
  63. package/dist/frameworks/react/add-ons/shopify/small-logo.svg +1 -0
  64. package/dist/frameworks/react/add-ons/strapi/info.json +1 -1
  65. package/dist/frameworks/react/add-ons/t3env/info.json +1 -1
  66. package/dist/frameworks/react/add-ons/workos/info.json +1 -1
  67. package/dist/frameworks/react/examples/shopify-storefront/README.md +39 -0
  68. package/dist/frameworks/react/examples/shopify-storefront/assets/src/components/FeaturedCollections.tsx +43 -0
  69. package/dist/frameworks/react/examples/shopify-storefront/assets/src/components/ShopHero.tsx +39 -0
  70. package/dist/frameworks/react/examples/shopify-storefront/assets/src/routes/index.tsx +65 -0
  71. package/dist/frameworks/react/examples/shopify-storefront/info.json +18 -0
  72. package/dist/frameworks/react/examples/shopify-storefront/package.json +3 -0
  73. package/dist/frameworks/react/hosts/cloudflare/README.md +11 -0
  74. package/dist/frameworks/react/hosts/cloudflare/info.json +1 -1
  75. package/dist/frameworks/react/hosts/netlify/README.md +11 -0
  76. package/dist/frameworks/react/hosts/netlify/info.json +1 -1
  77. package/dist/frameworks/react/hosts/nitro/README.md +12 -0
  78. package/dist/frameworks/react/hosts/nitro/info.json +1 -1
  79. package/dist/frameworks/react/hosts/railway/README.md +10 -0
  80. package/dist/frameworks/react/hosts/railway/info.json +1 -1
  81. package/dist/frameworks/react/project/base/src/components/Header.tsx.ejs +34 -34
  82. package/dist/frameworks/solid/add-ons/better-auth/info.json +1 -1
  83. package/dist/frameworks/solid/add-ons/convex/info.json +1 -1
  84. package/dist/frameworks/solid/add-ons/solid-ui/info.json +1 -1
  85. package/dist/frameworks/solid/add-ons/strapi/info.json +1 -1
  86. package/dist/frameworks/solid/add-ons/t3env/info.json +1 -1
  87. package/dist/frameworks/solid/hosts/cloudflare/README.md +11 -0
  88. package/dist/frameworks/solid/hosts/cloudflare/info.json +1 -1
  89. package/dist/frameworks/solid/hosts/netlify/README.md +11 -0
  90. package/dist/frameworks/solid/hosts/netlify/info.json +1 -1
  91. package/dist/frameworks/solid/hosts/nitro/README.md +12 -0
  92. package/dist/frameworks/solid/hosts/nitro/info.json +1 -1
  93. package/dist/frameworks/solid/hosts/railway/README.md +10 -0
  94. package/dist/frameworks/solid/hosts/railway/info.json +1 -1
  95. package/dist/index.js +1 -1
  96. package/dist/integrations/intent.js +1 -1
  97. package/dist/types/file-helpers.d.ts +1 -0
  98. package/dist/types/index.d.ts +1 -1
  99. package/package.json +1 -1
  100. package/src/create-app.ts +86 -22
  101. package/src/file-helpers.ts +20 -0
  102. package/src/frameworks/react/add-ons/ai/info.json +1 -1
  103. package/src/frameworks/react/add-ons/better-auth/info.json +1 -1
  104. package/src/frameworks/react/add-ons/clerk/README.md +42 -1
  105. package/src/frameworks/react/add-ons/clerk/assets/src/routes/demo/clerk.tsx +94 -11
  106. package/src/frameworks/react/add-ons/clerk/info.json +1 -1
  107. package/src/frameworks/react/add-ons/compiler/info.json +1 -1
  108. package/src/frameworks/react/add-ons/convex/info.json +1 -1
  109. package/src/frameworks/react/add-ons/drizzle/info.json +1 -1
  110. package/src/frameworks/react/add-ons/mcp/info.json +1 -1
  111. package/src/frameworks/react/add-ons/neon/info.json +1 -1
  112. package/src/frameworks/react/add-ons/paraglide/info.json +1 -1
  113. package/src/frameworks/react/add-ons/prisma/info.json +1 -1
  114. package/src/frameworks/react/add-ons/shadcn/info.json +1 -1
  115. package/src/frameworks/react/add-ons/shopify/README.md +86 -0
  116. package/src/frameworks/react/add-ons/shopify/assets/_dot_env.local.append +19 -0
  117. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/account-nav.tsx.ejs +41 -0
  118. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/add-to-cart-button.tsx +48 -0
  119. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/cart-line-item.tsx +94 -0
  120. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/cart-summary.tsx +111 -0
  121. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/empty-state.tsx +29 -0
  122. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/money.tsx +11 -0
  123. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/product-card.tsx +74 -0
  124. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/product-grid.tsx +24 -0
  125. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/shop-image.tsx +57 -0
  126. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/shop.css +58 -0
  127. package/src/frameworks/react/add-ons/shopify/assets/src/components/shop/variant-selector.tsx +79 -0
  128. package/src/frameworks/react/add-ons/shopify/assets/src/hooks/use-cart.ts +276 -0
  129. package/src/frameworks/react/add-ons/shopify/assets/src/hooks/use-customer.ts.ejs +22 -0
  130. package/src/frameworks/react/add-ons/shopify/assets/src/integrations/shopify/header-cart.tsx +37 -0
  131. package/src/frameworks/react/add-ons/shopify/assets/src/lib/shopify/customer-queries.ts.ejs +228 -0
  132. package/src/frameworks/react/add-ons/shopify/assets/src/lib/shopify/format.ts +33 -0
  133. package/src/frameworks/react/add-ons/shopify/assets/src/lib/shopify/queries.ts +684 -0
  134. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.addresses.tsx.ejs +67 -0
  135. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.callback.tsx.ejs +45 -0
  136. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.index.tsx.ejs +70 -0
  137. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.login.tsx.ejs +59 -0
  138. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.logout.tsx.ejs +16 -0
  139. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.orders.$id.tsx.ejs +126 -0
  140. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.orders.tsx.ejs +50 -0
  141. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.account.tsx.ejs +34 -0
  142. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.cart.tsx +45 -0
  143. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.collections.$handle.tsx +66 -0
  144. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.index.tsx +36 -0
  145. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.pages.$handle.tsx +39 -0
  146. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.policies.$handle.tsx +30 -0
  147. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.products.$handle.tsx +106 -0
  148. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.search.tsx +75 -0
  149. package/src/frameworks/react/add-ons/shopify/assets/src/routes/shop.tsx +78 -0
  150. package/src/frameworks/react/add-ons/shopify/assets/src/server/shopify/cart.functions.ts +207 -0
  151. package/src/frameworks/react/add-ons/shopify/assets/src/server/shopify/catalog.functions.ts +244 -0
  152. package/src/frameworks/react/add-ons/shopify/assets/src/server/shopify/cookies.ts +29 -0
  153. package/src/frameworks/react/add-ons/shopify/assets/src/server/shopify/customer-client.ts.ejs +99 -0
  154. package/src/frameworks/react/add-ons/shopify/assets/src/server/shopify/customer-cookies.ts.ejs +49 -0
  155. package/src/frameworks/react/add-ons/shopify/assets/src/server/shopify/customer.functions.ts.ejs +168 -0
  156. package/src/frameworks/react/add-ons/shopify/assets/src/server/shopify/env.ts +89 -0
  157. package/src/frameworks/react/add-ons/shopify/assets/src/server/shopify/oauth.ts.ejs +301 -0
  158. package/src/frameworks/react/add-ons/shopify/assets/src/server/shopify/storefront-client.ts +101 -0
  159. package/src/frameworks/react/add-ons/shopify/info.json +104 -0
  160. package/src/frameworks/react/add-ons/shopify/package.json +6 -0
  161. package/src/frameworks/react/add-ons/shopify/small-logo.svg +1 -0
  162. package/src/frameworks/react/add-ons/strapi/info.json +1 -1
  163. package/src/frameworks/react/add-ons/t3env/info.json +1 -1
  164. package/src/frameworks/react/add-ons/workos/info.json +1 -1
  165. package/src/frameworks/react/examples/shopify-storefront/README.md +39 -0
  166. package/src/frameworks/react/examples/shopify-storefront/assets/src/components/FeaturedCollections.tsx +43 -0
  167. package/src/frameworks/react/examples/shopify-storefront/assets/src/components/ShopHero.tsx +39 -0
  168. package/src/frameworks/react/examples/shopify-storefront/assets/src/routes/index.tsx +65 -0
  169. package/src/frameworks/react/examples/shopify-storefront/info.json +18 -0
  170. package/src/frameworks/react/examples/shopify-storefront/package.json +3 -0
  171. package/src/frameworks/react/hosts/cloudflare/README.md +11 -0
  172. package/src/frameworks/react/hosts/cloudflare/info.json +1 -1
  173. package/src/frameworks/react/hosts/netlify/README.md +11 -0
  174. package/src/frameworks/react/hosts/netlify/info.json +1 -1
  175. package/src/frameworks/react/hosts/nitro/README.md +12 -0
  176. package/src/frameworks/react/hosts/nitro/info.json +1 -1
  177. package/src/frameworks/react/hosts/railway/README.md +10 -0
  178. package/src/frameworks/react/hosts/railway/info.json +1 -1
  179. package/src/frameworks/react/project/base/src/components/Header.tsx.ejs +34 -34
  180. package/src/frameworks/solid/add-ons/better-auth/info.json +1 -1
  181. package/src/frameworks/solid/add-ons/convex/info.json +1 -1
  182. package/src/frameworks/solid/add-ons/solid-ui/info.json +1 -1
  183. package/src/frameworks/solid/add-ons/strapi/info.json +1 -1
  184. package/src/frameworks/solid/add-ons/t3env/info.json +1 -1
  185. package/src/frameworks/solid/hosts/cloudflare/README.md +11 -0
  186. package/src/frameworks/solid/hosts/cloudflare/info.json +1 -1
  187. package/src/frameworks/solid/hosts/netlify/README.md +11 -0
  188. package/src/frameworks/solid/hosts/netlify/info.json +1 -1
  189. package/src/frameworks/solid/hosts/nitro/README.md +12 -0
  190. package/src/frameworks/solid/hosts/nitro/info.json +1 -1
  191. package/src/frameworks/solid/hosts/railway/README.md +10 -0
  192. package/src/frameworks/solid/hosts/railway/info.json +1 -1
  193. package/src/index.ts +1 -0
  194. package/src/integrations/intent.ts +1 -1
  195. package/tests/create-app.test.ts +95 -0
@@ -0,0 +1,65 @@
1
+ import { Link, createFileRoute } from '@tanstack/react-router'
2
+
3
+ import '#/components/shop/shop.css'
4
+ import { ProductGrid } from '#/components/shop/product-grid'
5
+ import { FeaturedCollections } from '#/components/FeaturedCollections'
6
+ import { ShopHero } from '#/components/ShopHero'
7
+ import {
8
+ getCollections,
9
+ getProducts,
10
+ getShop,
11
+ } from '#/server/shopify/catalog.functions'
12
+
13
+ export const Route = createFileRoute('/')({
14
+ loader: async () => {
15
+ const [shop, collections, products] = await Promise.all([
16
+ getShop(),
17
+ getCollections(),
18
+ getProducts({ data: { first: 8, sortKey: 'BEST_SELLING' } }),
19
+ ])
20
+ return { shop, collections, featured: products.nodes }
21
+ },
22
+ head: ({ loaderData }) => ({
23
+ meta: loaderData
24
+ ? [
25
+ { title: loaderData.shop.name },
26
+ { name: 'description', content: loaderData.shop.description ?? '' },
27
+ ]
28
+ : [],
29
+ }),
30
+ component: HomePage,
31
+ })
32
+
33
+ function HomePage() {
34
+ const { shop, collections, featured } = Route.useLoaderData()
35
+
36
+ return (
37
+ <div className="shop-root min-h-screen">
38
+ <ShopHero
39
+ title={shop.name}
40
+ tagline={shop.description ?? 'A TanStack Start + Shopify storefront.'}
41
+ />
42
+
43
+ {collections.length > 0 && (
44
+ <section className="mx-auto max-w-7xl px-4 pb-20 sm:px-6 lg:px-8">
45
+ <FeaturedCollections collections={collections.slice(0, 3)} />
46
+ </section>
47
+ )}
48
+
49
+ <section className="mx-auto max-w-7xl px-4 pb-24 sm:px-6 lg:px-8">
50
+ <div className="mb-8 flex items-baseline justify-between">
51
+ <h2 className="text-2xl font-medium tracking-tight sm:text-3xl">
52
+ Best sellers
53
+ </h2>
54
+ <Link
55
+ to="/shop"
56
+ className="text-sm underline underline-offset-4 hover:opacity-80"
57
+ >
58
+ Shop all →
59
+ </Link>
60
+ </div>
61
+ <ProductGrid products={featured} />
62
+ </section>
63
+ </div>
64
+ )
65
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "Shopify Storefront",
3
+ "description": "A polished Shopify storefront starter — TanStack Start + Shopify Storefront API + optional customer accounts. Hosted checkout, deploy anywhere.",
4
+ "phase": "example",
5
+ "modes": ["file-router"],
6
+ "type": "example",
7
+ "category": "other",
8
+ "color": "#5A31F4",
9
+ "priority": 5,
10
+ "link": "https://shopify.dev/docs/storefronts/headless",
11
+ "dependsOn": ["shopify"],
12
+ "default": true,
13
+ "routes": [
14
+ { "url": "/", "path": "src/routes/index.tsx", "jsName": "ShopHome" }
15
+ ],
16
+ "integrations": [],
17
+ "variables": []
18
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "dependencies": {}
3
+ }
@@ -0,0 +1,11 @@
1
+ ## Deploy to Cloudflare Workers
2
+
3
+ This project uses the Cloudflare Vite plugin (configured in `vite.config.ts`) and `wrangler.jsonc`:
4
+
5
+ 1. Install Wrangler: `npm install -g wrangler`
6
+ 2. Authenticate: `wrangler login`
7
+ 3. Deploy: `npx wrangler deploy`
8
+
9
+ For production env vars, run `wrangler secret put MY_VAR` for each secret listed in `.env.example`. Public (non-secret) vars go in `wrangler.jsonc` under `vars`.
10
+
11
+ KV, D1, R2, and Durable Object bindings are configured in `wrangler.jsonc` — see https://developers.cloudflare.com/workers/wrangler/configuration/.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Cloudflare",
3
- "description": "Cloudflare deployment setup",
3
+ "description": "Deploy to Cloudflare Workers (edge runtime, KV/D1/R2 bindings).",
4
4
  "link": "https://developers.cloudflare.com/workers/vite-plugin/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,11 @@
1
+ ## Deploy to Netlify
2
+
3
+ This project ships with `netlify.toml` configured for a Netlify site:
4
+
5
+ 1. Push this repo to GitHub
6
+ 2. Visit https://app.netlify.com/start and import the repo
7
+ 3. Netlify auto-detects the build (`vite build` → `dist/client`)
8
+ 4. Open **Site settings → Environment variables** and add anything from `.env.example` that needs a real value in production
9
+ 5. Trigger the first deploy
10
+
11
+ Server functions and API routes run on Netlify Functions. For lower-latency request handling, see Netlify Edge Functions: https://docs.netlify.com/edge-functions/overview.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Netlify",
3
- "description": "Netlify deployment setup",
3
+ "description": "Deploy to Netlify (Functions and Edge Functions, GitHub-driven).",
4
4
  "link": "https://docs.netlify.com",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,12 @@
1
+ ## Deploy with Nitro
2
+
3
+ This project uses Nitro as a generic server adapter, so it can run on any Node-compatible host.
4
+
5
+ ```bash
6
+ npm run build
7
+ node dist/server/index.mjs
8
+ ```
9
+
10
+ The build output is a self-contained Node server. To deploy, push the `dist/` directory to your host (Render, Fly.io, your own VPS, etc.) and run the server command above.
11
+
12
+ For host-specific presets (Vercel, Netlify, Cloudflare, AWS Lambda, etc.) and tuning, see https://v3.nitro.build/deploy.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Nitro (agnostic)",
3
- "description": "Nitro deployment setup",
3
+ "description": "Generic Nitro adapter (deploy to any Node-compatible host).",
4
4
  "link": "https://v3.nitro.build/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,10 @@
1
+ ## Deploy to Railway
2
+
3
+ This project ships with `nixpacks.toml` so Railway detects the build automatically:
4
+
5
+ 1. Push this repo to GitHub
6
+ 2. Visit https://railway.com/new and create a project from your repo
7
+ 3. In the **Variables** tab, add the entries from `.env.example` with their production values
8
+ 4. Railway runs `vite build` and serves from `dist/client`
9
+
10
+ Need a database? Click **+ New** in your project to provision Postgres, MySQL, or Redis directly into the same environment — the connection string is auto-injected as `DATABASE_URL`.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Railway",
3
- "description": "Railway deployment setup",
3
+ "description": "Deploy to Railway (full-stack PaaS for Node + databases).",
4
4
  "link": "https://railway.com/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -32,7 +32,40 @@ export default function Header() {
32
32
  </Link>
33
33
  </h2>
34
34
 
35
- <div className="ml-auto flex items-center gap-1.5 sm:ml-0 sm:gap-2">
35
+ <div className="order-3 flex w-full flex-wrap items-center gap-x-4 gap-y-1 pb-1 text-sm font-semibold sm:order-none sm:w-auto sm:flex-nowrap sm:pb-0">
36
+ <Link to="/" className="nav-link" activeProps={{ className: 'nav-link is-active' }}>
37
+ Home
38
+ </Link>
39
+ <Link
40
+ to="/about"
41
+ className="nav-link"
42
+ activeProps={{ className: 'nav-link is-active' }}
43
+ >
44
+ About
45
+ </Link>
46
+ <a
47
+ href="https://tanstack.com/start/latest/docs/framework/react/overview"
48
+ className="nav-link"
49
+ target="_blank"
50
+ rel="noreferrer"
51
+ >
52
+ Docs
53
+ </a>
54
+ <% if (demoRoutes.length > 0) { %><details className="relative w-full sm:w-auto">
55
+ <summary className="nav-link list-none cursor-pointer">Demos</summary>
56
+ <div className="mt-2 min-w-56 rounded-xl border border-[var(--line)] bg-[var(--header-bg)] p-2 shadow-lg sm:absolute sm:right-0">
57
+ <% for (const route of demoRoutes) { %><a
58
+ href="<%= route.url %>"
59
+ className="block rounded-lg px-3 py-2 text-sm text-[var(--sea-ink-soft)] no-underline transition hover:bg-[var(--link-bg-hover)] hover:text-[var(--sea-ink)]"
60
+ >
61
+ <%= route.name %>
62
+ </a>
63
+ <% } %>
64
+ </div>
65
+ </details><% } %>
66
+ </div>
67
+
68
+ <div className="ml-auto flex items-center gap-1.5 sm:gap-2">
36
69
  <a
37
70
  href="https://x.com/tan_stack"
38
71
  target="_blank"
@@ -65,39 +98,6 @@ export default function Header() {
65
98
  <% } %>
66
99
  <ThemeToggle />
67
100
  </div>
68
-
69
- <div className="order-3 flex w-full flex-wrap items-center gap-x-4 gap-y-1 pb-1 text-sm font-semibold sm:order-2 sm:w-auto sm:flex-nowrap sm:pb-0">
70
- <Link to="/" className="nav-link" activeProps={{ className: 'nav-link is-active' }}>
71
- Home
72
- </Link>
73
- <Link
74
- to="/about"
75
- className="nav-link"
76
- activeProps={{ className: 'nav-link is-active' }}
77
- >
78
- About
79
- </Link>
80
- <a
81
- href="https://tanstack.com/start/latest/docs/framework/react/overview"
82
- className="nav-link"
83
- target="_blank"
84
- rel="noreferrer"
85
- >
86
- Docs
87
- </a>
88
- <% if (demoRoutes.length > 0) { %><details className="relative w-full sm:w-auto">
89
- <summary className="nav-link list-none cursor-pointer">Demos</summary>
90
- <div className="mt-2 min-w-56 rounded-xl border border-[var(--line)] bg-[var(--header-bg)] p-2 shadow-lg sm:absolute sm:right-0">
91
- <% for (const route of demoRoutes) { %><a
92
- href="<%= route.url %>"
93
- className="block rounded-lg px-3 py-2 text-sm text-[var(--sea-ink-soft)] no-underline transition hover:bg-[var(--link-bg-hover)] hover:text-[var(--sea-ink)]"
94
- >
95
- <%= route.name %>
96
- </a>
97
- <% } %>
98
- </div>
99
- </details><% } %>
100
- </div>
101
101
  </nav>
102
102
  </header>
103
103
  )
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Better Auth",
3
- "description": "Add Better Auth authentication to your application.",
3
+ "description": "Self-hosted user accounts and sessions (open source, full control).",
4
4
  "phase": "add-on",
5
5
  "type": "add-on",
6
6
  "category": "auth",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Convex",
3
- "description": "Add the Convex database to your application.",
3
+ "description": "Reactive document database with real-time queries and serverless functions.",
4
4
  "link": "https://convex.dev",
5
5
  "phase": "add-on",
6
6
  "type": "add-on",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Solid-UI",
3
- "description": "Add Solid-UI to your application.",
3
+ "description": "Copy-paste accessible UI components for Solid (Tailwind + Radix-style primitives).",
4
4
  "phase": "add-on",
5
5
  "link": "https://ui.shadcn.com/",
6
6
  "modes": ["file-router", "code-router"],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Strapi",
3
- "description": "Use the Strapi CMS to manage your content.",
3
+ "description": "Headless CMS with admin UI (self-hosted, content models in TypeScript).",
4
4
  "link": "https://strapi.io/",
5
5
  "phase": "add-on",
6
6
  "type": "add-on",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "T3Env",
3
- "description": "Add type safety to your environment variables",
3
+ "description": "Validate process.env at build time (catch missing/wrong env vars before runtime).",
4
4
  "phase": "add-on",
5
5
  "link": "https://github.com/t3-oss/t3-env",
6
6
  "type": "add-on",
@@ -0,0 +1,11 @@
1
+ ## Deploy to Cloudflare Workers
2
+
3
+ This project uses the Cloudflare Vite plugin (configured in `vite.config.ts`) and `wrangler.jsonc`:
4
+
5
+ 1. Install Wrangler: `npm install -g wrangler`
6
+ 2. Authenticate: `wrangler login`
7
+ 3. Deploy: `npx wrangler deploy`
8
+
9
+ For production env vars, run `wrangler secret put MY_VAR` for each secret listed in `.env.example`. Public (non-secret) vars go in `wrangler.jsonc` under `vars`.
10
+
11
+ KV, D1, R2, and Durable Object bindings are configured in `wrangler.jsonc` — see https://developers.cloudflare.com/workers/wrangler/configuration/.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Cloudflare",
3
- "description": "Cloudflare deployment setup",
3
+ "description": "Deploy to Cloudflare Workers (edge runtime, KV/D1/R2 bindings).",
4
4
  "link": "https://developers.cloudflare.com/workers/vite-plugin/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,11 @@
1
+ ## Deploy to Netlify
2
+
3
+ This project ships with `netlify.toml` configured for a Netlify site:
4
+
5
+ 1. Push this repo to GitHub
6
+ 2. Visit https://app.netlify.com/start and import the repo
7
+ 3. Netlify auto-detects the build (`vite build` → `dist/client`)
8
+ 4. Open **Site settings → Environment variables** and add anything from `.env.example` that needs a real value in production
9
+ 5. Trigger the first deploy
10
+
11
+ Server functions and API routes run on Netlify Functions. For lower-latency request handling, see Netlify Edge Functions: https://docs.netlify.com/edge-functions/overview.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Netlify",
3
- "description": "Netlify deployment setup",
3
+ "description": "Deploy to Netlify (Functions and Edge Functions, GitHub-driven).",
4
4
  "link": "https://docs.netlify.com",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,12 @@
1
+ ## Deploy with Nitro
2
+
3
+ This project uses Nitro as a generic server adapter, so it can run on any Node-compatible host.
4
+
5
+ ```bash
6
+ npm run build
7
+ node dist/server/index.mjs
8
+ ```
9
+
10
+ The build output is a self-contained Node server. To deploy, push the `dist/` directory to your host (Render, Fly.io, your own VPS, etc.) and run the server command above.
11
+
12
+ For host-specific presets (Vercel, Netlify, Cloudflare, AWS Lambda, etc.) and tuning, see https://v3.nitro.build/deploy.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Nitro (agnostic)",
3
- "description": "Nitro deployment setup",
3
+ "description": "Generic Nitro adapter (deploy to any Node-compatible host).",
4
4
  "link": "https://v3.nitro.build/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,10 @@
1
+ ## Deploy to Railway
2
+
3
+ This project ships with `nixpacks.toml` so Railway detects the build automatically:
4
+
5
+ 1. Push this repo to GitHub
6
+ 2. Visit https://railway.com/new and create a project from your repo
7
+ 3. In the **Variables** tab, add the entries from `.env.example` with their production values
8
+ 4. Railway runs `vite build` and serves from `dist/client`
9
+
10
+ Need a database? Click **+ New** in your project to provision Postgres, MySQL, or Redis directly into the same environment — the connection string is auto-injected as `DATABASE_URL`.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Railway",
3
- "description": "Railway deployment setup",
3
+ "description": "Deploy to Railway (full-stack PaaS for Node + databases).",
4
4
  "link": "https://railway.com/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ export { CONFIG_FILE } from './constants.js';
14
14
  export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager, } from './package-manager.js';
15
15
  export { registerFramework, getFrameworkById, getFrameworkByName, getFrameworks, scanProjectDirectory, scanAddOnDirectories, __testRegisterFramework, __testClearFrameworks, } from './frameworks.js';
16
16
  export { writeConfigFileToEnvironment, readConfigFileFromEnvironment, readConfigFile, } from './config-file.js';
17
- export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, toCleanPath, } from './file-helpers.js';
17
+ export { cleanUpFiles, cleanUpFileArray, isDemoFilePath, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, toCleanPath, } from './file-helpers.js';
18
18
  export { formatCommand, handleSpecialURL } from './utils.js';
19
19
  export { initStarter, compileStarter } from './custom-add-ons/starter.js';
20
20
  export { initAddOn, compileAddOn, devAddOn } from './custom-add-ons/add-on.js';
@@ -12,7 +12,7 @@ export async function setupIntent(environment, targetDir, options) {
12
12
  message: 'Setting up TanStack Intent skill mappings...',
13
13
  });
14
14
  try {
15
- await packageManagerExecute(environment, resolve(targetDir), options.packageManager, '@tanstack/intent', ['install']);
15
+ await packageManagerExecute(environment, resolve(targetDir), options.packageManager, '@tanstack/intent', ['install', '--map']);
16
16
  environment.finishStep('setup-intent', 'TanStack Intent configured');
17
17
  s.stop('TanStack Intent configured');
18
18
  }
@@ -10,6 +10,7 @@ export declare function getBinaryFile(content: string): string | null;
10
10
  export declare function toCleanPath(absolutePath: string, baseDir: string): string;
11
11
  export declare function relativePath(from: string, to: string, stripExtension?: boolean): string;
12
12
  export declare function isDirectory(path: string): boolean;
13
+ export declare function isDemoFilePath(path?: string): boolean;
13
14
  export declare function findFilesRecursively(path: string, files: Record<string, string>): void;
14
15
  export declare function recursivelyGatherFiles(path: string, includeProjectFiles?: boolean): Promise<Record<string, string>>;
15
16
  export declare function recursivelyGatherFilesFromEnvironment(environment: Environment, path: string, includeProjectFiles?: boolean): Promise<Record<string, string>>;
@@ -9,7 +9,7 @@ export { CONFIG_FILE } from './constants.js';
9
9
  export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager, } from './package-manager.js';
10
10
  export { registerFramework, getFrameworkById, getFrameworkByName, getFrameworks, scanProjectDirectory, scanAddOnDirectories, __testRegisterFramework, __testClearFrameworks, } from './frameworks.js';
11
11
  export { writeConfigFileToEnvironment, readConfigFileFromEnvironment, readConfigFile, } from './config-file.js';
12
- export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, toCleanPath, } from './file-helpers.js';
12
+ export { cleanUpFiles, cleanUpFileArray, isDemoFilePath, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, toCleanPath, } from './file-helpers.js';
13
13
  export { formatCommand, handleSpecialURL } from './utils.js';
14
14
  export { initStarter, compileStarter } from './custom-add-ons/starter.js';
15
15
  export { initAddOn, compileAddOn, devAddOn } from './custom-add-ons/add-on.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/create",
3
- "version": "0.64.0",
3
+ "version": "0.66.0",
4
4
  "description": "TanStack Application Builder Engine",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/create-app.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { basename, resolve } from 'node:path'
2
2
 
3
- import { isBase64 } from './file-helpers.js'
3
+ import { isBase64, isDemoFilePath } from './file-helpers.js'
4
4
  import { formatCommand } from './utils.js'
5
5
  import { writeConfigFileToEnvironment } from './config-file.js'
6
6
  import {
@@ -18,26 +18,6 @@ import { runSpecialSteps } from './special-steps/index.js'
18
18
 
19
19
  import type { Environment, FileBundleHandler, Options } from './types.js'
20
20
 
21
- function isDemoFilePath(path?: string) {
22
- if (!path) return false
23
- const normalized = path.replace(/\\/g, '/')
24
-
25
- if (
26
- normalized.includes('/routes/demo/') ||
27
- normalized.includes('/routes/example/')
28
- ) {
29
- return true
30
- }
31
-
32
- const filename = normalized.split('/').pop() || ''
33
- return (
34
- filename.startsWith('demo.') ||
35
- filename.startsWith('demo-') ||
36
- filename.startsWith('example.') ||
37
- filename.startsWith('example-')
38
- )
39
- }
40
-
41
21
  function stripExamplesFromOptions(options: Options): Options {
42
22
  if (options.includeExamples !== false) {
43
23
  return options
@@ -325,6 +305,87 @@ async function seedEnvValues(environment: Environment, options: Options) {
325
305
  await environment.writeFile(envLocalPath, envContents)
326
306
  }
327
307
 
308
+ async function writeEnvExample(environment: Environment, options: Options) {
309
+ const envExamplePath = resolve(options.targetDir, '.env.example')
310
+ const existing = environment.exists(envExamplePath)
311
+ ? await environment.readFile(envExamplePath)
312
+ : ''
313
+
314
+ const declared = new Set<string>()
315
+ for (const match of existing.matchAll(/^([A-Z_][A-Z0-9_]*)=/gm)) {
316
+ declared.add(match[1])
317
+ }
318
+
319
+ const sections: Array<string> = []
320
+ for (const addOn of options.chosenAddOns) {
321
+ const lines: Array<string> = []
322
+ for (const envVar of addOn.envVars || []) {
323
+ if (declared.has(envVar.name)) continue
324
+ declared.add(envVar.name)
325
+ if (envVar.description) {
326
+ const required = envVar.required ? ' (required)' : ''
327
+ lines.push(`# ${envVar.description}${required}`)
328
+ }
329
+ lines.push(`${envVar.name}=`)
330
+ }
331
+ if (lines.length > 0) {
332
+ sections.push(`# ${addOn.name}\n${lines.join('\n')}`)
333
+ }
334
+ }
335
+
336
+ if (sections.length === 0) return
337
+
338
+ const additions = sections.join('\n\n')
339
+ const newContent = existing
340
+ ? `${existing.trimEnd()}\n\n${additions}\n`
341
+ : `${additions}\n`
342
+
343
+ await environment.writeFile(envExamplePath, newContent)
344
+ }
345
+
346
+ const SHIPPING_CATEGORIES = new Set(['auth', 'database', 'orm', 'deploy'])
347
+
348
+ function buildNextSteps(options: Options): string {
349
+ const collectedEnv = new Set(Object.keys(options.envVarValues || {}))
350
+ const listedEnvVars = new Set<string>()
351
+ const envVarLines: Array<string> = []
352
+ const docLines: Array<string> = []
353
+
354
+ for (const addOn of options.chosenAddOns) {
355
+ if (addOn.link && addOn.category && SHIPPING_CATEGORIES.has(addOn.category)) {
356
+ docLines.push(` • ${addOn.name} (${addOn.category}) — ${addOn.link}`)
357
+ }
358
+
359
+ for (const envVar of addOn.envVars || []) {
360
+ if (listedEnvVars.has(envVar.name)) continue
361
+ listedEnvVars.add(envVar.name)
362
+ const required = envVar.required ? ' (required)' : ''
363
+ const status = collectedEnv.has(envVar.name)
364
+ ? ' — already set from your input'
365
+ : ' — needs a value'
366
+ const desc = envVar.description ? ` — ${envVar.description}` : ''
367
+ envVarLines.push(` • ${envVar.name}${required}${desc}${status}`)
368
+ }
369
+ }
370
+
371
+ const sections: Array<string> = []
372
+ if (envVarLines.length > 0) {
373
+ sections.push(
374
+ `Environment variables (review/fill in .env.local before deploying):\n${envVarLines.join('\n')}`,
375
+ )
376
+ }
377
+ if (docLines.length > 0) {
378
+ sections.push(`Docs for the integrations you picked:\n${docLines.join('\n')}`)
379
+ }
380
+ if (options.intent) {
381
+ sections.push(
382
+ `Working with an AI agent? Your agent config (AGENTS.md / CLAUDE.md) was wired up by TanStack Intent\nwith explicit skill mappings for the libraries you installed. Try asking your agent:\n • "migrate this Next.js page to TanStack Start"\n • "add a protected /dashboard route"\n • "show me how to use TanStack Router search params"`,
383
+ )
384
+ }
385
+
386
+ return sections.length > 0 ? `\nNext steps:\n\n${sections.join('\n\n')}\n` : ''
387
+ }
388
+
328
389
  function report(environment: Environment, options: Options) {
329
390
  const warnings: Array<string> = []
330
391
  for (const addOn of options.chosenAddOns) {
@@ -358,6 +419,8 @@ ${environment.getErrors().join('\n')}`
358
419
  : `% cd ${options.projectName}
359
420
  `
360
421
 
422
+ const nextSteps = buildNextSteps(options)
423
+
361
424
  // Use the force luke! :)
362
425
  environment.outro(
363
426
  `${locationMessage}
@@ -366,7 +429,7 @@ Use the following commands to start your app:
366
429
  ${cdInstruction}% ${formatCommand(
367
430
  getPackageManagerScriptCommand(options.packageManager, ['dev']),
368
431
  )}
369
-
432
+ ${nextSteps}
370
433
  Please read the README.md file for information on testing, styling, adding routes, etc.${errorStatement}`,
371
434
  )
372
435
  }
@@ -377,6 +440,7 @@ export async function createApp(environment: Environment, options: Options) {
377
440
  environment.startRun()
378
441
  await writeFiles(environment, effectiveOptions)
379
442
  await seedEnvValues(environment, effectiveOptions)
443
+ await writeEnvExample(environment, effectiveOptions)
380
444
  await runCommandsAndInstallDependencies(environment, effectiveOptions)
381
445
  environment.finishRun()
382
446
 
@@ -112,6 +112,26 @@ export function isDirectory(path: string): boolean {
112
112
  return statSync(path).isDirectory()
113
113
  }
114
114
 
115
+ export function isDemoFilePath(path?: string): boolean {
116
+ if (!path) return false
117
+ const normalized = path.replace(/\\/g, '/')
118
+
119
+ if (
120
+ normalized.includes('/routes/demo/') ||
121
+ normalized.includes('/routes/example/')
122
+ ) {
123
+ return true
124
+ }
125
+
126
+ const filename = normalized.split('/').pop() || ''
127
+ return (
128
+ filename.startsWith('demo.') ||
129
+ filename.startsWith('demo-') ||
130
+ filename.startsWith('example.') ||
131
+ filename.startsWith('example-')
132
+ )
133
+ }
134
+
115
135
  export function findFilesRecursively(
116
136
  path: string,
117
137
  files: Record<string, string>,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "AI",
3
- "description": "TanStack AI integration and examples.",
3
+ "description": "Streaming chat UI with model-agnostic backend (OpenAI, Anthropic, etc).",
4
4
  "phase": "add-on",
5
5
  "modes": ["file-router"],
6
6
  "type": "add-on",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Better Auth",
3
- "description": "Add Better Auth authentication to your application.",
3
+ "description": "Self-hosted user accounts and sessions (open source, full control).",
4
4
  "phase": "add-on",
5
5
  "type": "add-on",
6
6
  "category": "auth",