A robust full-stack template based on Josh's work, modified and enhanced with custom authentication ,session management and Redux -RTK Query 's integrated by Afdhali.
- Framework: Next.js 14
- API Layer: Hono
- Database: PostgreSQL (on-premise) with Prisma ORM
- Authentication: Supabase Auth
- State Management & Data Fetching: Redux Toolkit + RTK Query
- Persistence: Redux Persist
- Type Safety: TypeScript + Zod
- Styling: Tailwind CSS
- Data Serialization: SuperJSON
-
π Custom Auth & Session Management
- Secure cookie-based authentication
- Session tracking with device management
- Auto token refresh
- Persistent sessions with database backup
-
π οΈ Developer Experience
- Type-safe API routes with Hono
- Prisma for database management
- RTK Query for API calls
- Zod validation
- Full TypeScript support
-
π¦ Pre-configured Setup
- Redux store with persistence
- RTK Query integration
- Protected routes
- Error handling
- Typescript configurations
- ESLint setup
-
Clone & Install
git clone <repository-url> cd your-project-name npm install
-
Environment Setup
- Copy
.env.sampleto.env
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key DATABASE_URL=your_postgresql_url REDIS_URL=your_redis_url REDIS_TOKEN=your_redis_token
- Copy
-
Database Setup
npx prisma generate npx prisma db push
-
Development Server
npm run dev
src/
βββ app/ # Next.js app directory
βββ components/ # React components
βββ server/ # Hono API routes
β βββ __internals/ # Internal API utilities
β βββ routers/ # API route handlers
βββ lib/ # Utility functions
βββ hooks/ # Custom React hooks
βββ store/ # Redux store setup
β βββ api.ts # RTK Query API definitions
β βββ store.ts # Redux store configuration
βββ types/ # TypeScript types
The template comes with pre-configured RTK Query integration in /store/api.ts. You can easily add your data fetching logic:
// src/store/api.ts
export const api = createApi({
reducerPath: "api",
baseQuery: async (args: unknown) => {
try {
const result = await args;
return { data: result };
} catch (error) {
return { error };
}
},
endpoints: (builder) => ({
// Add your endpoints here
getUsers: builder.query<User[], void>({
query: () => client.users.getUsers.$get(),
}),
createUser: builder.mutation<User, CreateUserInput>({
query: (input) => client.users.createUser.$post(input),
}),
}),
});
// Export hooks for usage in components
export const { useGetUsersQuery, useCreateUserMutation } = api;Benefits:
- Automatic caching
- Loading & error states
- Optimistic updates
- TypeScript support
- Automatic re-fetching
- Cache invalidation
The template provides a streamlined way to create type-safe API endpoints. Here's how:
// /server/routers/users-router.ts
import { router } from "../__internals/router";
import { z } from "zod";
import { privateProcedure, publicProcedure } from "../procedures";
export const usersRouter = router({
// Public endpoint example
getUsers: publicProcedure.query(async ({ c }) => {
const users = await db.user.findMany();
return c.json({ users });
}),
// Protected endpoint with input validation
createUser: privateProcedure
.input(
z.object({
name: z.string(),
email: z.string().email(),
})
)
.mutation(async ({ c, input, ctx }) => {
const user = await db.user.create({
data: input,
});
return c.json({ user });
}),
});import { Hono } from "hono";
import { usersRouter } from "./routers/users-router";
const app = new Hono().basePath("/api");
/**
* Register your routers here
*/
const appRouter = app.route("/users", usersRouter); // This makes endpoints available at /api/users/*
// Add more routers here
export type AppType = typeof appRouter;export const api = createApi({
reducerPath: "api",
baseQuery: /* ... */,
endpoints: (builder) => ({
// The endpoint name pattern follows:
// client.<main_endpoint>.<controller_name>.<$get or $post>
getUsers: builder.query<User[], void>({
query: () => client.users.getUsers.$get(),
}),
createUser: builder.mutation<User, CreateUserInput>({
query: (input) => client.users.createUser.$post(input),
}),
}),
});function UsersList() {
// Type-safe hooks are automatically generated
const { data: users, isLoading } = useGetUsersQuery();
const [createUser] = useCreateUserMutation();
return (
// Your component JSX
);
}- π Complete Type Safety: From API definition to client usage
- π‘ IntelliSense Support: Get autocomplete for endpoints and their parameters
- π‘οΈ Runtime Validation: Using Zod for input validation
- π Automatic Type Generation: RTK Query generates typed hooks
- π Documentation: Types serve as documentation
- π Error Prevention: Catch errors at compile time
The template uses a custom authentication system built on top of Supabase Auth:
- Cookie-based token storage
- Database session tracking
- Device management
- Auto token refresh
- Session timeout handling
You can easily deploy with this template on & with :
- On Premise (such as VPS) by Docker
- On Vercel, with Neon's Postgres Database
- On Cloudflare Worker's as Edge Severless, with Neon's Postgres Database & wrangler
For issues and feature requests:
- Original template by: Josh's GitHub
- Auth modifications & Redux - RTK Query integrated by: Afdhali's GitHub
This project is licensed under the MIT License.
Built with β€οΈ using Next.js, Hono, and RTK Query