@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.
- package/README.md +548 -0
- package/dist/index.js +407 -0
- package/package.json +31 -0
- package/templates/animations/components/motion/fade-in.tsx +28 -0
- package/templates/appwrite/.env.example +3 -0
- package/templates/appwrite/lib/appwrite.ts +11 -0
- package/templates/auth/.env.example +6 -0
- package/templates/auth/app/(auth)/sign-in/[[...sign-in]]/page.tsx +9 -0
- package/templates/auth/app/(auth)/sign-up/[[...sign-up]]/page.tsx +9 -0
- package/templates/auth/middleware.ts +17 -0
- package/templates/base/.env.example +1 -0
- package/templates/base/.husky/pre-commit +19 -0
- package/templates/base/.husky/pre-push +11 -0
- package/templates/base/.prettierignore +8 -0
- package/templates/base/.prettierrc.json +9 -0
- package/templates/base/CONTRIBUTING.md +120 -0
- package/templates/base/app/globals.css +28 -0
- package/templates/base/app/page.tsx +7 -0
- package/templates/base/components/ui/button.tsx +40 -0
- package/templates/base/eslint.config.mjs +51 -0
- package/templates/base/lib/env.ts +7 -0
- package/templates/base/lib/utils.ts +6 -0
- package/templates/base/next.config.ts +5 -0
- package/templates/base/postcss.config.mjs +7 -0
- package/templates/base/tsconfig.json +23 -0
- package/templates/convex/.env.example +1 -0
- package/templates/convex/convex/schema.ts +10 -0
- package/templates/convex/convex/users.ts +19 -0
- package/templates/convex/providers/convex-provider.tsx +15 -0
- package/templates/data-fetching/lib/api.ts +18 -0
- package/templates/data-fetching/providers/query-provider.tsx +22 -0
- package/templates/forms/components/forms/example-form.tsx +58 -0
- package/templates/forms/lib/validations/example.ts +8 -0
- package/templates/prisma/.env.example +1 -0
- package/templates/prisma/lib/db.ts +11 -0
- package/templates/prisma/prisma/schema.prisma +16 -0
- 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`
|