A modern Next.js 15 starter template with Supabase authentication, React Query for data fetching, and built-in wrappers for queries and authentication. This starter is designed to accelerate development by providing preconfigured hooks, utilities, and best practices.
- Next.js 15 โ The latest Next.js version for optimized performance.
- Supabase Authentication โ Built-in auth system with user session handling.
- React Query โ Efficient data fetching and caching.
- ShadCN Components โ Prebuilt UI components for faster development.
- Tailwind CSS โ Utility-first styling for rapid UI building.
- Zod Validation โ Schema-based form validation for better data handling.
- Prebuilt Hooks โ Hooks for fetching data and mutations in client components.
- Query & Auth Wrappers โ Easily manage authentication state and query handling.
Create a new project using the CLI (if available):
npx create-next-supabase-starter@latest my-projectOr manually clone the repository:
git clone https://github.com/your-username/your-repo.git my-project
cd my-project
pnpm installCreate a .env.local file and add:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_keypnpm devYour app should be running at http://localhost:3000.
The AuthContext ensures user authentication is managed across the app.
"use client";
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export function AuthProvider({ children }: { children: React.ReactNode }) {
const { data: user, isLoading } = useQuery({
queryKey: ["user"],
queryFn: async () => {
const { data } = await supabase.auth.getUser();
return data?.user ?? null; // โ
Ensures it's never undefined
},
staleTime: 0,
});
return (
<AuthContext.Provider value={{ user: user ?? null, loading: isLoading }}>
{children}
</AuthContext.Provider>
);
}
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error("useAuth must be used within an AuthProvider");
}
return context;
}Use the useClientFetch hook for fetching data efficiently on client components:
import { useClientFetch } from "@/hooks/useClientFetch";
const Posts = () => {
const { data, isLoading } = useClientFetch("posts", "posts");
if (isLoading) return <p>Loading...</p>;
return (
<ul>
{data?.map((post) => (
<li key={post.id}>{post.name}</li>
))}
</ul>
);
};const FilteredUsers = () => {
const { data, isLoading } = useClientFetch(
"filtered-users", // key
"users", // table name
5000, // cache time
(query) => query.eq("role", "admin") // Supabase query filter
);
if (isLoading) return <p>Loading...</p>;
return (
<ul>
{data?.map((user) => (
<li key={user.id}>
{user.name} ({user.role})
</li>
))}
</ul>
);
};Use the useClientMutate hook for inserting, updating, and deleting data on client components:
import { useClientMutate } from "@/hooks/useClientMutate";
const AddPost = () => {
const mutation = useClientMutate("posts", "insert");
const handleSubmit = async () => {
mutation.mutate({ id: Date.now(), name: "New Post" });
};
return <button onClick={handleSubmit}>Add Post</button>;
};const UpdatePost = () => {
const mutation = useClientMutate("posts", "update");
const handleUpdate = () => {
mutation.mutate({ id: 1, name: "Updated Post" });
};
return <button onClick={handleUpdate}>Update User</button>;
};const DeleteUser = () => {
const mutation = useClientMutate("users", "delete");
const handleDelete = () => {
mutation.mutate({ id: 1 });
};
return <button onClick={handleDelete}>Delete User</button>;
};๐ฆ my-project
โโโ ๐ app # Next.js app directory
โ โโโ ๐ (auth) # Authentication pages
โ โ โโโ ๐ auth # Authentication utilities
โ โ โ โโโ ๐ confirm # Confirmation route
โ โ โ โ โโโ route.ts
โ โ โโโ ๐ error # Error handling
โ โ โโโ ๐ login # Login page
โ โ โโโ ๐ register # Register page
โ โ โโโ actions.ts # Auth actions
โ โ โโโ layout.tsx # Auth layout
โ โโโ ๐ (dashboard) # Dashboard pages
โ โโโ favicon.ico # Favicon
โ โโโ globals.css # Global styles
โ โโโ layout.tsx # Main layout
โ โโโ not-found.tsx # 404 Page
โ โโโ page.tsx # Home page
โโโ ๐ components # Shared UI components
โโโ ๐ hooks # Custom React Query hooks
โ โโโ use-client-fetch.ts
โ โโโ use-client-mutation.ts
โโโ ๐ lib # Utilities & helpers
โโโ ๐ public # Static assets
โโโ ๐ supabase # Supabase integrations clients
โ โโโ client.ts # Supabase client
โ โโโ middleware.ts # Middleware configuration
โ โโโ server.ts # Server-side Supabase utilities
โโโ ๐ node_modules # Dependencies
โโโ .env # Environment configuration
โโโ .env.example # Example environment variables
โโโ .gitignore # Git ignore file
โโโ components.json # UI component configurations
โโโ eslint.config.mjs # ESLint configuration
โโโ middleware.ts # Global middleware
โโโ next-env.d.ts # Next.js environment types
โโโ next.config.ts # Next.js configuration
โโโ package.json # Project dependencies
โโโ pnpm-lock.yaml # Lock file
โโโ postcss.config.mjs # PostCSS configuration
โโโ README.md # Project documentation
โโโ tailwind.config.ts # Tailwind CSS configuration
โโโ tsconfig.json # TypeScript configuration
- Next.js 15
- Supabase
- React Query
- ShadCN Components
- Tailwind CSS
- Zod Validation
- TypeScript