virastack 0.0.1 → 1.0.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.
- package/LICENSE +1 -1
- package/README.md +94 -18
- package/bin/virastack.js +7 -0
- package/package.json +43 -9
- package/src/commands/add.js +64 -0
- package/src/commands/init.js +286 -0
- package/src/i18n.js +231 -0
- package/src/index.js +64 -0
- package/src/utils/args.js +60 -0
- package/src/utils/copy-template.js +80 -0
- package/src/utils/exec.js +29 -0
- package/src/utils/git.js +38 -0
- package/src/utils/is-online.js +14 -0
- package/src/utils/package-info.js +12 -0
- package/src/utils/package-manager.js +33 -0
- package/src/utils/setup-env.js +25 -0
- package/src/utils/telemetry.js +86 -0
- package/src/utils/tools.js +48 -0
- package/src/utils/update-package-json.js +44 -0
- package/src/utils/update-readme.js +25 -0
- package/src/utils/validate-project-name.js +26 -0
- package/templates/nextjs/.changeset/README.md +8 -0
- package/templates/nextjs/.changeset/config.json +11 -0
- package/templates/nextjs/.env.example +6 -0
- package/templates/nextjs/.github/workflows/ci.yml +41 -0
- package/templates/nextjs/.husky/commit-msg +1 -0
- package/templates/nextjs/.husky/pre-commit +1 -0
- package/templates/nextjs/.husky/pre-push +1 -0
- package/templates/nextjs/.prettierignore +6 -0
- package/templates/nextjs/.prettierrc +42 -0
- package/templates/nextjs/.vscode/extensions.json +7 -0
- package/templates/nextjs/.vscode/settings.json +20 -0
- package/templates/nextjs/LICENSE +21 -0
- package/templates/nextjs/README.md +202 -0
- package/templates/nextjs/commitlint.config.js +6 -0
- package/templates/nextjs/eslint.config.mjs +27 -0
- package/templates/nextjs/knip.config.js +25 -0
- package/templates/nextjs/next.config.ts +39 -0
- package/templates/nextjs/package.json +115 -0
- package/templates/nextjs/pnpm-lock.yaml +6467 -0
- package/templates/nextjs/pnpm-workspace.yaml +3 -0
- package/templates/nextjs/postcss.config.mjs +7 -0
- package/templates/nextjs/public/favicon.ico +0 -0
- package/templates/nextjs/public/llms.txt +96 -0
- package/templates/nextjs/public/logo.png +0 -0
- package/templates/nextjs/public/logo.webp +0 -0
- package/templates/nextjs/public/og.png +0 -0
- package/templates/nextjs/src/app/error.tsx +34 -0
- package/templates/nextjs/src/app/favicon.ico +0 -0
- package/templates/nextjs/src/app/global-error.tsx +32 -0
- package/templates/nextjs/src/app/layout.tsx +37 -0
- package/templates/nextjs/src/app/loading.tsx +12 -0
- package/templates/nextjs/src/app/manifest.ts +22 -0
- package/templates/nextjs/src/app/not-found.tsx +18 -0
- package/templates/nextjs/src/app/page.tsx +5 -0
- package/templates/nextjs/src/app/robots.ts +13 -0
- package/templates/nextjs/src/app/sitemap.ts +14 -0
- package/templates/nextjs/src/components/shared/ThemeToggle.tsx +30 -0
- package/templates/nextjs/src/components/ui/avatar.tsx +54 -0
- package/templates/nextjs/src/components/ui/button.tsx +46 -0
- package/templates/nextjs/src/components/ui/dialog.tsx +107 -0
- package/templates/nextjs/src/components/ui/field.tsx +24 -0
- package/templates/nextjs/src/components/ui/index.ts +27 -0
- package/templates/nextjs/src/components/ui/input.tsx +23 -0
- package/templates/nextjs/src/components/ui/label.tsx +17 -0
- package/templates/nextjs/src/components/ui/skeleton.tsx +13 -0
- package/templates/nextjs/src/components/ui/table.tsx +94 -0
- package/templates/nextjs/src/components/ui/tabs.tsx +46 -0
- package/templates/nextjs/src/config/seo.config.ts +37 -0
- package/templates/nextjs/src/config/site.config.ts +15 -0
- package/templates/nextjs/src/constants/index.ts +5 -0
- package/templates/nextjs/src/env.ts +41 -0
- package/templates/nextjs/src/features/landing/api/get-users.api.ts +7 -0
- package/templates/nextjs/src/features/landing/api/index.ts +2 -0
- package/templates/nextjs/src/features/landing/api/query-keys.ts +7 -0
- package/templates/nextjs/src/features/landing/components/CartDemo.tsx +66 -0
- package/templates/nextjs/src/features/landing/components/Features.tsx +39 -0
- package/templates/nextjs/src/features/landing/components/Hero.tsx +65 -0
- package/templates/nextjs/src/features/landing/components/LandingPage.tsx +17 -0
- package/templates/nextjs/src/features/landing/components/ProjectFormDemo.tsx +62 -0
- package/templates/nextjs/src/features/landing/components/Reveal.tsx +83 -0
- package/templates/nextjs/src/features/landing/components/Showcase.tsx +66 -0
- package/templates/nextjs/src/features/landing/components/UsersDemo.tsx +188 -0
- package/templates/nextjs/src/features/landing/data/features.data.tsx +47 -0
- package/templates/nextjs/src/features/landing/data/index.ts +1 -0
- package/templates/nextjs/src/features/landing/helpers/get-initials.ts +15 -0
- package/templates/nextjs/src/features/landing/helpers/index.ts +7 -0
- package/templates/nextjs/src/features/landing/helpers/motion.ts +21 -0
- package/templates/nextjs/src/features/landing/hooks/index.ts +1 -0
- package/templates/nextjs/src/features/landing/hooks/use-users.ts +16 -0
- package/templates/nextjs/src/features/landing/icons/index.ts +6 -0
- package/templates/nextjs/src/features/landing/icons/nextjs.tsx +68 -0
- package/templates/nextjs/src/features/landing/icons/react-hook-form.tsx +18 -0
- package/templates/nextjs/src/features/landing/icons/react.tsx +20 -0
- package/templates/nextjs/src/features/landing/icons/tailwind.tsx +14 -0
- package/templates/nextjs/src/features/landing/icons/tanstack.tsx +321 -0
- package/templates/nextjs/src/features/landing/icons/typescript.tsx +16 -0
- package/templates/nextjs/src/features/landing/index.ts +1 -0
- package/templates/nextjs/src/features/landing/schemas/index.ts +1 -0
- package/templates/nextjs/src/features/landing/schemas/project.schema.ts +7 -0
- package/templates/nextjs/src/features/landing/stores/counter.store.ts +18 -0
- package/templates/nextjs/src/features/landing/stores/index.ts +1 -0
- package/templates/nextjs/src/features/landing/types/index.ts +1 -0
- package/templates/nextjs/src/features/landing/types/user.types.ts +9 -0
- package/templates/nextjs/src/helpers/format-date.ts +13 -0
- package/templates/nextjs/src/helpers/index.ts +1 -0
- package/templates/nextjs/src/hooks/index.ts +5 -0
- package/templates/nextjs/src/lib/api.ts +97 -0
- package/templates/nextjs/src/lib/query-client.ts +18 -0
- package/templates/nextjs/src/lib/utils.ts +12 -0
- package/templates/nextjs/src/providers/Providers.tsx +15 -0
- package/templates/nextjs/src/providers/QueryProvider.tsx +19 -0
- package/templates/nextjs/src/providers/ThemeProvider.tsx +9 -0
- package/templates/nextjs/src/providers/index.ts +1 -0
- package/templates/nextjs/src/proxy.ts +6 -0
- package/templates/nextjs/src/schemas/index.ts +5 -0
- package/templates/nextjs/src/stores/index.ts +5 -0
- package/templates/nextjs/src/styles/tailwind.css +122 -0
- package/templates/nextjs/src/types/site-config.types.ts +10 -0
- package/templates/nextjs/tsconfig.json +45 -0
- package/templates/tanstack/.changeset/README.md +8 -0
- package/templates/tanstack/.changeset/config.json +11 -0
- package/templates/tanstack/.env.example +6 -0
- package/templates/tanstack/.github/workflows/ci.yml +41 -0
- package/templates/tanstack/.husky/commit-msg +1 -0
- package/templates/tanstack/.husky/pre-commit +1 -0
- package/templates/tanstack/.husky/pre-push +1 -0
- package/templates/tanstack/.prettierignore +7 -0
- package/templates/tanstack/.prettierrc +41 -0
- package/templates/tanstack/.vscode/extensions.json +7 -0
- package/templates/tanstack/.vscode/settings.json +22 -0
- package/templates/tanstack/LICENSE +21 -0
- package/templates/tanstack/README.md +204 -0
- package/templates/tanstack/commitlint.config.js +6 -0
- package/templates/tanstack/eslint.config.js +28 -0
- package/templates/tanstack/knip.config.js +22 -0
- package/templates/tanstack/package.json +130 -0
- package/templates/tanstack/pnpm-lock.yaml +5835 -0
- package/templates/tanstack/pnpm-workspace.yaml +3 -0
- package/templates/tanstack/public/favicon.ico +0 -0
- package/templates/tanstack/public/llms.txt +86 -0
- package/templates/tanstack/public/logo.png +0 -0
- package/templates/tanstack/public/logo.webp +0 -0
- package/templates/tanstack/public/og.png +0 -0
- package/templates/tanstack/src/components/shared/DefaultCatchBoundary.tsx +36 -0
- package/templates/tanstack/src/components/shared/NotFound.tsx +18 -0
- package/templates/tanstack/src/components/shared/Pending.tsx +13 -0
- package/templates/tanstack/src/components/shared/ThemeToggle.tsx +31 -0
- package/templates/tanstack/src/components/ui/avatar.tsx +52 -0
- package/templates/tanstack/src/components/ui/button.tsx +47 -0
- package/templates/tanstack/src/components/ui/dialog.tsx +107 -0
- package/templates/tanstack/src/components/ui/field.tsx +24 -0
- package/templates/tanstack/src/components/ui/index.ts +27 -0
- package/templates/tanstack/src/components/ui/input.tsx +23 -0
- package/templates/tanstack/src/components/ui/label.tsx +17 -0
- package/templates/tanstack/src/components/ui/skeleton.tsx +13 -0
- package/templates/tanstack/src/components/ui/table.tsx +94 -0
- package/templates/tanstack/src/components/ui/tabs.tsx +46 -0
- package/templates/tanstack/src/config/seo.config.ts +52 -0
- package/templates/tanstack/src/config/site.config.ts +15 -0
- package/templates/tanstack/src/constants/index.ts +5 -0
- package/templates/tanstack/src/env.ts +47 -0
- package/templates/tanstack/src/features/landing/api/get-users.api.ts +7 -0
- package/templates/tanstack/src/features/landing/api/index.ts +2 -0
- package/templates/tanstack/src/features/landing/api/query-keys.ts +7 -0
- package/templates/tanstack/src/features/landing/components/CartDemo.tsx +66 -0
- package/templates/tanstack/src/features/landing/components/Features.tsx +39 -0
- package/templates/tanstack/src/features/landing/components/Hero.tsx +63 -0
- package/templates/tanstack/src/features/landing/components/LandingPage.tsx +17 -0
- package/templates/tanstack/src/features/landing/components/ProjectFormDemo.tsx +63 -0
- package/templates/tanstack/src/features/landing/components/Reveal.tsx +83 -0
- package/templates/tanstack/src/features/landing/components/Showcase.tsx +66 -0
- package/templates/tanstack/src/features/landing/components/UsersDemo.tsx +191 -0
- package/templates/tanstack/src/features/landing/data/features.data.tsx +45 -0
- package/templates/tanstack/src/features/landing/data/index.ts +1 -0
- package/templates/tanstack/src/features/landing/helpers/get-initials.ts +15 -0
- package/templates/tanstack/src/features/landing/helpers/index.ts +7 -0
- package/templates/tanstack/src/features/landing/helpers/motion.ts +21 -0
- package/templates/tanstack/src/features/landing/hooks/index.ts +1 -0
- package/templates/tanstack/src/features/landing/hooks/use-users.ts +19 -0
- package/templates/tanstack/src/features/landing/icons/index.ts +5 -0
- package/templates/tanstack/src/features/landing/icons/react-hook-form.tsx +18 -0
- package/templates/tanstack/src/features/landing/icons/react.tsx +20 -0
- package/templates/tanstack/src/features/landing/icons/tailwind.tsx +14 -0
- package/templates/tanstack/src/features/landing/icons/tanstack.tsx +321 -0
- package/templates/tanstack/src/features/landing/icons/typescript.tsx +16 -0
- package/templates/tanstack/src/features/landing/index.ts +1 -0
- package/templates/tanstack/src/features/landing/schemas/index.ts +1 -0
- package/templates/tanstack/src/features/landing/schemas/project.schema.ts +7 -0
- package/templates/tanstack/src/features/landing/stores/counter.store.ts +18 -0
- package/templates/tanstack/src/features/landing/stores/index.ts +1 -0
- package/templates/tanstack/src/features/landing/types/index.ts +1 -0
- package/templates/tanstack/src/features/landing/types/user.types.ts +9 -0
- package/templates/tanstack/src/helpers/format-date.ts +13 -0
- package/templates/tanstack/src/helpers/index.ts +1 -0
- package/templates/tanstack/src/hooks/index.ts +5 -0
- package/templates/tanstack/src/lib/api.ts +97 -0
- package/templates/tanstack/src/lib/query-client.ts +18 -0
- package/templates/tanstack/src/lib/utils.ts +13 -0
- package/templates/tanstack/src/providers/Providers.tsx +12 -0
- package/templates/tanstack/src/providers/ThemeProvider.tsx +98 -0
- package/templates/tanstack/src/providers/devtools.tsx +6 -0
- package/templates/tanstack/src/providers/index.ts +1 -0
- package/templates/tanstack/src/providers/root-provider.ts +9 -0
- package/templates/tanstack/src/routeTree.gen.ts +123 -0
- package/templates/tanstack/src/router.tsx +27 -0
- package/templates/tanstack/src/routes/__root.tsx +78 -0
- package/templates/tanstack/src/routes/index.tsx +13 -0
- package/templates/tanstack/src/routes/robots[.]txt.ts +21 -0
- package/templates/tanstack/src/routes/site[.]webmanifest.ts +32 -0
- package/templates/tanstack/src/routes/sitemap[.]xml.ts +27 -0
- package/templates/tanstack/src/schemas/index.ts +5 -0
- package/templates/tanstack/src/start.ts +20 -0
- package/templates/tanstack/src/stores/index.ts +5 -0
- package/templates/tanstack/src/styles/tailwind.css +123 -0
- package/templates/tanstack/src/types/site-config.types.ts +10 -0
- package/templates/tanstack/tsconfig.json +25 -0
- package/templates/tanstack/tsr.config.json +3 -0
- package/templates/tanstack/vite.config.ts +12 -0
- package/templates-i18n/nextjs/.changeset/README.md +8 -0
- package/templates-i18n/nextjs/.changeset/config.json +11 -0
- package/templates-i18n/nextjs/.env.example +6 -0
- package/templates-i18n/nextjs/.github/workflows/ci.yml +41 -0
- package/templates-i18n/nextjs/.husky/commit-msg +1 -0
- package/templates-i18n/nextjs/.husky/pre-commit +1 -0
- package/templates-i18n/nextjs/.husky/pre-push +1 -0
- package/templates-i18n/nextjs/.prettierignore +6 -0
- package/templates-i18n/nextjs/.prettierrc +42 -0
- package/templates-i18n/nextjs/.vscode/extensions.json +7 -0
- package/templates-i18n/nextjs/.vscode/settings.json +20 -0
- package/templates-i18n/nextjs/LICENSE +21 -0
- package/templates-i18n/nextjs/README.md +202 -0
- package/templates-i18n/nextjs/commitlint.config.js +6 -0
- package/templates-i18n/nextjs/eslint.config.mjs +27 -0
- package/templates-i18n/nextjs/knip.config.js +29 -0
- package/templates-i18n/nextjs/next.config.ts +42 -0
- package/templates-i18n/nextjs/package.json +117 -0
- package/templates-i18n/nextjs/pnpm-lock.yaml +6854 -0
- package/templates-i18n/nextjs/pnpm-workspace.yaml +3 -0
- package/templates-i18n/nextjs/postcss.config.mjs +7 -0
- package/templates-i18n/nextjs/public/favicon.ico +0 -0
- package/templates-i18n/nextjs/public/llms.txt +96 -0
- package/templates-i18n/nextjs/public/logo.png +0 -0
- package/templates-i18n/nextjs/public/logo.webp +0 -0
- package/templates-i18n/nextjs/public/og.png +0 -0
- package/templates-i18n/nextjs/src/app/[locale]/error.tsx +34 -0
- package/templates-i18n/nextjs/src/app/[locale]/layout.tsx +60 -0
- package/templates-i18n/nextjs/src/app/[locale]/loading.tsx +12 -0
- package/templates-i18n/nextjs/src/app/[locale]/not-found.tsx +18 -0
- package/templates-i18n/nextjs/src/app/[locale]/page.tsx +10 -0
- package/templates-i18n/nextjs/src/app/favicon.ico +0 -0
- package/templates-i18n/nextjs/src/app/global-error.tsx +32 -0
- package/templates-i18n/nextjs/src/app/manifest.ts +22 -0
- package/templates-i18n/nextjs/src/app/robots.ts +13 -0
- package/templates-i18n/nextjs/src/app/sitemap.ts +14 -0
- package/templates-i18n/nextjs/src/components/shared/LanguageSwitcher.tsx +48 -0
- package/templates-i18n/nextjs/src/components/shared/ThemeToggle.tsx +30 -0
- package/templates-i18n/nextjs/src/components/ui/avatar.tsx +54 -0
- package/templates-i18n/nextjs/src/components/ui/button.tsx +46 -0
- package/templates-i18n/nextjs/src/components/ui/dialog.tsx +107 -0
- package/templates-i18n/nextjs/src/components/ui/field.tsx +24 -0
- package/templates-i18n/nextjs/src/components/ui/index.ts +27 -0
- package/templates-i18n/nextjs/src/components/ui/input.tsx +23 -0
- package/templates-i18n/nextjs/src/components/ui/label.tsx +17 -0
- package/templates-i18n/nextjs/src/components/ui/skeleton.tsx +13 -0
- package/templates-i18n/nextjs/src/components/ui/table.tsx +94 -0
- package/templates-i18n/nextjs/src/components/ui/tabs.tsx +46 -0
- package/templates-i18n/nextjs/src/config/seo.config.ts +37 -0
- package/templates-i18n/nextjs/src/config/site.config.ts +15 -0
- package/templates-i18n/nextjs/src/constants/index.ts +5 -0
- package/templates-i18n/nextjs/src/env.ts +41 -0
- package/templates-i18n/nextjs/src/features/landing/api/get-users.api.ts +7 -0
- package/templates-i18n/nextjs/src/features/landing/api/index.ts +2 -0
- package/templates-i18n/nextjs/src/features/landing/api/query-keys.ts +7 -0
- package/templates-i18n/nextjs/src/features/landing/components/CartDemo.tsx +68 -0
- package/templates-i18n/nextjs/src/features/landing/components/Features.tsx +84 -0
- package/templates-i18n/nextjs/src/features/landing/components/Hero.tsx +76 -0
- package/templates-i18n/nextjs/src/features/landing/components/LandingPage.tsx +17 -0
- package/templates-i18n/nextjs/src/features/landing/components/ProjectFormDemo.tsx +64 -0
- package/templates-i18n/nextjs/src/features/landing/components/Reveal.tsx +83 -0
- package/templates-i18n/nextjs/src/features/landing/components/Showcase.tsx +83 -0
- package/templates-i18n/nextjs/src/features/landing/components/UsersDemo.tsx +191 -0
- package/templates-i18n/nextjs/src/features/landing/data/features.data.tsx +47 -0
- package/templates-i18n/nextjs/src/features/landing/data/index.ts +1 -0
- package/templates-i18n/nextjs/src/features/landing/helpers/get-initials.ts +15 -0
- package/templates-i18n/nextjs/src/features/landing/helpers/index.ts +7 -0
- package/templates-i18n/nextjs/src/features/landing/helpers/motion.ts +21 -0
- package/templates-i18n/nextjs/src/features/landing/hooks/index.ts +1 -0
- package/templates-i18n/nextjs/src/features/landing/hooks/use-users.ts +16 -0
- package/templates-i18n/nextjs/src/features/landing/icons/index.ts +6 -0
- package/templates-i18n/nextjs/src/features/landing/icons/nextjs.tsx +68 -0
- package/templates-i18n/nextjs/src/features/landing/icons/react-hook-form.tsx +18 -0
- package/templates-i18n/nextjs/src/features/landing/icons/react.tsx +20 -0
- package/templates-i18n/nextjs/src/features/landing/icons/tailwind.tsx +14 -0
- package/templates-i18n/nextjs/src/features/landing/icons/tanstack.tsx +321 -0
- package/templates-i18n/nextjs/src/features/landing/icons/typescript.tsx +16 -0
- package/templates-i18n/nextjs/src/features/landing/index.ts +1 -0
- package/templates-i18n/nextjs/src/features/landing/schemas/index.ts +1 -0
- package/templates-i18n/nextjs/src/features/landing/schemas/project.schema.ts +9 -0
- package/templates-i18n/nextjs/src/features/landing/stores/counter.store.ts +18 -0
- package/templates-i18n/nextjs/src/features/landing/stores/index.ts +1 -0
- package/templates-i18n/nextjs/src/features/landing/types/index.ts +1 -0
- package/templates-i18n/nextjs/src/features/landing/types/user.types.ts +9 -0
- package/templates-i18n/nextjs/src/helpers/format-date.ts +13 -0
- package/templates-i18n/nextjs/src/helpers/index.ts +1 -0
- package/templates-i18n/nextjs/src/hooks/index.ts +5 -0
- package/templates-i18n/nextjs/src/i18n/request.ts +16 -0
- package/templates-i18n/nextjs/src/i18n/routing.ts +11 -0
- package/templates-i18n/nextjs/src/lib/api.ts +97 -0
- package/templates-i18n/nextjs/src/lib/query-client.ts +18 -0
- package/templates-i18n/nextjs/src/lib/utils.ts +12 -0
- package/templates-i18n/nextjs/src/messages/en.json +55 -0
- package/templates-i18n/nextjs/src/messages/tr.json +55 -0
- package/templates-i18n/nextjs/src/providers/Providers.tsx +15 -0
- package/templates-i18n/nextjs/src/providers/QueryProvider.tsx +19 -0
- package/templates-i18n/nextjs/src/providers/ThemeProvider.tsx +9 -0
- package/templates-i18n/nextjs/src/providers/index.ts +1 -0
- package/templates-i18n/nextjs/src/proxy.ts +16 -0
- package/templates-i18n/nextjs/src/schemas/index.ts +5 -0
- package/templates-i18n/nextjs/src/stores/index.ts +5 -0
- package/templates-i18n/nextjs/src/styles/tailwind.css +122 -0
- package/templates-i18n/nextjs/src/types/site-config.types.ts +10 -0
- package/templates-i18n/nextjs/tsconfig.json +45 -0
- package/templates-i18n/tanstack/.changeset/README.md +8 -0
- package/templates-i18n/tanstack/.changeset/config.json +11 -0
- package/templates-i18n/tanstack/.env.example +6 -0
- package/templates-i18n/tanstack/.github/workflows/ci.yml +41 -0
- package/templates-i18n/tanstack/.husky/commit-msg +1 -0
- package/templates-i18n/tanstack/.husky/pre-commit +1 -0
- package/templates-i18n/tanstack/.husky/pre-push +1 -0
- package/templates-i18n/tanstack/.prettierignore +7 -0
- package/templates-i18n/tanstack/.prettierrc +41 -0
- package/templates-i18n/tanstack/.vscode/extensions.json +7 -0
- package/templates-i18n/tanstack/.vscode/settings.json +22 -0
- package/templates-i18n/tanstack/LICENSE +21 -0
- package/templates-i18n/tanstack/README.md +204 -0
- package/templates-i18n/tanstack/commitlint.config.js +6 -0
- package/templates-i18n/tanstack/eslint.config.js +29 -0
- package/templates-i18n/tanstack/knip.config.js +26 -0
- package/templates-i18n/tanstack/messages/en.json +65 -0
- package/templates-i18n/tanstack/messages/tr.json +65 -0
- package/templates-i18n/tanstack/package.json +132 -0
- package/templates-i18n/tanstack/pnpm-lock.yaml +5998 -0
- package/templates-i18n/tanstack/pnpm-workspace.yaml +3 -0
- package/templates-i18n/tanstack/project.inlang/README.md +157 -0
- package/templates-i18n/tanstack/project.inlang/settings.json +9 -0
- package/templates-i18n/tanstack/public/favicon.ico +0 -0
- package/templates-i18n/tanstack/public/llms.txt +86 -0
- package/templates-i18n/tanstack/public/logo.png +0 -0
- package/templates-i18n/tanstack/public/logo.webp +0 -0
- package/templates-i18n/tanstack/public/og.png +0 -0
- package/templates-i18n/tanstack/src/components/shared/DefaultCatchBoundary.tsx +36 -0
- package/templates-i18n/tanstack/src/components/shared/LanguageSwitcher.tsx +57 -0
- package/templates-i18n/tanstack/src/components/shared/NotFound.tsx +18 -0
- package/templates-i18n/tanstack/src/components/shared/Pending.tsx +13 -0
- package/templates-i18n/tanstack/src/components/shared/ThemeToggle.tsx +31 -0
- package/templates-i18n/tanstack/src/components/ui/avatar.tsx +52 -0
- package/templates-i18n/tanstack/src/components/ui/button.tsx +47 -0
- package/templates-i18n/tanstack/src/components/ui/dialog.tsx +107 -0
- package/templates-i18n/tanstack/src/components/ui/field.tsx +24 -0
- package/templates-i18n/tanstack/src/components/ui/index.ts +27 -0
- package/templates-i18n/tanstack/src/components/ui/input.tsx +23 -0
- package/templates-i18n/tanstack/src/components/ui/label.tsx +17 -0
- package/templates-i18n/tanstack/src/components/ui/skeleton.tsx +13 -0
- package/templates-i18n/tanstack/src/components/ui/table.tsx +94 -0
- package/templates-i18n/tanstack/src/components/ui/tabs.tsx +46 -0
- package/templates-i18n/tanstack/src/config/seo.config.ts +52 -0
- package/templates-i18n/tanstack/src/config/site.config.ts +15 -0
- package/templates-i18n/tanstack/src/constants/index.ts +5 -0
- package/templates-i18n/tanstack/src/env.ts +47 -0
- package/templates-i18n/tanstack/src/features/landing/api/get-users.api.ts +7 -0
- package/templates-i18n/tanstack/src/features/landing/api/index.ts +2 -0
- package/templates-i18n/tanstack/src/features/landing/api/query-keys.ts +7 -0
- package/templates-i18n/tanstack/src/features/landing/components/CartDemo.tsx +67 -0
- package/templates-i18n/tanstack/src/features/landing/components/Features.tsx +79 -0
- package/templates-i18n/tanstack/src/features/landing/components/Hero.tsx +68 -0
- package/templates-i18n/tanstack/src/features/landing/components/LandingPage.tsx +17 -0
- package/templates-i18n/tanstack/src/features/landing/components/ProjectFormDemo.tsx +64 -0
- package/templates-i18n/tanstack/src/features/landing/components/Reveal.tsx +83 -0
- package/templates-i18n/tanstack/src/features/landing/components/Showcase.tsx +81 -0
- package/templates-i18n/tanstack/src/features/landing/components/UsersDemo.tsx +191 -0
- package/templates-i18n/tanstack/src/features/landing/data/features.data.tsx +45 -0
- package/templates-i18n/tanstack/src/features/landing/data/index.ts +1 -0
- package/templates-i18n/tanstack/src/features/landing/helpers/get-initials.ts +15 -0
- package/templates-i18n/tanstack/src/features/landing/helpers/index.ts +7 -0
- package/templates-i18n/tanstack/src/features/landing/helpers/motion.ts +21 -0
- package/templates-i18n/tanstack/src/features/landing/hooks/index.ts +1 -0
- package/templates-i18n/tanstack/src/features/landing/hooks/use-users.ts +19 -0
- package/templates-i18n/tanstack/src/features/landing/icons/index.ts +5 -0
- package/templates-i18n/tanstack/src/features/landing/icons/react-hook-form.tsx +18 -0
- package/templates-i18n/tanstack/src/features/landing/icons/react.tsx +20 -0
- package/templates-i18n/tanstack/src/features/landing/icons/tailwind.tsx +14 -0
- package/templates-i18n/tanstack/src/features/landing/icons/tanstack.tsx +321 -0
- package/templates-i18n/tanstack/src/features/landing/icons/typescript.tsx +16 -0
- package/templates-i18n/tanstack/src/features/landing/index.ts +1 -0
- package/templates-i18n/tanstack/src/features/landing/schemas/index.ts +1 -0
- package/templates-i18n/tanstack/src/features/landing/schemas/project.schema.ts +10 -0
- package/templates-i18n/tanstack/src/features/landing/stores/counter.store.ts +18 -0
- package/templates-i18n/tanstack/src/features/landing/stores/index.ts +1 -0
- package/templates-i18n/tanstack/src/features/landing/types/index.ts +1 -0
- package/templates-i18n/tanstack/src/features/landing/types/user.types.ts +9 -0
- package/templates-i18n/tanstack/src/helpers/format-date.ts +13 -0
- package/templates-i18n/tanstack/src/helpers/index.ts +1 -0
- package/templates-i18n/tanstack/src/hooks/index.ts +5 -0
- package/templates-i18n/tanstack/src/lib/api.ts +97 -0
- package/templates-i18n/tanstack/src/lib/query-client.ts +18 -0
- package/templates-i18n/tanstack/src/lib/utils.ts +13 -0
- package/templates-i18n/tanstack/src/paraglide/README.md +162 -0
- package/templates-i18n/tanstack/src/providers/Providers.tsx +12 -0
- package/templates-i18n/tanstack/src/providers/ThemeProvider.tsx +98 -0
- package/templates-i18n/tanstack/src/providers/devtools.tsx +6 -0
- package/templates-i18n/tanstack/src/providers/index.ts +1 -0
- package/templates-i18n/tanstack/src/providers/root-provider.ts +9 -0
- package/templates-i18n/tanstack/src/routeTree.gen.ts +179 -0
- package/templates-i18n/tanstack/src/router.tsx +27 -0
- package/templates-i18n/tanstack/src/routes/$lang/index.tsx +13 -0
- package/templates-i18n/tanstack/src/routes/$lang.tsx +22 -0
- package/templates-i18n/tanstack/src/routes/__root.tsx +80 -0
- package/templates-i18n/tanstack/src/routes/index.tsx +13 -0
- package/templates-i18n/tanstack/src/routes/robots[.]txt.ts +21 -0
- package/templates-i18n/tanstack/src/routes/site[.]webmanifest.ts +32 -0
- package/templates-i18n/tanstack/src/routes/sitemap[.]xml.ts +27 -0
- package/templates-i18n/tanstack/src/schemas/index.ts +5 -0
- package/templates-i18n/tanstack/src/server.ts +10 -0
- package/templates-i18n/tanstack/src/start.ts +20 -0
- package/templates-i18n/tanstack/src/stores/index.ts +5 -0
- package/templates-i18n/tanstack/src/styles/tailwind.css +123 -0
- package/templates-i18n/tanstack/src/types/site-config.types.ts +10 -0
- package/templates-i18n/tanstack/tsconfig.json +26 -0
- package/templates-i18n/tanstack/tsr.config.json +3 -0
- package/templates-i18n/tanstack/vite.config.ts +31 -0
- package/index.js +0 -3
- package/public/start.jpg +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry of ViraStack tools the CLI knows how to wire up.
|
|
3
|
+
*
|
|
4
|
+
* - "dependency" tools are added straight to package.json and installed
|
|
5
|
+
* like any other npm package (e.g. @virastack/mask).
|
|
6
|
+
* - "postinstall-cli" tools ship their own `init` command that writes files
|
|
7
|
+
* into the target project (e.g. @virastack/ai writes .cursor/rules), so we
|
|
8
|
+
* shell out to them instead of treating them as a runtime dependency.
|
|
9
|
+
*/
|
|
10
|
+
export const TOOLS = [
|
|
11
|
+
{
|
|
12
|
+
id: "mask",
|
|
13
|
+
package: "@virastack/mask",
|
|
14
|
+
kind: "dependency",
|
|
15
|
+
version: "latest",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "password",
|
|
19
|
+
package: "@virastack/password",
|
|
20
|
+
kind: "dependency",
|
|
21
|
+
version: "latest",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "ai",
|
|
25
|
+
package: "@virastack/ai",
|
|
26
|
+
kind: "postinstall-cli",
|
|
27
|
+
version: "latest",
|
|
28
|
+
hiddenFromInit: true,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
export function findTool(id) {
|
|
33
|
+
return TOOLS.find((tool) => tool.id === id);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Parses a comma-separated tools flag into valid tool ids.
|
|
38
|
+
* Unknown ids are ignored; empty / missing input yields [].
|
|
39
|
+
*/
|
|
40
|
+
export function parseToolsFlag(value) {
|
|
41
|
+
if (value == null || value === true) return [];
|
|
42
|
+
|
|
43
|
+
return String(value)
|
|
44
|
+
.split(",")
|
|
45
|
+
.map((part) => part.trim())
|
|
46
|
+
.filter(Boolean)
|
|
47
|
+
.filter((id) => Boolean(findTool(id)));
|
|
48
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { findTool } from "./tools.js";
|
|
4
|
+
import { toPackageName } from "./validate-project-name.js";
|
|
5
|
+
import { getCliVersion } from "./package-info.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Rewrites the scaffolded package.json: gives it the user's project name
|
|
9
|
+
* and adds a dependency entry for every selected "dependency"-kind tool
|
|
10
|
+
* (e.g. @virastack/mask). Tools with an "init" CLI (like @virastack/ai)
|
|
11
|
+
* are handled separately since they aren't a runtime dependency.
|
|
12
|
+
*/
|
|
13
|
+
export async function updatePackageJson(targetDir, { projectName, tools }) {
|
|
14
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
15
|
+
|
|
16
|
+
let pkg;
|
|
17
|
+
try {
|
|
18
|
+
pkg = JSON.parse(await fs.readFile(pkgPath, "utf8"));
|
|
19
|
+
} catch {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pkg.name = toPackageName(projectName);
|
|
24
|
+
pkg.version = "1.0.0"; // Scaffolded project's own initial version
|
|
25
|
+
delete pkg.author;
|
|
26
|
+
delete pkg.repository;
|
|
27
|
+
delete pkg.bugs;
|
|
28
|
+
delete pkg.homepage;
|
|
29
|
+
delete pkg.keywords;
|
|
30
|
+
|
|
31
|
+
if (pkg.virastack) {
|
|
32
|
+
pkg.virastack.version = getCliVersion();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
pkg.dependencies = pkg.dependencies ?? {};
|
|
36
|
+
for (const toolId of tools) {
|
|
37
|
+
const tool = findTool(toolId);
|
|
38
|
+
if (tool?.kind === "dependency") {
|
|
39
|
+
pkg.dependencies[tool.package] = tool.version ?? "^1.0.0";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
await fs.writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
44
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Personalizes the scaffolded README: renames the H1 to the user's project
|
|
6
|
+
* and strips the marketing hero image (assets/ is not copied into projects).
|
|
7
|
+
*/
|
|
8
|
+
export async function updateReadme(targetDir, projectName) {
|
|
9
|
+
const readmePath = path.join(targetDir, "README.md");
|
|
10
|
+
|
|
11
|
+
let content;
|
|
12
|
+
try {
|
|
13
|
+
content = await fs.readFile(readmePath, "utf8");
|
|
14
|
+
} catch {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let updated = content
|
|
19
|
+
.replace(/^#\s+.+$/m, `# ${projectName}`)
|
|
20
|
+
.replace(/^!\[.*?\]\(\.\/assets\/.*?\)\n*/m, "");
|
|
21
|
+
|
|
22
|
+
if (updated === content) return;
|
|
23
|
+
|
|
24
|
+
await fs.writeFile(readmePath, updated);
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Same shape npm itself enforces for package names (scoped names included).
|
|
2
|
+
const NPM_NAME_PATTERN = /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns null when valid, or an error code ("empty" | "invalid") otherwise.
|
|
6
|
+
* "." is always valid — it means "use the current directory".
|
|
7
|
+
*/
|
|
8
|
+
export function validateProjectName(value) {
|
|
9
|
+
const trimmed = (value ?? "").trim();
|
|
10
|
+
|
|
11
|
+
if (trimmed.length === 0) return "empty";
|
|
12
|
+
if (trimmed === ".") return null;
|
|
13
|
+
if (!NPM_NAME_PATTERN.test(trimmed)) return "invalid";
|
|
14
|
+
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function toPackageName(name) {
|
|
19
|
+
const sanitized = name
|
|
20
|
+
.trim()
|
|
21
|
+
.toLowerCase()
|
|
22
|
+
.replace(/[^a-z0-9-~]+/g, "-")
|
|
23
|
+
.replace(/^-+|-+$/g, "");
|
|
24
|
+
|
|
25
|
+
return sanitized.length > 0 ? sanitized : "virastack-app";
|
|
26
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
+
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
+
find the full documentation for it [in our repository](https://github.com/changesets/changesets).
|
|
6
|
+
|
|
7
|
+
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": false,
|
|
5
|
+
"fixed": [],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "restricted",
|
|
8
|
+
"baseBranch": "main",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Public (exposed to the browser) — must be prefixed with NEXT_PUBLIC_
|
|
2
|
+
NEXT_PUBLIC_APP_URL="http://localhost:3000"
|
|
3
|
+
NEXT_PUBLIC_APP_NAME="ViraStack Start - Next.js Edition"
|
|
4
|
+
|
|
5
|
+
# Server-only (never exposed to the browser)
|
|
6
|
+
# NODE_ENV is set automatically by Next.js — no need to define it here.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Install pnpm
|
|
18
|
+
uses: pnpm/action-setup@v4
|
|
19
|
+
with:
|
|
20
|
+
version: 10
|
|
21
|
+
|
|
22
|
+
- name: Setup Node.js
|
|
23
|
+
uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: 22
|
|
26
|
+
cache: "pnpm"
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: pnpm install --frozen-lockfile
|
|
30
|
+
|
|
31
|
+
- name: Typecheck
|
|
32
|
+
run: pnpm run typecheck
|
|
33
|
+
|
|
34
|
+
- name: Lint
|
|
35
|
+
run: pnpm run lint:ci
|
|
36
|
+
|
|
37
|
+
- name: Knip
|
|
38
|
+
run: pnpm run knip
|
|
39
|
+
|
|
40
|
+
- name: Build
|
|
41
|
+
run: pnpm run build
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npx --no -- commitlint --edit "$1"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npx --no -- lint-staged
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npm run typecheck && npm run lint:ci
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"singleQuote": false,
|
|
3
|
+
"trailingComma": "all",
|
|
4
|
+
"printWidth": 100,
|
|
5
|
+
"plugins": ["@ianvs/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"],
|
|
6
|
+
"tailwindFunctions": ["cn", "clsx", "cva"],
|
|
7
|
+
"tailwindStylesheet": "./src/styles/tailwind.css",
|
|
8
|
+
"importOrder": [
|
|
9
|
+
"^react$",
|
|
10
|
+
"^next($|/)",
|
|
11
|
+
"",
|
|
12
|
+
"^@tanstack/.*",
|
|
13
|
+
"^zustand($|/)",
|
|
14
|
+
"^lucide-react($|/)",
|
|
15
|
+
"<THIRD_PARTY_MODULES>",
|
|
16
|
+
"",
|
|
17
|
+
"^@/types($|/)",
|
|
18
|
+
"^@/constants($|/)",
|
|
19
|
+
"^@/schemas($|/)",
|
|
20
|
+
"^@/config($|/)",
|
|
21
|
+
"^@/env($|/)",
|
|
22
|
+
"",
|
|
23
|
+
"^@/assets($|/)",
|
|
24
|
+
"^@/styles($|/)",
|
|
25
|
+
"^@/lib($|/)",
|
|
26
|
+
"^@/helpers($|/)",
|
|
27
|
+
"",
|
|
28
|
+
"^@/providers($|/)",
|
|
29
|
+
"^@/stores($|/)",
|
|
30
|
+
"^@/hooks($|/)",
|
|
31
|
+
"^@/data($|/)",
|
|
32
|
+
"",
|
|
33
|
+
"^@/components($|/)",
|
|
34
|
+
"^@/layout($|/)",
|
|
35
|
+
"^@/features($|/)",
|
|
36
|
+
"^@/ui($|/)",
|
|
37
|
+
"^@/.*",
|
|
38
|
+
"",
|
|
39
|
+
"^[./]"
|
|
40
|
+
],
|
|
41
|
+
"importOrderParserPlugins": ["typescript", "jsx"]
|
|
42
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
3
|
+
"editor.formatOnSave": true,
|
|
4
|
+
"editor.codeActionsOnSave": {
|
|
5
|
+
"source.fixAll.eslint": "explicit"
|
|
6
|
+
},
|
|
7
|
+
"typescript.tsdk": "node_modules/typescript/lib",
|
|
8
|
+
"files.exclude": {
|
|
9
|
+
"**/.git": true,
|
|
10
|
+
"**/.svn": true,
|
|
11
|
+
"**/.hg": true,
|
|
12
|
+
"**/.DS_Store": true,
|
|
13
|
+
"**/Thumbs.db": true,
|
|
14
|
+
"**/.cache": true,
|
|
15
|
+
"**/.next": true,
|
|
16
|
+
"**/build": true,
|
|
17
|
+
"**/dist": true,
|
|
18
|
+
"**/node_modules": true
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026-present Ömer Gülçiçek (ViraStack)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<a href="https://github.com/virastack/start" target="_blank" rel="noreferrer">
|
|
4
|
+
<picture>
|
|
5
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/virastack/start/main/assets/logo-dark.png">
|
|
6
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/virastack/start/main/assets/logo-light.png">
|
|
7
|
+
<img src="https://raw.githubusercontent.com/virastack/start/main/assets/logo-light.png" alt="ViraStack Start" height="120" style="max-width: 100%;" />
|
|
8
|
+
</picture>
|
|
9
|
+
</a>
|
|
10
|
+
|
|
11
|
+
# ViraStack Start — Next.js Edition
|
|
12
|
+
|
|
13
|
+
_The Next.js boilerplate that feels effortless._
|
|
14
|
+
|
|
15
|
+
[](https://virastack.com)
|
|
16
|
+
[](https://www.npmjs.com/package/virastack)
|
|
17
|
+
[](https://www.npmjs.com/package/virastack)
|
|
18
|
+
[](package.json)
|
|
19
|
+
[](LICENSE)
|
|
20
|
+
[](https://github.com/virastack/start/actions/workflows/ci.yml)
|
|
21
|
+
[](https://x.com/virastack)
|
|
22
|
+
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
**Docs:** [See the docs](https://www.virastack.com/nextjs-boilerplate/)
|
|
28
|
+
|
|
29
|
+
**Contents:** [Why](#why-virastack) · [Features](#features) · [Getting started](#getting-started) · [Environment](#environment-variables) · [Scripts](#scripts) · [Project structure](#project-structure) · [Customization](#customization) · [ViraStack AI](#virastack-ai) · [Deployment](#deployment)
|
|
30
|
+
|
|
31
|
+
Production-grade Next.js starter with feature-sliced architecture, strict TypeScript, and a pre-configured [**ViraStack AI**](https://github.com/virastack/ai) layer — so you and your coding agents ship consistent code from day one.
|
|
32
|
+
|
|
33
|
+
## Why ViraStack
|
|
34
|
+
|
|
35
|
+
- **Opinionated, not opaque** — clear folder rules and placement conventions; nothing important is hidden behind magic
|
|
36
|
+
- **Agent-ready by default** — `AGENTS.md`, Cursor rules, `llms.txt`, and design skills ship with every project
|
|
37
|
+
- **Own your UI** — Base UI primitives in `components/ui` (shadcn-style), fully editable
|
|
38
|
+
- **State triad** — TanStack Query (server), Zustand (client), nuqs (URL) — each with a dedicated job
|
|
39
|
+
- **DX that sticks** — ESLint, Prettier, Knip, Husky, Commitlint, and GitHub Actions CI out of the box
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
**Included**
|
|
44
|
+
|
|
45
|
+
- ⚡ **Next.js 16** — App Router, Turbopack, React Compiler
|
|
46
|
+
- ⚛️ **React 19** + TypeScript strict (`noUncheckedIndexedAccess`)
|
|
47
|
+
- 🎨 **Tailwind CSS 4** + Base UI primitives
|
|
48
|
+
- 🔄 **TanStack Query** · **Zustand** · **nuqs**
|
|
49
|
+
- 📋 **React Hook Form** + **Zod** — validated forms end to end
|
|
50
|
+
- 🤖 **ViraStack AI** — agent context, scoped rules, design skills
|
|
51
|
+
- ✅ **Quality built in** — ESLint, Prettier, Knip, Husky, Commitlint, CI (typecheck → lint → knip → build)
|
|
52
|
+
|
|
53
|
+
**Optional / bring your own**
|
|
54
|
+
|
|
55
|
+
- Auth, database, i18n, analytics, and monitoring — wire them in when you need them; the architecture is ready
|
|
56
|
+
|
|
57
|
+
## Getting started
|
|
58
|
+
|
|
59
|
+
**Quick Start & Setup:** Please follow the instructions in the main [ViraStack Start README](https://github.com/virastack/start#quick-start).
|
|
60
|
+
|
|
61
|
+
Once your project is scaffolded, start the development server:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pnpm dev
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Open [http://localhost:3000](http://localhost:3000). The home route renders `LandingPage` from `src/features/landing` — a full demo of the stack (theme toggle, TanStack Query, Zustand, Zod forms, nuqs). Delete that feature when you are ready to build.
|
|
68
|
+
|
|
69
|
+
## Environment variables
|
|
70
|
+
|
|
71
|
+
Validated in `src/env.ts`. Scaffolded projects already have `.env.local`.
|
|
72
|
+
|
|
73
|
+
| Variable | Scope | Description |
|
|
74
|
+
| :--------------------- | :----- | :------------------------------------------------------------ |
|
|
75
|
+
| `NEXT_PUBLIC_APP_URL` | Public | Canonical app URL (default `http://localhost:3000`) |
|
|
76
|
+
| `NEXT_PUBLIC_APP_NAME` | Public | Product name shown in UI/metadata (default `ViraStack Start`) |
|
|
77
|
+
|
|
78
|
+
`NODE_ENV` is set by Next.js — do not define it manually. Add new vars in both `.env.example` and `src/env.ts`.
|
|
79
|
+
|
|
80
|
+
## Scripts
|
|
81
|
+
|
|
82
|
+
| Script | Description |
|
|
83
|
+
| :------------------------------ | :------------------------------------------- |
|
|
84
|
+
| `dev` | Start the dev server (Turbopack) |
|
|
85
|
+
| `build` | Production build |
|
|
86
|
+
| `start` | Serve the production build |
|
|
87
|
+
| `analyze` | Build with bundle analyzer |
|
|
88
|
+
| `lint` / `lint:fix` / `lint:ci` | ESLint (+ format check in CI) |
|
|
89
|
+
| `format` / `format:check` | Prettier |
|
|
90
|
+
| `typecheck` | `tsc --noEmit` |
|
|
91
|
+
| `knip` | Find unused files, exports, and dependencies |
|
|
92
|
+
|
|
93
|
+
CI runs the same gates: typecheck → lint → knip → build (see `.github/workflows/ci.yml`).
|
|
94
|
+
|
|
95
|
+
## Project structure
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
src/
|
|
99
|
+
├── app/ # Routes, layouts, metadata (App Router only)
|
|
100
|
+
├── features/
|
|
101
|
+
│ └── landing/ # Demo feature (canonical folder layout)
|
|
102
|
+
│ ├── api/
|
|
103
|
+
│ ├── components/ # Hero, Features, Showcase, demos, LandingPage
|
|
104
|
+
│ ├── constants/
|
|
105
|
+
│ ├── data/
|
|
106
|
+
│ ├── helpers/
|
|
107
|
+
│ ├── hooks/
|
|
108
|
+
│ ├── icons/ # Brand SVGs used only by the landing demo
|
|
109
|
+
│ ├── schemas/
|
|
110
|
+
│ ├── stores/
|
|
111
|
+
│ ├── types/
|
|
112
|
+
│ └── index.ts
|
|
113
|
+
├── components/
|
|
114
|
+
│ ├── ui/ # Base UI primitives (Button, Dialog, Tabs, …)
|
|
115
|
+
│ ├── layout/ # Header, Footer (reusable chrome)
|
|
116
|
+
│ └── shared/ # Cross-feature components (ThemeToggle, …)
|
|
117
|
+
├── hooks/ # Shared hooks (promote via Rule of Three)
|
|
118
|
+
├── stores/
|
|
119
|
+
├── schemas/
|
|
120
|
+
├── providers/
|
|
121
|
+
├── lib/ # api.ts, query-client.ts, utils
|
|
122
|
+
├── config/
|
|
123
|
+
├── constants/
|
|
124
|
+
├── helpers/
|
|
125
|
+
├── types/
|
|
126
|
+
├── styles/
|
|
127
|
+
└── env.ts
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The bundled `landing` feature follows the ViraStack AI feature tree and is meant to be deleted when you start building.
|
|
131
|
+
|
|
132
|
+
**Quick start (strip the demo)**
|
|
133
|
+
|
|
134
|
+
1. Delete `src/features/landing`
|
|
135
|
+
2. Replace `src/app/page.tsx` with your own page
|
|
136
|
+
3. Keep `components/layout` Header/Footer if you still want site chrome — pass `links` only when you need nav items
|
|
137
|
+
|
|
138
|
+
**Rules of thumb**
|
|
139
|
+
|
|
140
|
+
- Default scope is `features/[feature]/` — promote to global `src/` only when a second feature needs it
|
|
141
|
+
- No cross-feature imports; share via `components/`, `lib/`, `hooks/`, etc.
|
|
142
|
+
- Path aliases are mandatory; parent-relative imports (`../`) are forbidden
|
|
143
|
+
|
|
144
|
+
See [`docs/architecture-guide.md`](docs/architecture-guide.md) for placement rules and import conventions.
|
|
145
|
+
|
|
146
|
+
## Customization
|
|
147
|
+
|
|
148
|
+
Search the repo for `FIXME:` to find the first things to own:
|
|
149
|
+
|
|
150
|
+
| File | What to change |
|
|
151
|
+
| :---------------------------- | :--------------------------------------- |
|
|
152
|
+
| `src/config/site.config.ts` | Site name, description, metadata |
|
|
153
|
+
| `next.config.ts` | Remote image domains and Next.js options |
|
|
154
|
+
| `src/lib/api.ts` | Auth header / API client wiring |
|
|
155
|
+
| `src/env.ts` + `.env.example` | New environment variables |
|
|
156
|
+
| `public/` | Favicon and static assets |
|
|
157
|
+
|
|
158
|
+
You own every file — trim demos, rename features, keep only what you need.
|
|
159
|
+
|
|
160
|
+
## ViraStack AI
|
|
161
|
+
|
|
162
|
+
Developed with [**ViraStack AI**](https://github.com/virastack/ai) — an AI-native architecture kit that ships agent context into every project:
|
|
163
|
+
|
|
164
|
+
| File | Purpose |
|
|
165
|
+
| :---------------- | :------------------------------- |
|
|
166
|
+
| `AGENTS.md` | Agent operating guide |
|
|
167
|
+
| `CLAUDE.md` | Claude Code entry point |
|
|
168
|
+
| `.cursor/rules/` | Scoped coding rules |
|
|
169
|
+
| `public/llms.txt` | Machine-readable project summary |
|
|
170
|
+
| `.agents/skills/` | Design-taste skills |
|
|
171
|
+
|
|
172
|
+
Install or refresh rules: `npx @virastack/ai init`
|
|
173
|
+
|
|
174
|
+
## Deployment
|
|
175
|
+
|
|
176
|
+
Optimized for [Vercel](https://vercel.com/):
|
|
177
|
+
|
|
178
|
+
1. Push the repo and import the project in Vercel (or your host of choice)
|
|
179
|
+
2. Set `NEXT_PUBLIC_APP_URL` and `NEXT_PUBLIC_APP_NAME` from `.env.example`
|
|
180
|
+
3. Run `pnpm analyze` locally before shipping if bundle size matters
|
|
181
|
+
4. Deploy — `pnpm build` / `pnpm start` work the same on any Node host
|
|
182
|
+
|
|
183
|
+
## Philosophy
|
|
184
|
+
|
|
185
|
+
- Minimal surface, strong conventions
|
|
186
|
+
- Agent-first documentation lives next to the code
|
|
187
|
+
- Own your UI and architecture — no locked black boxes
|
|
188
|
+
- Production-ready DX without forcing auth/db opinions until you need them
|
|
189
|
+
|
|
190
|
+
## Contributing
|
|
191
|
+
|
|
192
|
+
Ideas and bug reports welcome — open an [issue](https://github.com/virastack/start/issues).
|
|
193
|
+
|
|
194
|
+
PRs that improve DX, architecture docs, or the landing showcase are especially appreciated.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
<div align="center">
|
|
199
|
+
|
|
200
|
+
Bootstrapped with [**ViraStack Start**](https://github.com/virastack/start) · Built by <a href="https://omergulcicek.com">Ömer Gülçiçek</a> · <a href="LICENSE">MIT Licensed</a>
|
|
201
|
+
|
|
202
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import nextVitals from "eslint-config-next/core-web-vitals";
|
|
2
|
+
import nextTs from "eslint-config-next/typescript";
|
|
3
|
+
import { defineConfig, globalIgnores } from "eslint/config";
|
|
4
|
+
|
|
5
|
+
const eslintConfig = defineConfig([
|
|
6
|
+
...nextVitals,
|
|
7
|
+
...nextTs,
|
|
8
|
+
{
|
|
9
|
+
rules: {
|
|
10
|
+
"@typescript-eslint/no-unused-vars": [
|
|
11
|
+
"warn",
|
|
12
|
+
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
|
|
13
|
+
],
|
|
14
|
+
"no-console": ["warn", { allow: ["warn", "error"] }],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
// Override default ignores of eslint-config-next.
|
|
18
|
+
globalIgnores([
|
|
19
|
+
// Default ignores of eslint-config-next:
|
|
20
|
+
".next/**",
|
|
21
|
+
"out/**",
|
|
22
|
+
"build/**",
|
|
23
|
+
"next-env.d.ts",
|
|
24
|
+
]),
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
export default eslintConfig;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** @type {import('knip').KnipConfig} */
|
|
2
|
+
const config = {
|
|
3
|
+
entry: [
|
|
4
|
+
"src/app/**/{page,layout,template,default,loading,not-found,error,global-error}.{ts,tsx}",
|
|
5
|
+
"src/app/**/{sitemap,robots,manifest}.{ts,tsx}",
|
|
6
|
+
],
|
|
7
|
+
project: ["src/**/*.{ts,tsx,js,jsx}"],
|
|
8
|
+
ignore: [
|
|
9
|
+
"src/components/ui/**",
|
|
10
|
+
// Shared-layer barrels reserved for Rule-of-Three promotions
|
|
11
|
+
"src/hooks/index.ts",
|
|
12
|
+
"src/stores/index.ts",
|
|
13
|
+
"src/schemas/index.ts",
|
|
14
|
+
"src/constants/index.ts",
|
|
15
|
+
],
|
|
16
|
+
ignoreDependencies: ["tailwindcss", "tw-animate-css"],
|
|
17
|
+
rules: {
|
|
18
|
+
dependencies: "error",
|
|
19
|
+
exports: "warn",
|
|
20
|
+
types: "warn",
|
|
21
|
+
files: "warn",
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = config;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import type { NextConfig } from "next";
|
|
3
|
+
|
|
4
|
+
import createBundleAnalyzer from "@next/bundle-analyzer";
|
|
5
|
+
|
|
6
|
+
const withBundleAnalyzer = createBundleAnalyzer({
|
|
7
|
+
enabled: process.env.ANALYZE === "true",
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const nextConfig: NextConfig = {
|
|
11
|
+
reactCompiler: true,
|
|
12
|
+
turbopack: {
|
|
13
|
+
root: path.join(import.meta.dirname),
|
|
14
|
+
},
|
|
15
|
+
images: {
|
|
16
|
+
remotePatterns: [
|
|
17
|
+
// FIXME: add your own remote image domains here, e.g.:
|
|
18
|
+
// { protocol: "https", hostname: "images.unsplash.com" },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
async headers() {
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
source: "/:path*",
|
|
25
|
+
headers: [
|
|
26
|
+
{ key: "X-Frame-Options", value: "DENY" },
|
|
27
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
28
|
+
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
|
|
29
|
+
{
|
|
30
|
+
key: "Permissions-Policy",
|
|
31
|
+
value: "camera=(), microphone=(), geolocation=()",
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default withBundleAnalyzer(nextConfig);
|