create-nextjs-stack
v0.3.4
Published
CLI to scaffold a Next.js Landing Page and Admin Panel, backed by Supabase or Contentful
Downloads
25
Maintainers
Readme
create-nextjs-stack
A zero-config CLI for production-ready Next.js applications.
Scaffold a web app, an admin panel, or both — backed by Supabase or Contentful.
Quick Start · Templates · Project Structure · Environment Variables · Deployment · Contributing
Table of Contents
- Overview
- Quick Start
- CLI Reference
- Templates
- Project Structure
- Environment Variables
- Development
- Deployment
- FAQ
- Contributing
- Changelog
- License
🔍 Overview
create-nextjs-stack handles the tedious setup so that you can start building immediately. In a single command it:
- Scaffolds a fully configured Next.js 16 application
- Lets you choose Supabase or Contentful without changing the UI layer
- Copies
.env.exampleto.envso credentials are ready to fill - Sets the project name inside
package.jsonautomatically - Prints exact next steps so you never have to guess
The result follows real-world practices — App Router, TypeScript, Tailwind CSS 4, a typed service layer, CMS-aware authentication, SEO metadata, and more — without manual wiring.
⚡ Quick Start
# Using npx (no install required)
npx create-nextjs-stack@latest my-app
# Using npm
npm create nextjs-stack@latest my-app
# Global install (optional)
npm install -g create-nextjs-stack
create-nextjs-stack my-appThe interactive CLI will guide you:
? What is your project named? › my-app
? Which template would you like to generate?
❯ Full Stack (Web + Admin)
Web Only (Next.js Landing)
Admin Only (CMS Admin)
? Which data source would you like to use?
❯ Supabase
ContentfulAfter scaffolding:
cd my-app
npm install # install dependencies
# Open .env and fill in your credentials, then:
npm run dev # start development server at http://localhost:3000🖥 CLI Reference
Usage: create-nextjs-stack [project-directory] [options]
Arguments:
project-directory Target directory for the new project (optional, prompted if omitted)
Options:
-t, --template <type> Template to scaffold: web | admin | full-stack
-c, --cms <type> Data source: supabase | contentful (default: supabase)
-v, --version Print CLI version
-h, --help Show helpExamples
# Interactive — prompts for name, template and data source
npx create-nextjs-stack
# Named project, interactive selection
npx create-nextjs-stack my-app
# Fully non-interactive
npx create-nextjs-stack my-app --template web
npx create-nextjs-stack my-app --template admin
npx create-nextjs-stack my-app --template full-stack
# Contentful instead of Supabase
npx create-nextjs-stack my-app --template full-stack --cms contentfulData Sources
The template you pick decides what gets scaffolded; --cms decides where the
content lives. Both templates work with either data source — pages, components
and the admin CRUD are identical.
| | Supabase (default) | Contentful |
| --- | --- | --- |
| Content storage | Postgres tables | Contentful content types |
| Web reads through | @supabase/ssr server client | Content Delivery API |
| Admin writes through | Supabase client | Content Management API |
| Admin auth | Supabase Auth | Auth.js credentials (ADMIN_EMAIL + bcrypt hash) |
| Schema bootstrap | supabase_schema.sql | npm run contentful:setup |
| Draft preview | — | /api/preview + Preview API |
| On-publish revalidation | /api/revalidate | Contentful webhook → /api/revalidate/contentful |
| Rich text | — | body field + <RichText /> |
Field and content type names are deliberately kept identical between the two
(products, featured_image_url, category_id, …), so switching data sources
does not ripple into your UI code.
A scaffolded Contentful project ships with a CONTENTFUL.md covering space
setup, tokens, webhooks and the admin login.
Overwrite Behaviour
If the target directory already exists and is non-empty, the CLI will ask:
Directory my-app is not empty. Overwrite? (y/N)If you confirm, the directory is emptied before scaffolding. If you decline, the process aborts safely.
📦 Templates
🌐 Web — Landing Page
A production-ready Next.js marketing website starter.
Tech Stack
| Layer | Technology | Notes |
| ---------------- | ----------------------------------------------------------------------------------------------- | ---------------------------- |
| Framework | Next.js 16 | App Router, Turbopack |
| Language | TypeScript 5 | Strict mode |
| Styling | Tailwind CSS 4 | @tailwindcss/postcss |
| State Management | Redux Toolkit | Typed slices + actions |
| Content | Supabase or Contentful | Selected with --cms |
| Media | Cloudinary + next-cloudinary | Optimized image delivery |
| Email | Resend | Transactional emails |
| Analytics | Google Analytics | Via @next/third-parties |
| Forms | React Hook Form + Zod | Schema validation |
| Animations | Framer Motion | Page & component transitions |
| Icons | Lucide React + React Icons | |
Feature Highlights
- ⚡ Turbopack for sub-second dev rebuilds and faster production builds
- 🔍 Full SEO Suite — dynamic
metadataAPI,sitemap.ts,robots.ts, canonical URLs, and Open Graph tags all configurable from environment variables - 🎯 Service Layer — all external API calls go through
src/lib/services/, keeping components clean - 🗄 Pluggable Content Layer — Supabase SSR by default, or Contentful Delivery/Preview APIs with draft mode, rich text, and webhook revalidation
- 🖼 Cloudinary Integration — ready-to-use
CldImageandCldUploadWidgetcomponents vianext-cloudinary - 📬 Email Service — Resend integration with typed email helpers in the service layer
- 🔄 Redux Store — fully typed store with actions, reducers, and providers already wired in
- 📱 Responsive — mobile-first layout with Tailwind utilities
- 🌐 i18n Ready — folder structure supports multi-language routing expansion
🛠 Admin — CMS Panel
A minimal, extensible admin dashboard for managing Supabase or Contentful data.
Tech Stack
| Layer | Technology | Notes |
| --------------- | ----------------------------------------------------------- | ------------------------- |
| Framework | Next.js 16 | App Router |
| Language | TypeScript 5 | |
| Styling | Tailwind CSS 4 | tailwind-merge + clsx |
| Content | Supabase or Contentful | Selected with --cms |
| Authentication | Supabase Auth or Auth.js credentials | Matches the data source |
| Media | Cloudinary | Image uploads |
| Forms | React Hook Form | |
| Notifications | React Toastify | Toast alerts |
| Icons | Lucide React | |
| Utilities | clsx, tailwind-merge | Class merging helpers |
Feature Highlights
- 🔐 Server-side Auth — Supabase SSR sessions or Auth.js credentials with bcrypt password hashing
- 🔌 Shared CRUD Contract — the same forms and resource configuration work with Supabase and Contentful
- 🛡 Route Protection —
middleware.tsguards all dashboard routes; unauthenticated users are redirected to/login - 📊 Dashboard Layout — sidebar + header shell with nested route groups
(auth)and(dashboard) - ⚙ Server Actions — data mutations use Next.js Server Actions inside
app/actions/, keeping client bundles small - 🔔 Toast Notifications — React Toastify integrated at the root layout for global alerts
- 📷 Cloudinary Uploads — image upload utilities pre-configured
- 🧱 Component Library — reusable admin-specific components in
components/admin/
🏗 Full Stack
The full-stack template scaffolds both the Web and Admin templates into two independent subdirectories under a shared root:
my-app/
├── web/ ← Next.js landing page (port 3000)
└── admin/ ← CMS admin panel (port 3001)Each sub-project is completely independent — separate package.json, separate .env, separate node_modules and dev server. There is no shared monorepo config by design; this keeps the scaffold simple and avoids coupling.
Tip: Run each project in a separate terminal with
npm run dev. If ports conflict, pass-- --port 3001to the admin project.
📁 Project Structure
Web Template
The tree below shows the default Supabase output. With --cms contentful, the
CLI replaces src/lib/supabase/ with src/lib/contentful/, adds preview and
webhook routes, rich-text rendering, and Contentful setup/type-generation tools.
my-app/
├── public/
│ ├── og-image.png # Default Open Graph image
│ └── favicon.ico
│
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── layout.tsx # Root layout — fonts, providers, metadata
│ │ ├── page.tsx # Homepage
│ │ ├── robots.ts # Dynamic robots.txt generator
│ │ ├── sitemap.ts # Dynamic XML sitemap generator
│ │ └── api/ # API route handlers
│ │
│ ├── components/ # Shared UI components
│ │
│ ├── hooks/ # Custom React hooks
│ │
│ ├── lib/
│ │ ├── providers/
│ │ │ └── ReduxProvider.tsx # Wraps app with Redux store
│ │ ├── seo/
│ │ │ ├── seo.config.ts # Centralised SEO defaults
│ │ │ ├── metadata.ts # Page metadata helpers
│ │ │ └── structured-data.ts # JSON-LD schema helpers
│ │ ├── services/
│ │ │ ├── email.service.ts # Resend email helpers
│ │ │ ├── storage.service.ts # Cloudinary upload helpers
│ │ │ └── supabase.service.ts # Supabase query helpers
│ │ ├── supabase/
│ │ │ ├── client.ts # Browser Supabase client
│ │ │ ├── server.ts # Server Supabase client (SSR)
│ │ │ └── middleware.ts # Session refresh helper
│ │ └── utils/ # Shared utility functions
│ │
│ └── store/ # Redux Toolkit store
│ ├── index.ts # Store configuration
│ ├── actions/ # Action creators
│ ├── reducers/ # Slice reducers
│ └── types/ # Store-wide TypeScript types
│
├── .env.example # All required env vars with descriptions
├── components.json # shadcn/ui config (if used)
├── next.config.ts
├── postcss.config.mjs # Tailwind CSS 4 PostCSS config
└── tsconfig.jsonAdmin Template
The tree below shows the default Supabase output. With --cms contentful, the
CLI replaces the Supabase layer with the Contentful Management API, swaps auth
to Auth.js credentials, removes the users resource, and adds content-model setup
and password-hashing scripts.
my-admin/
├── public/
│
├── app/ # Next.js App Router (no src/ wrapper)
│ ├── layout.tsx # Root layout — Toastify provider
│ ├── page.tsx # Redirects to /dashboard
│ ├── globals.css # Tailwind CSS 4 imports + theme tokens
│ │
│ ├── (auth)/ # Unauthenticated routes
│ │ └── login/
│ │ └── page.tsx # Login page
│ │
│ ├── (dashboard)/ # Protected routes (guarded by middleware)
│ │ ├── layout.tsx # Dashboard shell (sidebar + header)
│ │ ├── dashboard/ # Main dashboard page
│ │ ├── users/ # User management
│ │ ├── content/ # Content management
│ │ └── settings/ # App settings
│ │
│ └── actions/ # Next.js Server Actions
│ ├── auth.actions.ts # Login / logout / session
│ └── data.actions.ts # CRUD operations
│
├── components/
│ └── admin/ # Admin-specific components
│ ├── Sidebar.tsx
│ ├── Header.tsx
│ ├── DataTable.tsx
│ └── ...
│
├── config/
│ └── navigation.ts # Sidebar navigation config
│
├── hooks/ # Custom hooks
│
├── lib/
│ ├── supabase/
│ │ ├── client.ts # Browser Supabase client
│ │ └── server.ts # Server Supabase client (SSR)
│ └── utils/ # Shared helpers (cn, formatters…)
│
├── middleware.ts # Route protection — redirects to /login
├── .env.example
├── next.config.ts
├── postcss.config.mjs
└── tsconfig.json🔑 Environment Variables
The CLI automatically copies .env.example → .env during scaffolding. Open .env and replace the placeholder values with your real credentials.
Supabase Web Template Env
# ─── Email (Resend) ────────────────────────────────────────────────────────────
# https://resend.com → API Keys
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxx
# The verified sender address configured in your Resend domain
[email protected]
# ─── Supabase ──────────────────────────────────────────────────────────────────
# https://supabase.com → Project Settings → API
NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsIn...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsIn... # Never expose this client-side!
# Used to verify on-demand revalidation requests
REVALIDATION_SECRET=a-random-secret-string
# ─── Cloudinary ────────────────────────────────────────────────────────────────
# https://cloudinary.com → Dashboard
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your-cloud-name
CLOUDINARY_API_KEY=000000000000000
CLOUDINARY_API_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAME
# ─── Site ──────────────────────────────────────────────────────────────────────
NEXT_PUBLIC_SITE_URL=https://yourdomain.com # Used for canonical URLs & OG tags
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX # Google Analytics Measurement IDSupabase Admin Template Env
# ─── Supabase ──────────────────────────────────────────────────────────────────
NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsIn...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsIn... # Server-side only
# ─── Cloudinary ────────────────────────────────────────────────────────────────
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your-cloud-name
CLOUDINARY_API_KEY=000000000000000
CLOUDINARY_API_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAMEContentful Projects
When --cms contentful is selected, Supabase variables are replaced with the
appropriate Contentful and Auth.js settings. The generated CONTENTFUL.md
contains the complete setup guide.
# Shared Contentful settings
CONTENTFUL_SPACE_ID=your-space-id
CONTENTFUL_ENVIRONMENT=master
CONTENTFUL_MANAGEMENT_TOKEN=your-content-management-token
# Web: delivery, preview and webhook support
CONTENTFUL_DELIVERY_TOKEN=your-delivery-token
CONTENTFUL_PREVIEW_TOKEN=your-preview-token
CONTENTFUL_PREVIEW_SECRET=your-random-preview-secret
CONTENTFUL_WEBHOOK_SECRET=your-random-webhook-secret
# Admin: Auth.js credentials
AUTH_SECRET=your-random-auth-secret
[email protected]
ADMIN_PASSWORD_HASH=your-bcrypt-password-hashBootstrap the Contentful model with npm run contentful:setup. In the web
template, generate entry types with npm run contentful:types; in the admin
template, create a password hash with npm run auth:hash -- "your-password".
⚠️ Security: Variables prefixed with
NEXT_PUBLIC_are bundled into the client. Never prefixSERVICE_ROLE_KEYorAPI_SECRETwithNEXT_PUBLIC_.
🛠 Development
Prerequisites
| Tool | Minimum Version | | ------- | --------------- | | Node.js | 20.x | | npm | 9.x |
Available Scripts
Both templates share the same script interface:
npm run dev # Start dev server (Web uses Turbopack: next dev --turbopack)
npm run build # Compile for production
npm run start # Serve the production build
npm run lint # Run ESLint across the projectThird-party Account Setup
| Service | Free Tier | Setup Steps |
| ------------------------------------------------ | --------- | ----------------------------------------------------------------------- |
| Supabase | ✅ Yes | Create project → copy URL and anon key from Project Settings → API |
| Contentful | ✅ Yes | Create a space → add API and management tokens → run the setup script |
| Cloudinary | ✅ Yes | Create account → copy cloud name and API credentials from Dashboard |
| Resend | ✅ Yes | Create account → add domain (or use sandbox) → create API key |
| Google Analytics | ✅ Yes | Create property → copy Measurement ID (G-XXXXXXXXXX) |
🚢 Deployment
Vercel (Recommended)
The Web template is optimised for Vercel — App Router, Edge Middleware, Supabase SSR, and Contentful preview/revalidation routes work with standard environment-variable configuration.
- Push your project to GitHub, GitLab, or Bitbucket.
- Go to vercel.com/new and import the repository.
- Add all environment variables from your
.envfile via the Environment Variables panel. - Click Deploy.
Full Stack: Deploy
web/andadmin/as separate Vercel projects pointing to different subdirectories. In each project's settings, set the Root Directory toweboradminrespectively.
Netlify
# Build command
npm run build
# Publish directory
.nextAdd a netlify.toml at the project root:
[build]
command = "npm run build"
publish = ".next"
[[plugins]]
package = "@netlify/plugin-nextjs"Railway / Render / Other Node hosts
These platforms detect Next.js automatically. Ensure your environment variables are configured in the platform's dashboard, then connect your repository and deploy.
Docker (Self-hosted)
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]Enable
output: 'standalone'innext.config.tswhen using Docker.
❓ FAQ
Q: Can I use JavaScript instead of TypeScript?
A: Not yet — TypeScript only for now. A --javascript flag is planned for a future release. See ROADMAP.md.
Q: Can I use a different CSS framework?
A: The templates are designed around Tailwind CSS 4. Swapping it out is possible but requires manual work. Additional styling options are on the roadmap.
Q: Can I switch between Supabase and Contentful later?
A: The generated UI and service contracts intentionally share the same resource
shape, but the CLI applies the selected data-source files during scaffolding.
Create a fresh project with the other --cms value and migrate custom code when
you need to switch an existing application.
Q: The CLI overwrote my directory, can I undo it?
A: The CLI asks for confirmation before overwriting. If you confirmed by mistake, restore from git or a backup — the CLI does not keep a copy.
Q: How do I update to a newer template version?
A: Re-run the scaffold into a new directory and manually migrate your custom code. There is no in-place upgrade mechanism currently.
Q: Why does npm run dev use Turbopack in Web but not in Admin?
A: The Web template targets higher-complexity landing pages where faster rebuilds matter most. The Admin template uses the standard Next.js dev server for broader compatibility. You can enable Turbopack in Admin by changing the dev script to next dev --turbopack.
Q: Can I deploy the Full Stack template as a monorepo on Vercel?
A: Yes — create two separate Vercel projects pointing to the same repository, and set their Root Directory to web and admin respectively.
🤝 Contributing
Contributions, bug reports, and feature requests are welcome! Please see CONTRIBUTING.md for detailed guidelines.
Open an issue to discuss what you'd like to change.
Fork the repository and create a feature branch:
git clone https://github.com/mburakaltiparmak/create-nextjs-stack.git cd create-nextjs-stack npm installMake your changes, run the tests:
npm testSubmit a pull request with a clear description of the change.
Please follow Conventional Commits for commit messages (feat:, fix:, docs:, chore:).
📋 Changelog
See CHANGELOG.md for a full history of changes.
