A modern full-stack template featuring Next.js for frontend and NestJS for backend, with built-in authentication, email service, and more.
- Frontend: Next.js 14 with App Router
- Backend: NestJS with Prisma ORM
- UI Components: shadcn/ui components
- Authentication: JWT-based auth system
- Email Service: Built-in email service with templates
- Docker Support: Containerization ready
- Type Safety: Full TypeScript support
- API Client: Axios-based API client with interceptors, automatic token handling, and type-safe responses
- Form Validation: Zod-based schema validation
- State Management: Built-in store setup
- Theme: Dark/Light mode support
- LLM Service: Built-in LLM service with Gemini support, type-safe responses, and retry mechanisms
- Node.js 20+
- pnpm
- Docker (optional, for containerized deployment)
-
Frontend Setup
cd web cp .env.example .env pnpm install -
Backend Setup
cd server cp .env.example .env pnpm install -
Database Setup
cd server pnpm prisma generate pnpm prisma db push
-
Start Backend Server
cd server pnpm start:dev -
Start Frontend Development Server
cd web pnpm dev
Using Docker:
./deploy-docker.shβββ web/ # Frontend (Next.js)
β βββ app/ # App router pages
β βββ components/ # React components
β βββ constants/ # Constants files
β βββ hooks/ # React Hooks
β βββ lib/ # Lib Functions like, ApiClient, authOptions for NextAuth
β βββ config/ # Mainly for Environment config
β βββ services/ # API services Must call backend apis through this
β βββ store/ # Zustand State management use for global state management
β βββ utils/ # All utils Functions goes here
β βββ validations/ # Zod schemas
β βββ types/ # TypeScript types
β
βββ server/ # Backend (NestJS)
β βββ src/
β β βββ auth/ # Authentication module
β β βββ mail/ # Email service
β β βββ prisma/ # Database module
β βββ prisma/ # Prisma schema & client
β
βββ docs/ # Documentation
- Use TypeScript for all new code
- Follow ESLint and Prettier configurations
- Use meaningful commit messages following commitlint
-
Components
- Use functional components with hooks
- Follow atomic design principles
- Place reusable components in
components/directory - Use shadcn/ui components for consistent UI
- Always write modular and clean code
- Follow DRY principle
-
State Management
- Use React hooks for local state
- Implement global state in
store/directory - Keep state logic separate from UI components
-
API Integration
- Use services from
services/directory for all API calls - Create type-safe service methods using ApiClient
- Implement proper loading states and error handling
- Never call API endpoints directly; always create a service method
- Example service pattern:
// services/user.service.ts import { ApiClient } from '@/lib/api-client'; import { User, UpdateUserDto } from '@/types'; export class UserService { static async getProfile() { return await ApiClient.get<User>('/api/users/profile'); } static async updateProfile(data: UpdateUserDto) { return await ApiClient.patch<User>('/api/users/profile', data); } }
- Use services from
-
Routing
- Use App Router conventions
- Implement proper loading and error states
- Keep route handlers clean and focused
-
Architecture
- Follow NestJS module architecture
- Use dependency injection
- Implement DTOs for data validation, add ApiProperty Tag to each dto field for swagger
- Follow RESTful API conventions
-
Database
- Use Prisma for database operations
- Write clean and optimized queries
- Use transactions where necessary
-
Security
- Implement proper authentication checks
- Validate all input data
- Follow security best practices
- Use environment variables for sensitive data
The ApiClient class provides a type-safe way to make HTTP requests with automatic token handling and error formatting:
// Example usage:
import { ApiClient } from '@/lib/api-client';
// GET request
const response = await ApiClient.get<UserType>('/api/users/profile');
if (response.data) {
// response.data is typed as UserType
console.log(response.data);
} else {
// response.error contains formatted error details
console.error(response.error.message);
}
// POST request with data
const loginResponse = await ApiClient.post<LoginResponse>('/api/auth/login', {
email,
password
});Return type for all API calls:
type ApiResult<T> =
| {
data: T;
error?: never;
}
| {
data?: never;
error: {
message: string;
status: number;
details?: Record<string, unknown>;
};
};The authentication system provides:
- JWT-based authentication with automatic token handling
- Multiple authentication methods:
- Google OAuth authentication
- Email OTP-based authentication
- Protected routes by default with
@Public()decorator for public endpoints - Easy access to user data via
@CurrentUser()decorator - Type-safe user information with
RequestUserinterface
Detailed Authentication Documentation
The email service features:
- Type-safe template system with HTML support
- Built-in templates for OTP and Welcome emails
- Easy template creation with TypeScript types
- Automatic context validation
- Placeholder system using
{{variableName}}syntax
Detailed Email Templates Documentation
The LLM service features:
- Type-safe interaction with Large Language Models
- Support for both string and JSON responses
- Configurable retry mechanisms with exponential backoff
- Temperature control for response randomness
- Automatic error handling and response formatting
- Built-in support for Gemini model
Detailed LLM Service Documentation
- Extract Text from File
- Supported File Types : PDF, DOCX, TEXT, CSV, XLSX
- Just Call extract
async extractTextFromDocument(file: Express.Multer.File):stringfunction.