create-next-style-guide 0.0.0-stage → 0.1.2

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 (61) hide show
  1. package/addons/ci/.cursor/rules/ci.mdc +11 -0
  2. package/addons/ci/docs/style-guide/ops/ci.md +7 -0
  3. package/addons/docker/.cursor/rules/docker.mdc +12 -0
  4. package/addons/docker/.dockerignore +12 -0
  5. package/addons/docker/docker/production.Dockerfile +53 -0
  6. package/addons/docker/docs/style-guide/ops/docker.md +14 -0
  7. package/addons/docs/data/tanstack-query.md +7 -0
  8. package/addons/docs/examples/api-app-crud.md +94 -0
  9. package/addons/docs/ui/icons.md +5 -0
  10. package/addons/endpoints/.cursor/rules/endpoints.mdc +17 -0
  11. package/addons/endpoints/docs/style-guide/http/endpoints.md +21 -0
  12. package/addons/endpoints/scripts/endpoints.codegen.json +7 -0
  13. package/addons/endpoints/scripts/generate-endpoints.ts +1384 -0
  14. package/addons/endpoints/src/endpoints/Types.ts +105 -0
  15. package/addons/endpoints/src/endpoints/index.ts +2 -0
  16. package/addons/endpoints/src/utils/api-error.ts +181 -0
  17. package/addons/endpoints/src/utils/api-result.ts +13 -0
  18. package/addons/endpoints/src/utils/axios-instance.ts +23 -0
  19. package/addons/endpoints/src/utils/form-data.ts +37 -0
  20. package/addons/endpoints/src/utils/search-params.ts +21 -0
  21. package/addons/eslint/.cursor/rules/eslint.mdc +12 -0
  22. package/addons/eslint/docs/style-guide/tooling/eslint.md +13 -0
  23. package/addons/eslint/eslint.config.mjs +85 -0
  24. package/addons/husky/.husky/pre-commit +2 -0
  25. package/addons/husky/docs/style-guide/tooling/husky.md +10 -0
  26. package/addons/prettier/.cursor/rules/prettier.mdc +11 -0
  27. package/addons/prettier/.prettierrc +14 -0
  28. package/addons/prettier/docs/style-guide/tooling/prettier.md +9 -0
  29. package/dist/index.js +3848 -0
  30. package/dist/index.js.map +1 -0
  31. package/package.json +38 -4
  32. package/template/.cursor/rules/components.mdc +27 -0
  33. package/template/.cursor/rules/core.mdc +16 -0
  34. package/template/.cursor/rules/forms.mdc +16 -0
  35. package/template/.env.example +6 -0
  36. package/template/AGENTS.md +38 -0
  37. package/template/README.md +28 -0
  38. package/template/docs/style-guide/README.md +11 -0
  39. package/template/docs/style-guide/http/client.md +9 -0
  40. package/template/docs/style-guide/overview/architecture.md +21 -0
  41. package/template/docs/style-guide/overview/project-structure.md +36 -0
  42. package/template/eslint.config.mjs +13 -0
  43. package/template/gitignore +39 -0
  44. package/template/next-env.d.ts +4 -0
  45. package/template/next.config.ts +7 -0
  46. package/template/package.json +27 -0
  47. package/template/src/app/_components/welcome-card/index.tsx +24 -0
  48. package/template/src/app/globals.css +84 -0
  49. package/template/src/app/layout.tsx +22 -0
  50. package/template/src/app/page.tsx +25 -0
  51. package/template/src/components/.gitkeep +0 -0
  52. package/template/src/constants/.gitkeep +0 -0
  53. package/template/src/hooks/.gitkeep +0 -0
  54. package/template/src/lib/env.ts +17 -0
  55. package/template/src/lib/http.ts +28 -0
  56. package/template/src/lib/utils.ts +6 -0
  57. package/template/src/providers/.gitkeep +0 -0
  58. package/template/src/types/.gitkeep +0 -0
  59. package/template/src/utils/.gitkeep +0 -0
  60. package/template/tsconfig.json +23 -0
  61. package/README.md +0 -3
