@codabytez/create-next-template 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +548 -0
  2. package/dist/index.js +407 -0
  3. package/package.json +31 -0
  4. package/templates/animations/components/motion/fade-in.tsx +28 -0
  5. package/templates/appwrite/.env.example +3 -0
  6. package/templates/appwrite/lib/appwrite.ts +11 -0
  7. package/templates/auth/.env.example +6 -0
  8. package/templates/auth/app/(auth)/sign-in/[[...sign-in]]/page.tsx +9 -0
  9. package/templates/auth/app/(auth)/sign-up/[[...sign-up]]/page.tsx +9 -0
  10. package/templates/auth/middleware.ts +17 -0
  11. package/templates/base/.env.example +1 -0
  12. package/templates/base/.husky/pre-commit +19 -0
  13. package/templates/base/.husky/pre-push +11 -0
  14. package/templates/base/.prettierignore +8 -0
  15. package/templates/base/.prettierrc.json +9 -0
  16. package/templates/base/CONTRIBUTING.md +120 -0
  17. package/templates/base/app/globals.css +28 -0
  18. package/templates/base/app/page.tsx +7 -0
  19. package/templates/base/components/ui/button.tsx +40 -0
  20. package/templates/base/eslint.config.mjs +51 -0
  21. package/templates/base/lib/env.ts +7 -0
  22. package/templates/base/lib/utils.ts +6 -0
  23. package/templates/base/next.config.ts +5 -0
  24. package/templates/base/postcss.config.mjs +7 -0
  25. package/templates/base/tsconfig.json +23 -0
  26. package/templates/convex/.env.example +1 -0
  27. package/templates/convex/convex/schema.ts +10 -0
  28. package/templates/convex/convex/users.ts +19 -0
  29. package/templates/convex/providers/convex-provider.tsx +15 -0
  30. package/templates/data-fetching/lib/api.ts +18 -0
  31. package/templates/data-fetching/providers/query-provider.tsx +22 -0
  32. package/templates/forms/components/forms/example-form.tsx +58 -0
  33. package/templates/forms/lib/validations/example.ts +8 -0
  34. package/templates/prisma/.env.example +1 -0
  35. package/templates/prisma/lib/db.ts +11 -0
  36. package/templates/prisma/prisma/schema.prisma +16 -0
  37. package/templates/ui/components.json +20 -0
