A modern, production-ready Next.js 15 boilerplate with TypeScript, Zod validation, Mantine UI, TanStack Query, and Zustand for state management.
- β‘οΈ Next.js 15 with App Router
- π― TypeScript for type safety
- β Zod for schema validation with automatic type inference
- π¨ Mantine UI for beautiful, accessible components
- π TanStack Query (React Query) for data fetching and caching
- ποΈ Zustand for simple and scalable state management
- π‘ Axios for HTTP requests
- ποΈ Organized project structure with clear separation of concerns
src/
βββ app/ # Next.js app router pages
β βββ layout.tsx # Root layout
β βββ page.tsx # Home page
β βββ mock-form/ # Form example page
β βββ random-facts/ # API integration example
βββ components/ # Reusable React components
β βββ BackButton.tsx
β βββ MockForm.tsx
βββ constants/ # Application constants
βββ hooks/ # Custom React hooks
β βββ useMockMutation.ts
β βββ useRandomFactsQuery.ts
βββ layouts/ # Layout components
β βββ BasicAppShellLayout.tsx
βββ providers/ # Context providers
β βββ MantineProvider.tsx
β βββ QueryClientProvider.tsx
β βββ RootProvider.tsx
βββ schema/ # Zod validation schemas
β βββ mockFormSchema.ts
βββ services/ # API services
β βββ api/
β β βββ apiClient.ts
β βββ mockFormService.ts
β βββ randomFactsService.ts
βββ store/ # Zustand stores
β βββ store.ts
βββ styles/ # Global styles
βββ global.css
- Framework: Next.js 15.1.2
- Language: TypeScript 5+
- Validation: Zod 3.23+ with mantine-form-zod-resolver
- UI Library: Mantine 7.15+
- Data Fetching: TanStack Query 5.62+
- State Management: Zustand 5.0+
- HTTP Client: Axios 1.7+
- Icons: Tabler Icons React
# Clone the repository
git clone <your-repo-url>
# Navigate to project directory
cd frontend-boilerplate-next
# Install dependencies
npm installRun the development server:
npm run devOpen http://localhost:3000 in your browser.
npm run dev # Start development server
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLintDefine schemas with automatic TypeScript type inference:
import { z } from "zod";
export const mockFormSchema = z.object({
name: z.string().min(1, "Name is required"),
age: z.number().positive("Age must be positive"),
gender: z.enum(["MALE", "FEMALE"]),
});
// Automatically inferred type
export type MockFormValues = z.infer<typeof mockFormSchema>;export const useRandomFactsQuery = () => {
return useQuery({
queryKey: ["randomFacts"],
queryFn: getRandomFacts,
enabled: false,
});
};interface CounterStore {
count: number;
increment: () => void;
decrement: () => void;
}
export const useCounterStore = create<CounterStore>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}));- State Management (
/) - Zustand counter with localStorage persistence - Form Validation (
/mock-form) - Mantine Form with Zod validation - API Integration (
/random-facts) - TanStack Query with external API
tsconfig.json- TypeScript configurationnext.config.ts- Next.js configurationpackage.json- Dependencies and scripts
Create a new folder in src/app/:
// src/app/new-page/page.tsx
export default function NewPage() {
return <div>New Page</div>;
}Create schemas in src/schema/:
import { z } from "zod";
export const mySchema = z.object({
// your fields
});
export type MySchemaType = z.infer<typeof mySchema>;Create hooks in src/hooks/:
import { useQuery } from "@tanstack/react-query";
export const useMyQuery = () => {
return useQuery({
queryKey: ["myQuery"],
queryFn: myService,
});
};- Push your code to GitHub
- Import project on Vercel
- Deploy automatically
Build the project:
npm run build
npm run startThis project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Feel free to submit issues or pull requests.