@@ -0,0 +1,38 @@
1
+ # Agents (__PROJECT_NAME__)
2
+
3
+ Generated from [next-style-guide](https://github.com/alidanial7/next-style-guide).
4
+
5
+ ## Maintenance
6
+
7
+ Stack-wide → here. Feature detail → `.cursor/rules/*.mdc` (glob-scoped — only load when editing matching files). Don't re-read this file mid-task.
8
+
9
+ ## Stack
10
+
11
+ App Router · TS strict · Zod/Yup env (`src/lib/env.ts`) · __PACKAGE_MANAGER__.
12
+ Optional features (Query, store, endpoints, i18n, SEO, tests, Docker, CI, …) exist only when enabled at scaffold.
13
+
14
+ ## Do
15
+
16
+ - Thin `page.tsx` / `layout.tsx` — UI in folder-per-component `_components/`.
17
+ - Route-only → `src/app/<route>/_components/<name>/index.tsx`.
18
+ - Layout / home → `src/app/_components/<name>/`.
19
+ - Shared (≥2 routes) → `src/components/` (`ui/` flat for shadcn).
20
+ - Infra → `src/lib/`; API helpers → `src/utils/`; client state → `src/stores/` (when present).
21
+ - Named exports `function Foo()`; default only for Next route files.
22
+ - Prefer Server Components; `"use client"` only when needed.
23
+ - Single `<main>` in root layout — never nest `<main>` in pages/components.
24
+
25
+ ## Don't
26
+
27
+ - Park single-route UI in `src/components/`.
28
+ - Flat files in `_components/` (use `<name>/index.tsx`).
29
+ - Invent a second folder convention without updating this file + `docs/style-guide/`.
30
+ - Auto `git commit` / `git push` — leave that to the developer.
31
+
32
+ ## Read when needed
33
+
34
+ | Task | Open |
35
+ |------|------|
36
+ | Conventions | `docs/style-guide/README.md` |
37
+ | Architecture | `docs/style-guide/overview/architecture.md` |
38
+ | Cursor rules | `.cursor/rules/` (glob-scoped) |
@@ -0,0 +1,28 @@
1
+ # __PROJECT_NAME__
2
+
3
+ Next.js App Router app generated with [next-style-guide](https://github.com/alidanial7/next-style-guide).
4
+
5
+ ## Docs
6
+
7
+ | Audience | Start |
8
+ |----------|--------|
9
+ | Coding agents | [`AGENTS.md`](AGENTS.md) → [`.cursor/rules/`](.cursor/rules/) |
10
+ | Humans | [`docs/style-guide/`](docs/style-guide/) |
11
+
12
+ ## Stack
13
+
14
+ - Next.js 16 · React 19 · TypeScript
15
+ - Env validation via Zod or Yup
16
+ - App Router under `src/app/`
17
+ - Route-colocated UI under `_components/` (folder-per-component)
18
+ - Package manager: __PACKAGE_MANAGER__
19
+
20
+ ## Setup
21
+
22
+ ```bash
23
+ cp .env.example .env
24
+ __PACKAGE_MANAGER__ install
25
+ __PACKAGE_MANAGER__ dev
26
+ ```
27
+
28
+ App: [http://localhost:3000](http://localhost:3000)
@@ -0,0 +1,11 @@
1
+ # Style guide — __PROJECT_NAME__
2
+
3
+ Living conventions for this app. Open one page at a time.
4
+
5
+ | Page | Topic |
6
+ |------|--------|
7
+ | [Architecture](overview/architecture.md) | Layers: app / components / lib / utils |
8
+ | [Project structure](overview/project-structure.md) | Folder map |
9
+ | [HTTP client](http/client.md) | `apiFetch` helper |
10
+
11
+ Coding agents: start at [`AGENTS.md`](../../AGENTS.md) → [`.cursor/rules/`](../../.cursor/rules/).
@@ -0,0 +1,9 @@
1
+ # HTTP client
2
+
3
+ Base helper: `src/lib/http.ts` → `apiFetch`.
4
+
5
+ - Builds URLs from `NEXT_PUBLIC_API_URL`
6
+ - Expects JSON
7
+ - Throws on non-OK responses
8
+
9
+ When **endpoints** / axios helpers are enabled, prefer generated clients and `unwrapApiResult` for `{ result, status, success, messages }` responses so route UI never parses envelopes by hand.
@@ -0,0 +1,21 @@
1
+ # Architecture
2
+
3
+ ```text
4
+ src/app/ → routes + layouts (thin)
5
+ src/app/_components/ → layout / homepage UI only
6
+ src/app/<route>/_components/ → route-only UI
7
+ src/components/ → shared UI (≥2 routes) + ui/ primitives
8
+ src/lib/ → env, http, shared helpers
9
+ src/utils/ → API client helpers (when enabled)
10
+ src/providers/ → client providers (Query, theme, Redux, …)
11
+ src/stores/ → client global state (Zustand / Redux, when enabled)
12
+ src/hooks/ · types/ · constants/
13
+ ```
14
+
15
+ ## Rules of thumb
16
+
17
+ 1. **Routes orchestrate** — load data, compose colocated `_components`.
18
+ 2. **Colocate by usage** — one route → that route's `_components/`; two+ routes → `src/components/`.
19
+ 3. **Server first** — prefer RSC; `"use client"` only at the leaves that need interactivity.
20
+ 4. **One HTTP doorway** — `src/lib/http.ts` and/or generated `src/endpoints/*` (when enabled). Avoid ad-hoc `fetch` in UI.
21
+ 5. **Split server cache vs UI state** — TanStack Query for server/async cache; Zustand/Redux for client UI/session state only.
@@ -0,0 +1,36 @@
1
+ # Project structure
2
+
3
+ Lean App Router layout. Installers only add folders they need (e.g. `stores/`, `endpoints/`).
4
+
5
+ ```text
6
+ __PROJECT_SLUG__/
7
+ ├── src/
8
+ │ ├── app/ # routes + layouts (thin)
9
+ │ │ ├── _components/ # layout / homepage UI
10
+ │ │ └── <route>/_components/ # route-only UI (folder-per-component)
11
+ │ ├── components/ # shared UI (≥2 routes); ui/ for primitives
12
+ │ ├── lib/ # env, http, cn, seo, …
13
+ │ ├── utils/ # API helpers (axios, errors, tokens, …)
14
+ │ ├── providers/ # client providers (Query, theme, Redux, …)
15
+ │ ├── stores/ # client store slices (Zustand / Redux) — when enabled
16
+ │ ├── hooks/ # shared hooks
17
+ │ ├── types/ # shared types
18
+ │ └── constants/ # shared constants
19
+ ├── docs/style-guide/ # conventions that match enabled options
20
+ ├── AGENTS.md
21
+ ├── .cursor/rules/ # glob-scoped agent rules
22
+ ├── .env.example
23
+ └── package.json
24
+ ```
25
+
26
+ ## Placement rules
27
+
28
+ | What | Where |
29
+ |------|--------|
30
+ | One route only | `src/app/<route>/_components/<name>/index.tsx` |
31
+ | Layout / home chrome | `src/app/_components/<name>/` |
32
+ | Shared across ≥2 routes | `src/components/` |
33
+ | Env / pure helpers | `src/lib/` |
34
+ | HTTP / API adapters | `src/utils/` (or generated `src/endpoints/`) |
35
+ | Client global state | `src/stores/` |
36
+ | Client providers | `src/providers/` |
@@ -0,0 +1,13 @@
1
+ import nextVitals from "eslint-config-next/core-web-vitals";
2
+ import nextTs from "eslint-config-next/typescript";
3
+
4
+ /** Minimal Next flat config. Replaced when the enhanced ESLint option is on. */
5
+ const eslintConfig = [
6
+ ...nextVitals,
7
+ ...nextTs,
8
+ {
9
+ ignores: [".next/**", "out/**", "build/**", "next-env.d.ts", "node_modules/**"],
10
+ },
11
+ ];
12
+
13
+ export default eslintConfig;
@@ -0,0 +1,39 @@
1
+ # dependencies
2
+ /node_modules
3
+ /.pnp
4
+ .pnp.*
5
+ .yarn/*
6
+ !.yarn/patches
7
+ !.yarn/plugins
8
+ !.yarn/releases
9
+ !.yarn/versions
10
+
11
+ # testing
12
+ /coverage
13
+
14
+ # next.js
15
+ /.next/
16
+ /out/
17
+
18
+ # production
19
+ /build
20
+
21
+ # misc
22
+ .DS_Store
23
+ *.pem
24
+ *.tsbuildinfo
25
+ next-env.d.ts
26
+
27
+ # debug
28
+ npm-debug.log*
29
+ yarn-debug.log*
30
+ yarn-error.log*
31
+ .pnpm-debug.log*
32
+
33
+ # env
34
+ .env
35
+ .env*.local
36
+ !.env.example
37
+
38
+ # vercel
39
+ .vercel
@@ -0,0 +1,4 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+
4
+ // NOTE: This file should not be edited — see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ reactStrictMode: true,
5
+ };
6
+
7
+ export default nextConfig;
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "__PROJECT_SLUG__",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "packageManager": "pnpm@9.15.0",
6
+ "scripts": {
7
+ "dev": "next dev --turbopack",
8
+ "build": "next build",
9
+ "start": "next start",
10
+ "lint": "eslint .",
11
+ "typecheck": "tsc --noEmit"
12
+ },
13
+ "dependencies": {
14
+ "next": "16.4.5",
15
+ "react": "19.2.8",
16
+ "react-dom": "19.2.8",
17
+ "zod": "^3.24.1"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^22.10.2",
21
+ "@types/react": "19.2.18",
22
+ "@types/react-dom": "19.2.4",
23
+ "eslint": "^9.17.0",
24
+ "eslint-config-next": "16.4.5",
25
+ "typescript": "^5.7.2"
26
+ }
27
+ }
@@ -0,0 +1,24 @@
1
+ /** Homepage sample — replace when you add real route UI. */
2
+ export function WelcomeCard() {
3
+ return (
4
+ <div className="card">
5
+ <h2>App layout</h2>
6
+ <ul>
7
+ <li>
8
+ Route-only UI →{" "}
9
+ <code>src/app/&lt;route&gt;/_components/&lt;name&gt;/index.tsx</code>
10
+ </li>
11
+ <li>
12
+ Layout / homepage UI → <code>src/app/_components/</code>
13
+ </li>
14
+ <li>
15
+ Shared across 2+ routes → <code>src/components/</code>
16
+ </li>
17
+ <li>
18
+ HTTP / env → <code>src/lib/</code> · API helpers →{" "}
19
+ <code>src/utils/</code>
20
+ </li>
21
+ </ul>
22
+ </div>
23
+ );
24
+ }
@@ -0,0 +1,84 @@
1
+ :root {
2
+ color-scheme: light;
3
+ --bg: #f6f4ef;
4
+ --fg: #14201b;
5
+ --muted: #5b6b63;
6
+ --accent: #0b5fff;
7
+ --card: #ffffff;
8
+ --border: #d9e0db;
9
+ --font: "Segoe UI", system-ui, sans-serif;
10
+ }
11
+
12
+ * {
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ html,
17
+ body {
18
+ margin: 0;
19
+ padding: 0;
20
+ min-height: 100%;
21
+ background: radial-gradient(circle at top left, #eef3ff, transparent 40%),
22
+ var(--bg);
23
+ color: var(--fg);
24
+ font-family: var(--font);
25
+ }
26
+
27
+ a {
28
+ color: var(--accent);
29
+ text-decoration: none;
30
+ }
31
+
32
+ a:hover {
33
+ text-decoration: underline;
34
+ }
35
+
36
+ main {
37
+ width: min(720px, calc(100% - 2rem));
38
+ margin: 0 auto;
39
+ padding: 4rem 0 3rem;
40
+ }
41
+
42
+ .hero {
43
+ display: grid;
44
+ gap: 1rem;
45
+ }
46
+
47
+ .hero h1 {
48
+ margin: 0;
49
+ font-size: clamp(2rem, 5vw, 3rem);
50
+ letter-spacing: -0.03em;
51
+ }
52
+
53
+ .hero p {
54
+ margin: 0;
55
+ color: var(--muted);
56
+ line-height: 1.6;
57
+ max-width: 40rem;
58
+ }
59
+
60
+ .card {
61
+ margin-top: 2rem;
62
+ padding: 1.25rem 1.5rem;
63
+ background: var(--card);
64
+ border: 1px solid var(--border);
65
+ border-radius: 12px;
66
+ }
67
+
68
+ .card h2 {
69
+ margin: 0 0 0.5rem;
70
+ font-size: 1rem;
71
+ }
72
+
73
+ .card ul {
74
+ margin: 0;
75
+ padding-left: 1.1rem;
76
+ color: var(--muted);
77
+ line-height: 1.7;
78
+ }
79
+
80
+ .meta {
81
+ margin-top: 2rem;
82
+ font-size: 0.875rem;
83
+ color: var(--muted);
84
+ }
@@ -0,0 +1,22 @@
1
+ import type { Metadata } from "next";
2
+
3
+ import "./globals.css";
4
+
5
+ export const metadata: Metadata = {
6
+ title: "__PROJECT_NAME__",
7
+ description: "Generated with next-style-guide",
8
+ };
9
+
10
+ export default function RootLayout({
11
+ children,
12
+ }: Readonly<{
13
+ children: React.ReactNode;
14
+ }>) {
15
+ return (
16
+ <html lang="en">
17
+ <body>
18
+ <main>{children}</main>
19
+ </body>
20
+ </html>
21
+ );
22
+ }
@@ -0,0 +1,25 @@
1
+ import { WelcomeCard } from "@/app/_components/welcome-card";
2
+
3
+ export default function HomePage() {
4
+ return (
5
+ <>
6
+ <section className="hero">
7
+ <h1>__PROJECT_NAME__</h1>
8
+ <p>
9
+ Next.js App Router scaffold from{" "}
10
+ <strong>next-style-guide</strong>. Route UI lives under{" "}
11
+ <code>src/app/_components/</code> (or a route&apos;s{" "}
12
+ <code>_components/</code>); shared primitives under{" "}
13
+ <code>src/components/</code>; HTTP helpers under <code>src/lib/</code>.
14
+ </p>
15
+ </section>
16
+
17
+ <WelcomeCard />
18
+
19
+ <p className="meta">
20
+ Read <code>AGENTS.md</code> and <code>docs/style-guide/</code> before
21
+ adding routes.
22
+ </p>
23
+ </>
24
+ );
25
+ }
File without changes
File without changes
File without changes
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+
3
+ /**
4
+ * Validated public env. Import from Client Components only for NEXT_PUBLIC_*.
5
+ * Server-only secrets stay out of this schema until needed.
6
+ */
7
+ const publicEnvSchema = z.object({
8
+ NEXT_PUBLIC_APP_URL: z.string().url().default("http://localhost:3000"),
9
+ NEXT_PUBLIC_API_URL: z.string().url().default("http://localhost:8000"),
10
+ });
11
+
12
+ export type PublicEnv = z.infer<typeof publicEnvSchema>;
13
+
14
+ export const env: PublicEnv = publicEnvSchema.parse({
15
+ NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
16
+ NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
17
+ });
@@ -0,0 +1,28 @@
1
+ import { env } from "@/lib/env";
2
+
3
+ /**
4
+ * Minimal JSON fetch helper.
5
+ * Prefer generated endpoints / axios helpers when that option is enabled.
6
+ */
7
+ export async function apiFetch<T>(
8
+ path: string,
9
+ init?: RequestInit,
10
+ ): Promise<T> {
11
+ const url = path.startsWith("http")
12
+ ? path
13
+ : `${env.NEXT_PUBLIC_API_URL.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
14
+
15
+ const response = await fetch(url, {
16
+ ...init,
17
+ headers: {
18
+ Accept: "application/json",
19
+ ...(init?.headers ?? {}),
20
+ },
21
+ });
22
+
23
+ if (!response.ok) {
24
+ throw new Error(`API ${response.status}: ${response.statusText}`);
25
+ }
26
+
27
+ return response.json() as Promise<T>;
28
+ }
@@ -0,0 +1,6 @@
1
+ /** Lightweight class join — swap for clsx + tailwind-merge when shadcn lands. */
2
+ export function cn(
3
+ ...parts: Array<string | false | null | undefined>
4
+ ): string {
5
+ return parts.filter(Boolean).join(" ");
6
+ }
File without changes
File without changes
File without changes
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [{ "name": "next" }],
17
+ "paths": {
18
+ "@/*": ["./src/*"]
19
+ }
20
+ },
21
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
22
+ "exclude": ["node_modules"]
23
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.