@calmsey/frontend-toolkit
v0.0.1
Published
A modern Next.js frontend boilerplate with automatic API code generation, authentication, and UI components
Maintainers
Readme
Frontend Toolset
A modern Next.js frontend boilerplate with automatic API code generation, authentication, and UI components.
🎯 Use Cases
This project supports two scenarios for API usage:
- Fullstack - Using Next.js API Routes (integrated backend)
- External API - Consuming API from a separate backend (microservices, REST API, etc.)
See API_ARCHITECTURE.md for a complete guide.
🚀 Features
- Next.js 15 - App Router with Server Components
- TypeScript - Type-safe development
- TanStack Query (React Query) - Powerful data fetching and caching
- NextAuth.js - Authentication with JWT strategy
- Orval - Automatic API client generation from OpenAPI/Swagger
- Shadcn UI - Beautiful and accessible UI components
- Tailwind CSS - Utility-first CSS framework
- Axios - HTTP client with interceptors for auth
📁 Project Structure
frontend-toolset/
├── public/ # Static assets
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── (auth)/ # Auth route group (login, register)
│ │ ├── (dashboard)/ # Dashboard route group (protected)
│ │ ├── api/ # API routes
│ │ │ └── auth/ # NextAuth endpoints
│ │ ├── layout.tsx # Root layout with providers
│ │ ├── page.tsx # Homepage
│ │ └── globals.css # Global styles
│ │
│ ├── components/ # UI Components
│ │ ├── ui/ # Shadcn UI components
│ │ ├── shared/ # Shared components (Navbar, Footer)
│ │ └── forms/ # Form components
│ │
│ ├── hooks/ # Custom React hooks
│ │
│ ├── lib/ # Library configurations
│ │ ├── auth.ts # NextAuth configuration
│ │ ├── axios.ts # Axios instance with interceptors
│ │ ├── query-client.ts # React Query configuration
│ │ └── utils.ts # Utility functions (cn merger)
│ │
│ ├── services/ # API Integration Layer
│ │ ├── api/ # Auto-generated by Orval
│ │ │ ├── model/ # TypeScript interfaces from OpenAPI
│ │ │ └── endpoints/ # Generated React Query hooks
│ │ └── custom/ # Manual API services
│ │
│ ├── schemas/ # Zod validation schemas
│ ├── store/ # State management (Zustand/Jotai)
│ ├── types/ # Global TypeScript types
│ └── providers/ # React context providers
│
├── orval.config.js # Orval configuration
├── tailwind.config.ts # Tailwind configuration
├── components.json # Shadcn UI configuration
├── next.config.mjs # Next.js configuration
└── tsconfig.json # TypeScript configuration🛠️ Quick Start
Option 1: Install via npx (Recommended)
Create a new project instantly:
npx @wisnuvb/frontend-toolkit my-app
cd my-app
npm run devOption 2: Clone from Repository
- Clone the repository:
git clone <repository-url>
cd frontend-toolset- Install dependencies:
npm install- Create environment file:
# Copy ENV_TEMPLATE.md content to .env.local
# Or generate NEXTAUTH_SECRET:
openssl rand -base64 32- Update environment variables in
.env.local:
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-generated-secret-key
NEXT_PUBLIC_API_URL=http://localhost:3000/api- Configure Orval:
- Update
orval.config.jswith your OpenAPI/Swagger spec URL - Run API generation:
- Update
npm run generate:api- Start development server:
npm run devVisit http://localhost:3000
Prerequisites
- Node.js 18+
- npm/yarn/pnpm
📝 Usage
API Code Generation with Orval
Orval automatically generates TypeScript types and React Query hooks from your OpenAPI spec.
- Configure OpenAPI source in
orval.config.js:
input: {
target: 'https://api.example.com/swagger.json', // Your API spec
}- Generate API client:
npm run generate:api- Use generated hooks:
import { useGetUsers } from '@/services/api/endpoints/users';
function UsersList() {
const { data, isLoading, error } = useGetUsers();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error loading users</div>;
return (
<ul>
{data?.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}Authentication
The project uses NextAuth.js with JWT strategy.
Login example:
import { signIn } from 'next-auth/react';
const handleLogin = async () => {
await signIn('credentials', {
email: '[email protected]',
password: 'password',
});
};Protected routes:
'use client';
import { useSession } from 'next-auth/react';
import { redirect } from 'next/navigation';
export default function ProtectedPage() {
const { data: session, status } = useSession();
if (status === 'unauthenticated') {
redirect('/login');
}
return <div>Protected content</div>;
}Using Shadcn UI Components
Install components as needed:
npx shadcn@latest add button
npx shadcn@latest add card
npx shadcn@latest add inputUse in your components:
import { Button } from '@/components/ui/button';
function MyComponent() {
return <Button>Click me</Button>;
}Forms with React Hook Form + Zod
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
type FormData = z.infer<typeof schema>;
function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
const onSubmit = (data: FormData) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('email')} />
{errors.email && <span>{errors.email.message}</span>}
<input type="password" {...register('password')} />
{errors.password && <span>{errors.password.message}</span>}
<button type="submit">Login</button>
</form>
);
}🔧 Configuration
Axios Interceptors
The Axios instance in src/lib/axios.ts automatically:
- Adds Bearer token from NextAuth session
- Handles 401 Unauthorized responses
- Can be extended for other interceptors
React Query Settings
Configured in src/lib/query-client.ts:
- Default stale time: 1 minute
- Retry failed requests: 1 time
- No refetch on window focus
API Base URL
Set in environment variables:
NEXT_PUBLIC_API_URL=https://api.example.com📜 Available Scripts
npm run dev- Start development server with Turbopacknpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLintnpm run generate:api- Generate API client from OpenAPI spec
🎨 Customization
Tailwind Theme
Customize colors and styling in tailwind.config.ts.
Shadcn UI Theme
Modify CSS variables in src/app/globals.css to change theme colors.
Adding New API Endpoints (Manual)
For endpoints not covered by Orval:
- Create a service in
src/services/custom/:
// src/services/custom/my-service.ts
import { axiosInstance } from '@/lib/axios';
export const myCustomApi = {
getData: async () => {
const { data } = await axiosInstance.get('/custom-endpoint');
return data;
},
};- Create a React Query hook:
// src/hooks/useCustomData.ts
import { useQuery } from '@tanstack/react-query';
import { myCustomApi } from '@/services/custom/my-service';
export function useCustomData() {
return useQuery({
queryKey: ['customData'],
queryFn: myCustomApi.getData,
});
}🚀 Deployment
Vercel (Recommended)
- Push code to GitHub
- Import project in Vercel
- Configure environment variables
- Deploy
Docker
docker build -t frontend-toolset .
docker run -p 3000:3000 frontend-toolset📚 Resources
📄 License
MIT
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
