diff --git a/templates/start-app/.cta.json b/templates/start-app/.cta.json new file mode 100644 index 000000000..66693b519 --- /dev/null +++ b/templates/start-app/.cta.json @@ -0,0 +1,16 @@ +{ + "projectName": "start-app", + "mode": "file-router", + "typescript": true, + "tailwind": true, + "packageManager": "pnpm", + "addOnOptions": {}, + "git": true, + "version": 1, + "framework": "react-cra", + "chosenAddOns": [ + "eslint", + "nitro", + "start" + ] +} \ No newline at end of file diff --git a/templates/start-app/.gitignore b/templates/start-app/.gitignore new file mode 100644 index 000000000..6221ecbd0 --- /dev/null +++ b/templates/start-app/.gitignore @@ -0,0 +1,13 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local +count.txt +.env +.nitro +.tanstack +.wrangler +.output +.vinxi +todos.json diff --git a/templates/start-app/.prettierignore b/templates/start-app/.prettierignore new file mode 100644 index 000000000..5322d7fee --- /dev/null +++ b/templates/start-app/.prettierignore @@ -0,0 +1,3 @@ +package-lock.json +pnpm-lock.yaml +yarn.lock \ No newline at end of file diff --git a/templates/start-app/README.md b/templates/start-app/README.md new file mode 100644 index 000000000..115a35f22 --- /dev/null +++ b/templates/start-app/README.md @@ -0,0 +1,3 @@ +# TanStack Start + shadcn/ui + +This is a template for a new TanStack Start project with React, TypeScript, and shadcn/ui. diff --git a/templates/start-app/eslint.config.js b/templates/start-app/eslint.config.js new file mode 100644 index 000000000..676b32a87 --- /dev/null +++ b/templates/start-app/eslint.config.js @@ -0,0 +1,5 @@ +// @ts-check + +import { tanstackConfig } from '@tanstack/eslint-config' + +export default [...tanstackConfig] diff --git a/templates/start-app/package.json b/templates/start-app/package.json new file mode 100644 index 000000000..6b571f9ca --- /dev/null +++ b/templates/start-app/package.json @@ -0,0 +1,44 @@ +{ + "name": "start-app", + "private": true, + "type": "module", + "scripts": { + "dev": "vite dev --port 3000", + "build": "vite build", + "preview": "vite preview", + "test": "vitest run", + "lint": "eslint", + "format": "prettier", + "check": "prettier --write . && eslint --fix" + }, + "dependencies": { + "@tailwindcss/vite": "^4.0.6", + "@tanstack/react-devtools": "^0.7.0", + "@tanstack/react-router": "^1.132.0", + "@tanstack/react-router-devtools": "^1.132.0", + "@tanstack/react-router-ssr-query": "^1.131.7", + "@tanstack/react-start": "^1.132.0", + "@tanstack/router-plugin": "^1.132.0", + "nitro": "latest", + "react": "^19.2.0", + "react-dom": "^19.2.0", + "tailwindcss": "^4.0.6", + "vite-tsconfig-paths": "^5.1.4" + }, + "devDependencies": { + "@tanstack/devtools-vite": "^0.3.11", + "@tanstack/eslint-config": "^0.3.0", + "@testing-library/dom": "^10.4.0", + "@testing-library/react": "^16.2.0", + "@types/node": "^22.10.2", + "@types/react": "^19.2.0", + "@types/react-dom": "^19.2.0", + "@vitejs/plugin-react": "^5.0.4", + "jsdom": "^27.0.0", + "prettier": "^3.5.3", + "typescript": "^5.7.2", + "vite": "^7.1.7", + "vitest": "^3.0.5", + "web-vitals": "^5.1.0" + } +} diff --git a/templates/start-app/prettier.config.js b/templates/start-app/prettier.config.js new file mode 100644 index 000000000..aea1c4804 --- /dev/null +++ b/templates/start-app/prettier.config.js @@ -0,0 +1,10 @@ +// @ts-check + +/** @type {import('prettier').Config} */ +const config = { + semi: false, + singleQuote: true, + trailingComma: "all", +}; + +export default config; diff --git a/templates/start-app/public/favicon.ico b/templates/start-app/public/favicon.ico new file mode 100644 index 000000000..a11777cc4 Binary files /dev/null and b/templates/start-app/public/favicon.ico differ diff --git a/templates/start-app/public/logo192.png b/templates/start-app/public/logo192.png new file mode 100644 index 000000000..fc44b0a37 Binary files /dev/null and b/templates/start-app/public/logo192.png differ diff --git a/templates/start-app/public/logo512.png b/templates/start-app/public/logo512.png new file mode 100644 index 000000000..a4e47a654 Binary files /dev/null and b/templates/start-app/public/logo512.png differ diff --git a/templates/start-app/public/manifest.json b/templates/start-app/public/manifest.json new file mode 100644 index 000000000..078ef5011 --- /dev/null +++ b/templates/start-app/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "TanStack App", + "name": "Create TanStack App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/templates/start-app/public/robots.txt b/templates/start-app/public/robots.txt new file mode 100644 index 000000000..e9e57dc4d --- /dev/null +++ b/templates/start-app/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/templates/start-app/public/tanstack-circle-logo.png b/templates/start-app/public/tanstack-circle-logo.png new file mode 100644 index 000000000..9db3e67ba Binary files /dev/null and b/templates/start-app/public/tanstack-circle-logo.png differ diff --git a/templates/start-app/public/tanstack-word-logo-white.svg b/templates/start-app/public/tanstack-word-logo-white.svg new file mode 100644 index 000000000..b6ec5086c --- /dev/null +++ b/templates/start-app/public/tanstack-word-logo-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/start-app/src/logo.svg b/templates/start-app/src/logo.svg new file mode 100644 index 000000000..fe53fe8d0 --- /dev/null +++ b/templates/start-app/src/logo.svg @@ -0,0 +1,12 @@ + + + logo + + \ No newline at end of file diff --git a/templates/start-app/src/routeTree.gen.ts b/templates/start-app/src/routeTree.gen.ts new file mode 100644 index 000000000..dceedffdc --- /dev/null +++ b/templates/start-app/src/routeTree.gen.ts @@ -0,0 +1,68 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as IndexRouteImport } from './routes/index' + +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' + fileRoutesByTo: FileRoutesByTo + to: '/' + id: '__root__' | '/' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/react-start' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited> + } +} diff --git a/templates/start-app/src/router.tsx b/templates/start-app/src/router.tsx new file mode 100644 index 000000000..efee944f9 --- /dev/null +++ b/templates/start-app/src/router.tsx @@ -0,0 +1,15 @@ +import { createRouter } from '@tanstack/react-router' + +// Import the generated route tree +import { routeTree } from './routeTree.gen' + +// Create a new router instance +export const getRouter = () => { + const router = createRouter({ + routeTree, + scrollRestoration: true, + defaultPreloadStaleTime: 0, + }) + + return router +} diff --git a/templates/start-app/src/routes/__root.tsx b/templates/start-app/src/routes/__root.tsx new file mode 100644 index 000000000..1810d79e6 --- /dev/null +++ b/templates/start-app/src/routes/__root.tsx @@ -0,0 +1,55 @@ +import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router' +import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools' +import { TanStackDevtools } from '@tanstack/react-devtools' + +import appCss from '../styles.css?url' + +export const Route = createRootRoute({ + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + { + title: 'TanStack Start Starter', + }, + ], + links: [ + { + rel: 'stylesheet', + href: appCss, + }, + ], + }), + + shellComponent: RootDocument, +}) + +function RootDocument({ children }: { children: React.ReactNode }) { + return ( + + + + + + {children} + , + }, + ]} + /> + + + + ) +} diff --git a/templates/start-app/src/routes/index.tsx b/templates/start-app/src/routes/index.tsx new file mode 100644 index 000000000..8f26ade19 --- /dev/null +++ b/templates/start-app/src/routes/index.tsx @@ -0,0 +1,11 @@ +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/")({ component: App }); + +function App() { + return ( +
+
Hello World
+
+ ); +} diff --git a/templates/start-app/src/styles.css b/templates/start-app/src/styles.css new file mode 100644 index 000000000..f1d8c73cd --- /dev/null +++ b/templates/start-app/src/styles.css @@ -0,0 +1 @@ +@import "tailwindcss"; diff --git a/templates/start-app/tsconfig.json b/templates/start-app/tsconfig.json new file mode 100644 index 000000000..0b0985e66 --- /dev/null +++ b/templates/start-app/tsconfig.json @@ -0,0 +1,29 @@ +{ + "include": ["**/*.ts", "**/*.tsx", "eslint.config.js", "prettier.config.js", "vite.config.js"], + + "compilerOptions": { + "target": "ES2022", + "jsx": "react-jsx", + "module": "ESNext", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "types": ["vite/client"], + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": false, + "noEmit": true, + + /* Linting */ + "skipLibCheck": true, + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/templates/start-app/vite.config.ts b/templates/start-app/vite.config.ts new file mode 100644 index 000000000..5294ebcaf --- /dev/null +++ b/templates/start-app/vite.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'vite' +import { devtools } from '@tanstack/devtools-vite' +import { tanstackStart } from '@tanstack/react-start/plugin/vite' +import viteReact from '@vitejs/plugin-react' +import viteTsConfigPaths from 'vite-tsconfig-paths' +import tailwindcss from '@tailwindcss/vite' +import { nitro } from 'nitro/vite' + +const config = defineConfig({ + plugins: [ + devtools(), + nitro(), + // this is the plugin that enables path aliases + viteTsConfigPaths({ + projects: ['./tsconfig.json'], + }), + tailwindcss(), + tanstackStart(), + viteReact(), + ], +}) + +export default config