diff --git a/index.js b/index.js
index 46398ba..d59cd49 100755
--- a/index.js
+++ b/index.js
@@ -328,7 +328,7 @@ async function createAction(projectName, options) {
// Architecture availability map
const ARCHITECTURES = {
'nextjs-monolith': { label: 'Next.js 14 — App Router', available: ['portfolio', 'ecommerce', 'school', 'saas', 'blog'] },
- 'vite-react': { label: 'Vite + React 18 — SPA', available: ['saas'] },
+ 'vite-react': { label: 'Vite + React 18 — SPA', available: ['portfolio', 'ecommerce', 'saas'] },
'nextjs-turborepo': { label: 'Turborepo — Monorepo', available: [] },
};
diff --git a/scripts/test-single-template.js b/scripts/test-single-template.js
index 4b4024e..f1952ad 100644
--- a/scripts/test-single-template.js
+++ b/scripts/test-single-template.js
@@ -21,8 +21,8 @@ if (!template) {
const DESIGNS = ['Minimal Clean', 'Dark Terminal', 'Glassmorphism'];
const ARCHITECTURES = {
- portfolio: ['nextjs-monolith'],
- ecommerce: ['nextjs-monolith'],
+ portfolio: ['nextjs-monolith', 'vite-react'],
+ ecommerce: ['nextjs-monolith', 'vite-react'],
school: ['nextjs-monolith'],
saas: ['nextjs-monolith', 'vite-react'],
blog: ['nextjs-monolith'],
diff --git a/scripts/test-templates.js b/scripts/test-templates.js
index 115122a..eddb1bd 100644
--- a/scripts/test-templates.js
+++ b/scripts/test-templates.js
@@ -19,8 +19,8 @@ const DESIGNS = ['Minimal Clean', 'Dark Terminal', 'Glassmorphism'];
// Template → available architectures
const ARCHITECTURES = {
- portfolio: ['nextjs-monolith'],
- ecommerce: ['nextjs-monolith'],
+ portfolio: ['nextjs-monolith', 'vite-react'],
+ ecommerce: ['nextjs-monolith', 'vite-react'],
school: ['nextjs-monolith'],
saas: ['nextjs-monolith', 'vite-react'],
blog: ['nextjs-monolith'],
diff --git a/templates/ecommerce/nextjs-monolith/app/account/page.tsx b/templates/ecommerce/nextjs-monolith/app/account/page.tsx
new file mode 100644
index 0000000..7650ac1
--- /dev/null
+++ b/templates/ecommerce/nextjs-monolith/app/account/page.tsx
@@ -0,0 +1,137 @@
+import Link from 'next/link';
+
+export default function AccountPage() {
+ const orders = [
+ { id: 'ORD-2024-001', date: 'Jun 15, 2024', items: 3, total: '$469.97', status: 'Delivered' },
+ { id: 'ORD-2024-002', date: 'Jun 2, 2024', items: 1, total: '$89.99', status: 'Delivered' },
+ { id: 'ORD-2024-003', date: 'May 18, 2024', items: 2, total: '$189.98', status: 'Delivered' },
+ { id: 'ORD-2024-004', date: 'May 5, 2024', items: 1, total: '$249.99', status: 'Returned' },
+ ];
+
+ const addresses = [
+ { label: 'Home', name: 'John Doe', address: '123 Main Street, Apt 4B', city: 'New York, NY 10001', default: true },
+ { label: 'Office', name: 'John Doe', address: '456 Business Ave, Floor 12', city: 'New York, NY 10018', default: false },
+ ];
+
+ return (
+
+
+
My Account
+
Manage your profile, orders, and preferences
+
+
+ {/* Sidebar */}
+
+
+
+
+ JD
+
+
+
John Doe
+
john@example.com
+
+
+
+
+
+
+
+ {/* Main Content */}
+
+ {/* Recent Orders */}
+
+
+
Recent Orders
+
+
+
+ {orders.map((order) => (
+
+
+
{order.id}
+
{order.date} · {order.items} item{order.items > 1 ? 's' : ''}
+
+
+
{order.total}
+
+ {order.status}
+
+
+
+ ))}
+
+
+
+ {/* Saved Addresses */}
+
+
+
Saved Addresses
+
+
+
+ {addresses.map((addr) => (
+
+
+ {addr.label}
+ {addr.default && (
+ Default
+ )}
+
+
{addr.name}
+
{addr.address}
+
{addr.city}
+
+
+
+
+
+ ))}
+
+
+
+ {/* Account Settings */}
+
+
Account Settings
+
+
+
+
+
+
+
+ );
+}
diff --git a/templates/ecommerce/vite-react/index.html b/templates/ecommerce/vite-react/index.html
new file mode 100644
index 0000000..93ad3da
--- /dev/null
+++ b/templates/ecommerce/vite-react/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ {{projectName}} - Store
+
+
+
+
+
+
diff --git a/templates/ecommerce/vite-react/package.json b/templates/ecommerce/vite-react/package.json
new file mode 100644
index 0000000..086d63f
--- /dev/null
+++ b/templates/ecommerce/vite-react/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "{{projectName}}",
+ "version": "1.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-router-dom": "^6.23.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.3.0",
+ "@types/react-dom": "^18.3.0",
+ "@vitejs/plugin-react": "^4.2.1",
+ "autoprefixer": "^10.4.19",
+ "postcss": "^8.4.38",
+ "tailwindcss": "^3.4.3",
+ "typescript": "^5.4.5",
+ "vite": "^5.2.11"
+ }
+}
diff --git a/templates/ecommerce/vite-react/postcss.config.js b/templates/ecommerce/vite-react/postcss.config.js
new file mode 100644
index 0000000..2aa7205
--- /dev/null
+++ b/templates/ecommerce/vite-react/postcss.config.js
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/templates/ecommerce/vite-react/src/App.tsx b/templates/ecommerce/vite-react/src/App.tsx
new file mode 100644
index 0000000..8385ef8
--- /dev/null
+++ b/templates/ecommerce/vite-react/src/App.tsx
@@ -0,0 +1,30 @@
+/**
+ * ⚠️ SEO WARNING: This is a client-side SPA (Vite + React).
+ * E-commerce stores typically need SSR for SEO and initial page load performance.
+ * Consider using the Next.js App Router architecture for public-facing stores.
+ * This Vite SPA is best suited for internal admin panels or private storefronts.
+ */
+
+import { BrowserRouter, Routes, Route } from 'react-router-dom';
+import Layout from './components/Layout';
+import Home from './pages/Home';
+import Products from './pages/Products';
+import ProductDetail from './pages/ProductDetail';
+import Cart from './pages/Cart';
+import Account from './pages/Account';
+
+export default function App() {
+ return (
+
+
+ }>
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+ );
+}
diff --git a/templates/ecommerce/vite-react/src/components/Layout.tsx b/templates/ecommerce/vite-react/src/components/Layout.tsx
new file mode 100644
index 0000000..cb5dcd8
--- /dev/null
+++ b/templates/ecommerce/vite-react/src/components/Layout.tsx
@@ -0,0 +1,74 @@
+import { Link, Outlet } from 'react-router-dom';
+import { navLinks } from '../lib/nav';
+
+function Navbar() {
+ return (
+
+
+
+ );
+}
+
+function Sidebar() {
+ return (
+
+ );
+}
+
+export default function Layout() {
+ const useSidebar = ('{{includeSidebar}}' as string) === 'true';
+
+ if (useSidebar) {
+ return (
+
+
+
+
+
+
+ );
+ }
+
+ return (
+ <>
+
+
+
+
+ >
+ );
+}
diff --git a/templates/ecommerce/vite-react/src/index.css b/templates/ecommerce/vite-react/src/index.css
new file mode 100644
index 0000000..7a2f894
--- /dev/null
+++ b/templates/ecommerce/vite-react/src/index.css
@@ -0,0 +1,48 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+:root {
+ --bg-color: #ffffff;
+ --bg-secondary: #f9fafb;
+ --text-color: #111827;
+ --text-secondary: #6b7280;
+ --primary: #2563eb;
+ --primary-hover: #1d4ed8;
+ --border-color: #e5e7eb;
+ --card-bg: #ffffff;
+ --font-family: 'Inter', system-ui, sans-serif;
+ --radius: 0.5rem;
+}
+
+[data-theme="Glassmorphism"] {
+ --bg-color: #0f172a;
+ --bg-secondary: rgba(255, 255, 255, 0.05);
+ --text-color: #f1f5f9;
+ --text-secondary: #94a3b8;
+ --primary: #8b5cf6;
+ --primary-hover: #7c3aed;
+ --border-color: rgba(255, 255, 255, 0.1);
+ --card-bg: rgba(255, 255, 255, 0.08);
+ --font-family: 'Inter', system-ui, sans-serif;
+ --radius: 1rem;
+}
+
+[data-theme="Dark Terminal"] {
+ --bg-color: #000000;
+ --bg-secondary: #0a0a0a;
+ --text-color: #3fb950;
+ --text-secondary: #8b949e;
+ --primary: #3fb950;
+ --primary-hover: #2ea043;
+ --border-color: #21262d;
+ --card-bg: #0d1117;
+ --font-family: 'JetBrains Mono', 'Fira Code', monospace;
+ --radius: 0.25rem;
+}
+
+body {
+ background-color: var(--bg-color);
+ color: var(--text-color);
+ font-family: var(--font-family);
+}
diff --git a/templates/ecommerce/vite-react/src/main.tsx b/templates/ecommerce/vite-react/src/main.tsx
new file mode 100644
index 0000000..9aa52ff
--- /dev/null
+++ b/templates/ecommerce/vite-react/src/main.tsx
@@ -0,0 +1,10 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+import './index.css';
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+ ,
+);
diff --git a/templates/ecommerce/vite-react/src/pages/Account.tsx b/templates/ecommerce/vite-react/src/pages/Account.tsx
new file mode 100644
index 0000000..9129d5a
--- /dev/null
+++ b/templates/ecommerce/vite-react/src/pages/Account.tsx
@@ -0,0 +1,98 @@
+export default function Account() {
+ const orders = [
+ { id: 'ORD-2024-001', date: 'Jun 15, 2024', items: 3, total: '$469.97', status: 'Delivered' },
+ { id: 'ORD-2024-002', date: 'Jun 2, 2024', items: 1, total: '$89.99', status: 'Delivered' },
+ { id: 'ORD-2024-003', date: 'May 18, 2024', items: 2, total: '$189.98', status: 'Delivered' },
+ ];
+
+ return (
+
+
+
My Account
+
Manage your profile, orders, and preferences
+
+
+ {/* Profile Card */}
+
+
+
+
+ JD
+
+
+
John Doe
+
john@example.com
+
+
+
+
+
+
+
+ {/* Orders */}
+
+
+
+
Recent Orders
+
+
+ {orders.map((order) => (
+
+
+
{order.id}
+
{order.date} · {order.items} items
+
+
+
{order.total}
+
+ {order.status}
+
+
+
+ ))}
+
+
+
+ {/* Settings */}
+
+
Account Settings
+
+
+
+
+
+
+
+ );
+}
diff --git a/templates/ecommerce/vite-react/src/pages/Cart.tsx b/templates/ecommerce/vite-react/src/pages/Cart.tsx
new file mode 100644
index 0000000..d7d1c70
--- /dev/null
+++ b/templates/ecommerce/vite-react/src/pages/Cart.tsx
@@ -0,0 +1,97 @@
+import { Link } from 'react-router-dom';
+
+export default function Cart() {
+ const items = [
+ { name: 'Classic White Sneakers', price: 89.99, quantity: 1, color: 'White', size: '10', imageColor: '#f1f5f9' },
+ { name: 'Leather Crossbody Bag', price: 129.99, quantity: 1, color: 'Tan', size: 'One Size', imageColor: '#d4a574' },
+ { name: 'Oversized Wool Coat', price: 249.99, quantity: 1, color: 'Charcoal', size: 'M', imageColor: '#1e293b' },
+ ];
+
+ const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
+ const tax = subtotal * 0.08;
+ const total = subtotal + tax;
+
+ return (
+
+
+
Shopping Cart
+
{items.length} items in your cart
+
+
+ {/* Items */}
+
+
+ {items.map((item, index) => (
+
+
+
+
+
+
{item.name}
+
{item.color} · Size {item.size}
+
+
+
+
+
+
+ {item.quantity}
+
+
+
${(item.price * item.quantity).toFixed(2)}
+
+
+
+ ))}
+
+
+ ← Continue Shopping
+
+
+
+ {/* Summary */}
+
+
+
Order Summary
+
+
+ Subtotal
+ ${subtotal.toFixed(2)}
+
+
+ Shipping
+ Calculated at checkout
+
+
+ Estimated Tax
+ ${tax.toFixed(2)}
+
+
+
+
+ Total
+ ${total.toFixed(2)}
+
+
+
+
+
Accepted Payment Methods
+
+ {['Visa', 'Mastercard', 'Amex', 'PayPal'].map((m) => (
+ {m}
+ ))}
+
+
+
+
+
+
+
+ );
+}
diff --git a/templates/ecommerce/vite-react/src/pages/Home.tsx b/templates/ecommerce/vite-react/src/pages/Home.tsx
new file mode 100644
index 0000000..a29177b
--- /dev/null
+++ b/templates/ecommerce/vite-react/src/pages/Home.tsx
@@ -0,0 +1,96 @@
+import { Link } from 'react-router-dom';
+
+export default function Home() {
+ const categories = [
+ { name: 'Women', count: 124, color: '#f9a8d4' },
+ { name: 'Men', count: 98, color: '#93c5fd' },
+ { name: 'Accessories', count: 67, color: '#fcd34d' },
+ { name: 'Sale', count: 45, color: '#fca5a5' },
+ ];
+
+ const featured = [
+ { slug: 'classic-white-sneakers', name: 'Classic White Sneakers', price: '$89.99', color: '#f1f5f9' },
+ { slug: 'leather-crossbody-bag', name: 'Leather Crossbody Bag', price: '$129.99', originalPrice: '$159.99', color: '#d4a574' },
+ { slug: 'oversized-wool-coat', name: 'Oversized Wool Coat', price: '$249.99', color: '#1e293b' },
+ { slug: 'silk-scarf', name: 'Silk Scarf Collection', price: '$59.99', color: '#c4b5fd' },
+ ];
+
+ return (
+
+ {/* Hero */}
+
+
+
+
+
+ Welcome to {{projectName}}
+
+
+ Discover our curated {{variant}} collection — where timeless elegance meets modern design.
+
+
+
+ Shop Now
+
+
+ View Collections
+
+
+
+
+
+
+ {/* Categories */}
+
+ Shop by Category
+
+ {categories.map((cat) => (
+
+
+
+
{cat.name}
+
{cat.count} items
+
+
+ ))}
+
+
+
+ {/* Featured Products */}
+
+
+
Featured Products
+ View All →
+
+
+ {featured.map((product) => (
+
+
+
+
{product.name}
+
+ {product.price}
+ {product.originalPrice && {product.originalPrice}}
+
+
+
+ ))}
+
+
+
+ {/* Newsletter */}
+
+
+
Join the {{projectName}} Community
+
Get 10% off your first order when you subscribe.
+
+
+
+
+
+
+
+ );
+}
diff --git a/templates/ecommerce/vite-react/src/pages/ProductDetail.tsx b/templates/ecommerce/vite-react/src/pages/ProductDetail.tsx
new file mode 100644
index 0000000..8df6720
--- /dev/null
+++ b/templates/ecommerce/vite-react/src/pages/ProductDetail.tsx
@@ -0,0 +1,101 @@
+import { useParams, Link } from 'react-router-dom';
+
+export default function ProductDetail() {
+ const { slug } = useParams();
+ const productName = (slug || 'product').replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
+
+ const sizes = ['XS', 'S', 'M', 'L', 'XL'];
+ const colors = [
+ { name: 'Black', hex: '#1a1a1a' },
+ { name: 'White', hex: '#ffffff' },
+ { name: 'Navy', hex: '#1e3a5f' },
+ { name: 'Red', hex: '#dc2626' },
+ ];
+
+ return (
+
+
+ {/* Breadcrumb */}
+
+
+
+ {/* Images */}
+
+
+
+ {[0, 1, 2, 3].map((i) => (
+
+ ))}
+
+
+
+ {/* Info */}
+
+
{productName}
+
+
+ {[1, 2, 3, 4, 5].map((star) => (
+
+ ))}
+
+
4.5 (128 reviews)
+
+
+
+ $99.99
+ $129.99
+
+
+
+ Crafted from premium materials with meticulous attention to detail. This piece combines timeless design with modern comfort.
+
+
+ {/* Colors */}
+
+
Color
+
+ {colors.map((c, i) => (
+
+ ))}
+
+
+
+ {/* Sizes */}
+
+
Size
+
+ {sizes.map((size, i) => (
+
+ ))}
+
+
+
+ {/* Quantity */}
+
+
Quantity
+
+
+ 1
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/templates/ecommerce/vite-react/src/pages/Products.tsx b/templates/ecommerce/vite-react/src/pages/Products.tsx
new file mode 100644
index 0000000..3d1e0a4
--- /dev/null
+++ b/templates/ecommerce/vite-react/src/pages/Products.tsx
@@ -0,0 +1,76 @@
+import { Link } from 'react-router-dom';
+
+export default function Products() {
+ const products = [
+ { slug: 'classic-white-sneakers', name: 'Classic White Sneakers', price: '$89.99', color: '#f1f5f9' },
+ { slug: 'leather-crossbody-bag', name: 'Leather Crossbody Bag', price: '$129.99', originalPrice: '$159.99', badge: 'Sale', color: '#d4a574' },
+ { slug: 'oversized-wool-coat', name: 'Oversized Wool Coat', price: '$249.99', badge: 'New', color: '#1e293b' },
+ { slug: 'silk-scarf', name: 'Silk Scarf Collection', price: '$59.99', color: '#c4b5fd' },
+ { slug: 'cashmere-sweater', name: 'Cashmere V-Neck Sweater', price: '$179.99', originalPrice: '$219.99', badge: 'Sale', color: '#fef3c7' },
+ { slug: 'tailored-blazer', name: 'Tailored Linen Blazer', price: '$199.99', badge: 'New', color: '#e2e8f0' },
+ { slug: 'canvas-tote', name: 'Canvas Tote Bag', price: '$49.99', color: '#d6d3d1' },
+ { slug: 'gold-earrings', name: 'Gold Hoop Earrings', price: '$39.99', color: '#fde68a' },
+ { slug: 'chelsea-boots', name: 'Leather Chelsea Boots', price: '$189.99', badge: 'New', color: '#292524' },
+ ];
+
+ const categories = ['Clothing', 'Shoes', 'Bags', 'Accessories'];
+
+ return (
+
+
+
+
All Products
+
Showing {products.length} products
+
+
+
+ {/* Filters */}
+
+
+ {/* Grid */}
+
+
+ {products.map((product) => (
+
+
+
+ {product.badge && (
+
+ {product.badge}
+
+ )}
+
+
+
{product.name}
+
+ {product.price}
+ {product.originalPrice && {product.originalPrice}}
+
+
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/templates/ecommerce/vite-react/tailwind.config.ts b/templates/ecommerce/vite-react/tailwind.config.ts
new file mode 100644
index 0000000..c677f76
--- /dev/null
+++ b/templates/ecommerce/vite-react/tailwind.config.ts
@@ -0,0 +1,28 @@
+import type { Config } from 'tailwindcss';
+
+const config: Config = {
+ content: ['./index.html', './src/**/*.{ts,tsx}'],
+ theme: {
+ extend: {
+ colors: {
+ background: 'var(--bg-color)',
+ 'bg-secondary': 'var(--bg-secondary)',
+ foreground: 'var(--text-color)',
+ 'text-secondary': 'var(--text-secondary)',
+ primary: 'var(--primary)',
+ 'primary-hover': 'var(--primary-hover)',
+ border: 'var(--border-color)',
+ card: 'var(--card-bg)',
+ },
+ borderRadius: {
+ theme: 'var(--radius)',
+ },
+ fontFamily: {
+ theme: 'var(--font-family)',
+ },
+ },
+ },
+ plugins: [],
+};
+
+export default config;
diff --git a/templates/ecommerce/vite-react/tsconfig.json b/templates/ecommerce/vite-react/tsconfig.json
new file mode 100644
index 0000000..3934b8f
--- /dev/null
+++ b/templates/ecommerce/vite-react/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/templates/ecommerce/vite-react/tsconfig.node.json b/templates/ecommerce/vite-react/tsconfig.node.json
new file mode 100644
index 0000000..42872c5
--- /dev/null
+++ b/templates/ecommerce/vite-react/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/templates/ecommerce/vite-react/vite.config.ts b/templates/ecommerce/vite-react/vite.config.ts
new file mode 100644
index 0000000..0466183
--- /dev/null
+++ b/templates/ecommerce/vite-react/vite.config.ts
@@ -0,0 +1,6 @@
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig({
+ plugins: [react()],
+});