package/README.md ADDED
@@ -0,0 +1,548 @@
1
+ # create-next-template
2
+
3
+ An interactive CLI that scaffolds a production-ready Next.js project with your preferred stack — only what you need, nothing you don't.
4
+
5
+ ---
6
+
7
+ ## Quick start
8
+
9
+ ```bash
10
+ npx create-next-template
11
+ ```
12
+
13
+ Or with a specific package manager:
14
+
15
+ ```bash
16
+ pnpm dlx create-next-template
17
+ bunx create-next-template
18
+ ```
19
+
20
+ ---
21
+
22
+ ## How it works
23
+
24
+ When you run the CLI, it will ask you three questions:
25
+
26
+ 1. **Project name** — used as the folder name and `package.json` name
27
+ 2. **Package manager** — `npm`, `pnpm`, `yarn`, or `bun`
28
+ 3. **Features** — pick any combination from the list below
29
+
30
+ The CLI then:
31
+
32
+ - Copies the base template into a new folder
33
+ - Merges in the files for each selected feature
34
+ - Generates a `layout.tsx` with the correct providers already wired up
35
+ - Merges all `.env.example` entries into a single file
36
+ - Writes a `package.json` with only the dependencies you need
37
+ - Installs dependencies
38
+ - Runs any required post-install steps (e.g. `prisma generate`)
39
+ - Initializes a git repository with an initial commit
40
+
41
+ ---
42
+
43
+ ## What's always included
44
+
45
+ These come with every project — they're small, universal, and always useful:
46
+
47
+ | Package | Purpose |
48
+ | -------------------------- | ---------------------------------------------------------- |
49
+ | `next` | React framework (v15) |
50
+ | `react` + `react-dom` | React runtime |
51
+ | `tailwindcss` v4 | Utility-first CSS |
52
+ | `@tailwindcss/postcss` | Tailwind v4 PostCSS plugin |
53
+ | `clsx` | Conditional class names |
54
+ | `tailwind-merge` | Merges Tailwind classes without conflicts |
55
+ | `class-variance-authority` | Type-safe component variants |
56
+ | `zod` | Schema validation (used for forms, env, and API responses) |
57
+ | `date-fns` | Lightweight date formatting and manipulation |
58
+ | `cookies-next` | Read/write cookies in Next.js (client + server) |
59
+ | `lucide-react` | Clean, consistent icon set |
60
+ | `prettier` | Code formatter |
61
+ | `eslint-plugin-prettier` | Runs Prettier as an ESLint rule |
62
+ | `husky` | Git hooks (pre-commit, pre-push) |
63
+ | `lint-staged` | Runs linters only on staged files |
64
+
65
+ A `cn()` utility ([lib/utils.ts](lib/utils.ts)) combining `clsx` + `tailwind-merge` is also included, as well as a base `Button` component built with CVA.
66
+
67
+ ---
68
+
69
+ ## Code quality tooling
70
+
71
+ Every project comes pre-configured with a full code quality pipeline — no setup needed.
72
+
73
+ ### Prettier
74
+
75
+ Config in `.prettierrc.json`:
76
+
77
+ - Double quotes, semicolons, 2-space indent, 80 char line width, trailing commas (ES5)
78
+
79
+ Run manually:
80
+
81
+ ```bash
82
+ pnpm format # format everything
83
+ pnpm check-format # check without writing
84
+ ```
85
+
86
+ ### ESLint
87
+
88
+ Config in `eslint.config.mjs` (flat config, ESLint v9). Includes:
89
+
90
+ - `eslint-config-next` (core web vitals + TypeScript rules)
91
+ - `eslint-plugin-prettier` (formatting errors shown as lint errors)
92
+ - Rules enforced: no `console.log`, no `var`, no unused vars, self-closing JSX, exhaustive deps, no duplicate imports
93
+
94
+ ```bash
95
+ pnpm lint
96
+ ```
97
+
98
+ ### TypeScript
99
+
100
+ ```bash
101
+ pnpm check-types # runs tsc --noEmit, no output = no errors
102
+ ```
103
+
104
+ ### Git hooks (Husky)
105
+
106
+ Hooks are set up automatically after `pnpm install` via the `prepare` script.
107
+
108
+ **Pre-commit** — runs on every `git commit`:
109
+
110
+ 1. Prettier format check (auto-fixes and re-stages if needed)
111
+ 2. lint-staged — ESLint + Prettier on staged files only
112
+ 3. TypeScript type check
113
+
114
+ **Pre-push** — runs on every `git push`:
115
+
116
+ 1. Full `next build` — blocks the push if the build fails
117
+
118
+ > Do not bypass hooks with `--no-verify`. Fix the issue instead.
119
+
120
+ ### Tailwind v4 custom theme
121
+
122
+ `app/globals.css` includes a commented-out `@theme` block — uncomment and fill in your design tokens:
123
+
124
+ ```css
125
+ @theme {
126
+ --color-primary: #6366f1;
127
+ --color-secondary: #f59e0b;
128
+ --font-sans: "Inter", sans-serif;
129
+ }
130
+ ```
131
+
132
+ These become available as Tailwind utilities automatically (e.g. `bg-primary`, `text-secondary`).
133
+
134
+ ---
135
+
136
+ ## Selectable features
137
+
138
+ ### Animations — `framer-motion`
139
+
140
+ Adds [Framer Motion](https://www.framer.com/motion/) for declarative animations.
141
+
142
+ **Files added:**
143
+
144
+ ```ts
145
+ components/motion/fade-in.tsx ← reusable fade-in wrapper
146
+ ```
147
+
148
+ **Usage:**
149
+
150
+ ```tsx
151
+ import { FadeIn } from "@/components/motion/fade-in";
152
+
153
+ <FadeIn delay={0.1}>
154
+ <p>Animated content</p>
155
+ </FadeIn>;
156
+ ```
157
+
158
+ ---
159
+
160
+ ### Data Fetching — TanStack Query + Axios
161
+
162
+ Adds [@tanstack/react-query](https://tanstack.com/query) and [Axios](https://axios-http.com/) with a pre-configured client and provider.
163
+
164
+ **Files added:**
165
+
166
+ ```ts
167
+ lib/api.ts ← Axios instance with base URL + 401 interceptor
168
+ providers/query-provider.tsx ← QueryClientProvider (already wired into layout)
169
+ ```
170
+
171
+ **The Axios instance** reads `NEXT_PUBLIC_API_URL` from your env. If not set, it defaults to `/api`. Add to your `.env`:
172
+
173
+ ```env
174
+ NEXT_PUBLIC_API_URL=https://api.example.com
175
+ ```
176
+
177
+ **Usage:**
178
+
179
+ ```tsx
180
+ import { useQuery } from "@tanstack/react-query";
181
+ import { api } from "@/lib/api";
182
+
183
+ const { data } = useQuery({
184
+ queryKey: ["users"],
185
+ queryFn: () => api.get("/users").then((res) => res.data),
186
+ });
187
+ ```
188
+
189
+ ---
190
+
191
+ ### Forms — React Hook Form + Zod resolver
192
+
193
+ Adds [React Hook Form](https://react-hook-form.com/) with the [Zod resolver](https://github.com/react-hook-form/resolvers) for schema-driven form validation.
194
+
195
+ **Files added:**
196
+
197
+ ```ts
198
+ lib/validations/example.ts ← example Zod schema
199
+ components/forms/example-form.tsx ← example form component
200
+ ```
201
+
202
+ **How to add a new form:**
203
+
204
+ 1. Define your schema in `lib/validations/`:
205
+
206
+ ```ts
207
+ import { z } from "zod";
208
+
209
+ export const loginSchema = z.object({
210
+ email: z.string().email(),
211
+ password: z.string().min(8),
212
+ });
213
+
214
+ export type LoginFormValues = z.infer<typeof loginSchema>;
215
+ ```
216
+
217
+ 1. Use it in your component:
218
+
219
+ ```tsx
220
+ import { useForm } from "react-hook-form";
221
+ import { zodResolver } from "@hookform/resolvers/zod";
222
+ import { loginSchema, type LoginFormValues } from "@/lib/validations/login";
223
+
224
+ const {
225
+ register,
226
+ handleSubmit,
227
+ formState: { errors },
228
+ } = useForm<LoginFormValues>({
229
+ resolver: zodResolver(loginSchema),
230
+ });
231
+ ```
232
+
233
+ ---
234
+
235
+ ### Extra Icons — `iconsax-reactjs`
236
+
237
+ Adds [Iconsax](https://iconsax-react.pages.dev/) — a large icon library with multiple visual styles (Linear, Outline, Broken, Bulk, Bold, TwoTone).
238
+
239
+ **Usage:**
240
+
241
+ ```tsx
242
+ import { Home, Setting2, User } from "iconsax-reactjs";
243
+
244
+ <Home size={24} variant="Linear" />
245
+ <Setting2 size={20} variant="Bulk" color="#FF6B6B" />
246
+ ```
247
+
248
+ Available variants: `Linear`, `Outline`, `Broken`, `Bulk`, `Bold`, `TwoTone`
249
+
250
+ > **Tip:** Use Lucide for simple UI icons and Iconsax where you need more expressive or stylized icons.
251
+
252
+ ---
253
+
254
+ ### Auth — Clerk
255
+
256
+ Adds [Clerk](https://clerk.com/) for authentication with pre-built sign-in and sign-up pages.
257
+
258
+ **Files added:**
259
+
260
+ ```ts
261
+ middleware.ts ← protects all non-public routes
262
+ app/(auth)/sign-in/[[...sign-in]]/page.tsx
263
+ app/(auth)/sign-up/[[...sign-up]]/page.tsx
264
+ ```
265
+
266
+ The `layout.tsx` is automatically wrapped with `<ClerkProvider>`.
267
+
268
+ **Setup steps:**
269
+
270
+ 1. Create a project at [clerk.com](https://clerk.com)
271
+ 2. Copy your keys into `.env`:
272
+
273
+ ```env
274
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
275
+ CLERK_SECRET_KEY=sk_test_...
276
+ NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
277
+ NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
278
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
279
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
280
+ ```
281
+
282
+ **Accessing the current user:**
283
+
284
+ ```tsx
285
+ import { useUser } from "@clerk/nextjs";
286
+
287
+ const { user, isLoaded } = useUser();
288
+ ```
289
+
290
+ **In Server Components or Route Handlers:**
291
+
292
+ ```ts
293
+ import { auth, currentUser } from "@clerk/nextjs/server";
294
+
295
+ const { userId } = await auth();
296
+ const user = await currentUser();
297
+ ```
298
+
299
+ **To make a route public**, add it to the `isPublicRoute` matcher in `middleware.ts`:
300
+
301
+ ```ts
302
+ const isPublicRoute = createRouteMatcher([
303
+ "/",
304
+ "/sign-in(.*)",
305
+ "/sign-up(.*)",
306
+ "/about",
307
+ ]);
308
+ ```
309
+
310
+ ---
311
+
312
+ ### Database — Prisma
313
+
314
+ Adds [Prisma ORM](https://www.prisma.io/) configured for PostgreSQL.
315
+
316
+ **Files added:**
317
+
318
+ ```ts
319
+ prisma/schema.prisma ← database schema with a starter User model
320
+ lib/db.ts ← singleton Prisma client (safe for dev hot-reload)
321
+ ```
322
+
323
+ **Setup steps:**
324
+
325
+ 1. Add your database URL to `.env`:
326
+
327
+ ```env
328
+ DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
329
+ ```
330
+
331
+ 1. Edit `prisma/schema.prisma` to define your models, then run:
332
+
333
+ ```bash
334
+ npx prisma migrate dev --name init
335
+ ```
336
+
337
+ 1. Generate the Prisma client anytime you change the schema:
338
+
339
+ ```bash
340
+ npx prisma generate
341
+ ```
342
+
343
+ **Usage:**
344
+
345
+ ```ts
346
+ import { db } from "@/lib/db";
347
+
348
+ const users = await db.user.findMany();
349
+ const user = await db.user.create({ data: { email: "...", name: "..." } });
350
+ ```
351
+
352
+ > **Note:** `lib/db.ts` uses a global singleton to prevent creating multiple Prisma instances during Next.js hot-reload in development.
353
+
354
+ ---
355
+
356
+ ### Database — Convex
357
+
358
+ Adds [Convex](https://www.convex.dev/) — a real-time backend with live queries, mutations, and a built-in database.
359
+
360
+ **Files added:**
361
+
362
+ ```ts
363
+ convex/schema.ts ← database schema definition
364
+ convex/users.ts ← example queries and mutations
365
+ providers/convex-provider.tsx ← ConvexProvider (already wired into layout)
366
+ ```
367
+
368
+ **Setup steps:**
369
+
370
+ 1. Run the Convex dev server (this will prompt you to log in and create a project):
371
+
372
+ ```bash
373
+ npx convex dev
374
+ ```
375
+
376
+ 1. Convex will automatically populate `NEXT_PUBLIC_CONVEX_URL` in your `.env.local`.
377
+
378
+ **Usage:**
379
+
380
+ ```tsx
381
+ import { useQuery, useMutation } from "convex/react";
382
+ import { api } from "@/convex/_generated/api";
383
+
384
+ // Read data (live, auto-updates)
385
+ const users = useQuery(api.users.getUsers);
386
+
387
+ // Write data
388
+ const createUser = useMutation(api.users.createUser);
389
+ await createUser({ name: "Alice", email: "alice@example.com" });
390
+ ```
391
+
392
+ > **Tip:** Convex queries are reactive — components automatically re-render when the data changes, no polling or invalidation needed.
393
+
394
+ ---
395
+
396
+ ### Database — Appwrite
397
+
398
+ Adds [Appwrite](https://appwrite.io/) — an open-source BaaS with databases, auth, storage, and more.
399
+
400
+ **Files added:**
401
+
402
+ ```ts
403
+ lib/appwrite.ts ← pre-configured Account, Databases, and Storage clients
404
+ ```
405
+
406
+ **Setup steps:**
407
+
408
+ 1. Create a project at [cloud.appwrite.io](https://cloud.appwrite.io) (or self-host)
409
+ 2. Fill in your `.env`:
410
+
411
+ ```env
412
+ NEXT_PUBLIC_APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
413
+ NEXT_PUBLIC_APPWRITE_PROJECT_ID=your-project-id
414
+ NEXT_PUBLIC_APPWRITE_DATABASE_ID=your-database-id
415
+ ```
416
+
417
+ **Usage:**
418
+
419
+ ```ts
420
+ import { databases, account, storage } from "@/lib/appwrite";
421
+ import { ID } from "appwrite";
422
+
423
+ // Create a document
424
+ await databases.createDocument(
425
+ process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID!,
426
+ "your-collection-id",
427
+ ID.unique(),
428
+ { name: "Alice", email: "alice@example.com" },
429
+ );
430
+
431
+ // Get current user
432
+ const user = await account.get();
433
+ ```
434
+
435
+ ---
436
+
437
+ ### UI Components — shadcn/ui
438
+
439
+ Adds a `components.json` config file so you can immediately start adding [shadcn/ui](https://ui.shadcn.com/) components.
440
+
441
+ **Post-install step (required):**
442
+
443
+ ```bash
444
+ npx shadcn@latest init
445
+ ```
446
+
447
+ This will read the existing `components.json` and finish setting up the component system.
448
+
449
+ **Adding components:**
450
+
451
+ ```bash
452
+ npx shadcn@latest add button
453
+ npx shadcn@latest add dialog
454
+ npx shadcn@latest add input card badge
455
+ ```
456
+
457
+ Components are added directly to `components/ui/` — they're yours to modify.
458
+
459
+ ---
460
+
461
+ ## Project structure
462
+
463
+ After scaffolding, your project will look like this (depending on selected features):
464
+
465
+ ```ts
466
+ my-app/
467
+ ├── app/
468
+ │ ├── (auth)/ ← Clerk sign-in / sign-up [auth]
469
+ │ │ ├── sign-in/[[...sign-in]]/page.tsx
470
+ │ │ └── sign-up/[[...sign-up]]/page.tsx
471
+ │ ├── globals.css
472
+ │ ├── layout.tsx ← auto-generated with selected providers
473
+ │ └── page.tsx
474
+ ├── components/
475
+ │ ├── forms/
476
+ │ │ └── example-form.tsx ← [forms]
477
+ │ ├── motion/
478
+ │ │ └── fade-in.tsx ← [animations]
479
+ │ └── ui/
480
+ │ └── button.tsx ← always included
481
+ ├── convex/ ← [convex]
482
+ │ ├── schema.ts
483
+ │ └── users.ts
484
+ ├── lib/
485
+ │ ├── api.ts ← [data-fetching]
486
+ │ ├── appwrite.ts ← [appwrite]
487
+ │ ├── db.ts ← [prisma]
488
+ │ ├── env.ts ← always included
489
+ │ ├── utils.ts ← always included (cn function)
490
+ │ └── validations/
491
+ │ └── example.ts ← [forms]
492
+ ├── prisma/
493
+ │ └── schema.prisma ← [prisma]
494
+ ├── providers/
495
+ │ ├── convex-provider.tsx ← [convex]
496
+ │ └── query-provider.tsx ← [data-fetching]
497
+ ├── middleware.ts ← [auth]
498
+ ├── next.config.ts
499
+ ├── postcss.config.mjs
500
+ ├── tsconfig.json
501
+ ├── .env.example
502
+ └── .gitignore
503
+ ```
504
+
505
+ ---
506
+
507
+ ## Environment variables
508
+
509
+ All `.env.example` entries from your selected features are merged into a single `.env.example` file. Copy it to get started:
510
+
511
+ ```bash
512
+ cp .env.example .env
513
+ ```
514
+
515
+ Then fill in the values for each service you selected.
516
+
517
+ ---
518
+
519
+ ## Combining features
520
+
521
+ Features are designed to work together. Common combinations:
522
+
523
+ | Stack | Features to select |
524
+ | ------------------- | ------------------------------------------------ |
525
+ | SaaS starter | Auth + Prisma + Forms + Data Fetching + UI |
526
+ | Real-time app | Convex + Auth + Animations + UI |
527
+ | Mobile-like web app | Animations + Forms + Data Fetching + Extra Icons |
528
+ | Content platform | Appwrite + Forms + UI + Data Fetching |
529
+ | Minimal | Just the base (no features selected) |
530
+
531
+ ---
532
+
533
+ ## Contributing
534
+
535
+ 1. Clone the repo
536
+ 2. Install dependencies: `pnpm install`
537
+ 3. Make your changes in `src/` or `templates/`
538
+ 4. Build: `pnpm run build`
539
+ 5. Test locally: `node dist/index.js`
540
+
541
+ To add a new feature:
542
+
543
+ 1. Add its template files under `templates/<feature-name>/`
544
+ 2. Add its dependencies to `FEATURE_DEPS` in `src/helpers/packages.ts`
545
+ 3. Add it to the prompts in `src/index.ts`
546
+ 4. Map the template name in `FEATURE_TEMPLATE_MAP` in `src/installer.ts`
547
+ 5. If it needs a provider in `layout.tsx`, update `src/generators/layout.ts`
548
+ 6. If it needs env vars, add a `.env.example` under `templates/<feature-name>/` and register it in `src/helpers/env.ts`