Nano Banana Pro
Agent skill for nano-banana-pro
A production-ready full-stack React application template with integrated Express server, featuring React Router 6 SPA mode, TypeScript, Vitest, Zod and modern tooling.
Sign in to like and favorite skills
A production-ready full-stack React application template with integrated Express server, featuring React Router 6 SPA mode, TypeScript, Vitest, Zod and modern tooling.
While the starter comes with a express server, only create endpoint when strictly neccesary, for example to encapsulate logic that must leave in the server, such as private keys handling, or certain DB operations, db...
client/ # React SPA frontend ├── pages/ # Route components (Index.tsx = home) ├── components/ui/ # Pre-built UI component library ├── App.tsx # App entry point and with SPA routing setup └── global.css # TailwindCSS 3 theming and global styles server/ # Express API backend ├── index.ts # Main server setup (express config + routes) └── routes/ # API handlers shared/ # Types used by both client & server └── api.ts # Example of how to share api interfaces
The routing system is powered by React Router 6:
client/src/pages/Index.tsx represents the home page.client/src/App.tsx using the react-router-dom importclient/src/pages/ directoryFor example, routes can be defined with:
import { BrowserRouter, Routes, Route } from "react-router-dom"; <Routes> <Route path="/" element={<Index />} /> {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} <Route path="*" element={<NotFound />} /> </Routes>;
client/src/global.cssclient/src/components/ui/cn() function combines clsx + tailwind-merge for conditional classes// cn utility usage className={cn( "base-classes", { "conditional-class": condition }, props.className // User overrides )}
/api/GET /api/ping - Simple ping apiGET /api/demo - Demo endpointImport consistent types in both client and server:
import { DemoResponse } from "@shared/api";
Path aliases:
@shared/* - Shared folder@/* - Client folderpnpm dev # Start dev server (client + server) pnpm build # Production build pnpm start # Start production server pnpm typecheck # TypeScript validation pnpm test # Run Vitest tests
Open
client/global.css and tailwind.config.ts and add new tailwind colors.
shared/api.ts:export interface MyRouteResponse { message: string; // Add other response properties here }
server/routes/my-route.ts:import { RequestHandler } from "express"; import { MyRouteResponse } from "@shared/api"; // Optional: for type safety export const handleMyRoute: RequestHandler = (req, res) => { const response: MyRouteResponse = { message: "Hello from my endpoint!", }; res.json(response); };
server/index.ts:import { handleMyRoute } from "./routes/my-route"; // Add to the createServer function: app.get("/api/my-endpoint", handleMyRoute);
import { MyRouteResponse } from "@shared/api"; // Optional: for type safety const response = await fetch("/api/my-endpoint"); const data: MyRouteResponse = await response.json();
client/pages/MyPage.tsxclient/App.tsx:<Route path="/my-page" element={<MyPage />} />
pnpm build