@withmata/blueprints 0.3.1 → 0.3.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 (24) hide show
  1. package/.claude/skills/blueprint-catalog/SKILL.md +13 -2
  2. package/.claude/skills/scaffold-env/SKILL.md +222 -0
  3. package/.claude/skills/scaffold-tailwind/SKILL.md +177 -0
  4. package/.claude/skills/scaffold-ui/SKILL.md +206 -0
  5. package/blueprints/features/env-t3/BLUEPRINT.md +332 -0
  6. package/blueprints/features/env-t3/files/nextjs/.env.example +17 -0
  7. package/blueprints/features/env-t3/files/nextjs/.env.local +0 -0
  8. package/blueprints/features/env-t3/files/nextjs/env/client.ts +13 -0
  9. package/blueprints/features/env-t3/files/nextjs/env/server.ts +12 -0
  10. package/blueprints/features/env-t3/files/server/.env.example +14 -0
  11. package/blueprints/features/env-t3/files/server/.env.local +0 -0
  12. package/blueprints/features/env-t3/files/server/env.ts +17 -0
  13. package/blueprints/features/tailwind-v4/BLUEPRINT.md +262 -12
  14. package/blueprints/features/tailwind-v4/files/tailwind-config/package.json +20 -0
  15. package/blueprints/features/tailwind-v4/files/tailwind-config/shared-styles.css +131 -0
  16. package/blueprints/features/ui-shared-components/BLUEPRINT.md +350 -13
  17. package/blueprints/features/ui-shared-components/files/ui/components.json +21 -0
  18. package/blueprints/features/ui-shared-components/files/ui/package.json +42 -0
  19. package/blueprints/features/ui-shared-components/files/ui/styles/globals.css +2 -0
  20. package/blueprints/features/ui-shared-components/files/ui/tsconfig.json +9 -0
  21. package/blueprints/features/ui-shared-components/files/ui/utils/cn.ts +6 -0
  22. package/blueprints/features/ui-shared-components/files/ui/utils/cva.ts +4 -0
  23. package/dist/index.js +1 -1
  24. package/package.json +1 -1
@@ -0,0 +1,332 @@
1
+ # Environment Variables Blueprint — T3 Env + Zod Validation
2
+
3
+ ## Tier
4
+
5
+ Feature
6
+
7
+ ## Status
8
+
9
+ Complete.
10
+
11
+ ## Problem
12
+
13
+ Environment variable management is tedious and error-prone across projects. Developers forget to add new variables to `.env.example`, miss the split between client and server vars in Next.js, deploy with missing variables that only crash at runtime, and have no type safety when accessing `process.env`. This blueprint creates a validated, type-safe environment variable system using `@t3-oss/env` + Zod that catches missing or malformed variables at build time.
14
+
15
+ This blueprint covers both Next.js apps (client/server split with `@t3-oss/env-nextjs`) and backend apps (server-only with `@t3-oss/env-core`).
16
+
17
+ ## Blueprint Dependencies
18
+
19
+ None. This blueprint is standalone and can be installed into any project.
20
+
21
+ ### Interaction with Other Blueprints
22
+
23
+ Feature blueprints that introduce environment variables (auth, db, etc.) should merge their vars into the env files this blueprint creates. The `// CONFIGURE:` comments mark where to add new variables.
24
+
25
+ - **auth-better-auth**: Adds `BETTER_AUTH_URL`, `BETTER_AUTH_SECRET`, `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` to `env/server.ts`
26
+ - **db-drizzle-postgres**: Adds `DATABASE_URL` to `packages/db/.env` (monorepo) or root `.env` (single-repo) — not to the app's env files
27
+
28
+ ---
29
+
30
+ ## Architecture
31
+
32
+ ### Core Pattern
33
+
34
+ Every app in the project gets Zod-validated environment variables through `@t3-oss/env`. Variables are validated at startup (or build time for Next.js) — if any are missing or malformed, the app fails immediately with a clear error instead of crashing later at the point of use.
35
+
36
+ **Next.js apps** use a two-file split:
37
+ - `src/env/client.ts` — client-side variables (`NEXT_PUBLIC_*`) using `@t3-oss/env-nextjs`
38
+ - `src/env/server.ts` — server-side variables using `@t3-oss/env-nextjs` with `experimental__runtimeEnv: process.env`
39
+
40
+ Both files are imported in `next.config.ts` to trigger build-time validation.
41
+
42
+ **Backend apps** (Hono, Express, Node) use a single file:
43
+ - `src/env.ts` — all server variables using `@t3-oss/env-core` with `dotenv/config`
44
+
45
+ ### Key Decisions
46
+
47
+ - **Client/server split for Next.js** (required) — Next.js runs code in both client and server contexts. Client variables must use the `NEXT_PUBLIC_` prefix and be declared in a `client` schema. Server variables must NOT be in the client schema (they'd be exposed to the browser). The two-file split enforces this boundary structurally.
48
+
49
+ - **`experimental__runtimeEnv: process.env` for server vars** (required) — Server variables in Next.js use `experimental__runtimeEnv` instead of listing each variable in `runtimeEnv`. This avoids the tedious boilerplate of repeating every server variable name twice (once in the schema, once in runtimeEnv).
50
+
51
+ - **`emptyStringAsUndefined: true`** (required) — Empty string environment variables are treated as undefined. This prevents the common mistake of setting `DATABASE_URL=` in `.env` and having it pass Zod validation as a valid string.
52
+
53
+ - **Build-time validation via `next.config.ts` import** (required) — Importing the env files at the top of `next.config.ts` ensures validation runs during `next build`. Missing variables fail the build rather than causing runtime errors in production.
54
+
55
+ - **`@t3-oss/env-core` for backend apps** (required) — Backend apps don't have the Next.js client/server split, so they use the simpler `@t3-oss/env-core` package with `dotenv/config` for `.env` file loading.
56
+
57
+ - **`z.preprocess` for PORT** (recommended) — Environment variables are always strings. PORT needs to be a number. `z.preprocess` handles the string-to-number conversion cleanly.
58
+
59
+ - **`.env.example` with documentation** (required) — Every app gets a documented `.env.example` with section headers, comments explaining each variable, and local/production value hints. This is the single source of truth for what environment variables an app needs.
60
+
61
+ - **Empty `.env.local` created** (required) — An empty `.env.local` file is created during scaffolding so developers have the file ready to fill in. This file is gitignored.
62
+
63
+ ---
64
+
65
+ ## Hard Requirements vs Recommended Defaults
66
+
67
+ **Hard requirements:**
68
+ - `@t3-oss/env-nextjs` for Next.js apps
69
+ - `@t3-oss/env-core` for backend apps
70
+ - Zod for schema validation
71
+ - Client/server split in Next.js (two files)
72
+ - Build-time validation via `next.config.ts` import
73
+ - `.env.example` for every app
74
+
75
+ **Recommended defaults — ask during scaffolding:**
76
+
77
+ | Choice | Recommended | Alternatives |
78
+ |---|---|---|
79
+ | Next.js env location | `src/env/client.ts` + `src/env/server.ts` | `env/client.ts` + `env/server.ts` (no `src/` prefix) |
80
+ | Backend env location | `src/env.ts` | `env.ts` at app root |
81
+ | Include PORT in backend env | Yes | No (if platform handles it) |
82
+ | Create `.env.local` | Yes | No (if using `.env` directly) |
83
+
84
+ ---
85
+
86
+ ## Dependencies
87
+
88
+ ### npm packages
89
+
90
+ **Next.js apps:**
91
+ | Package | Version | Purpose |
92
+ |---|---|---|
93
+ | `@t3-oss/env-nextjs` | ^0.13 | Environment variable validation for Next.js (client/server split) |
94
+ | `zod` | ^3.24 | Schema validation |
95
+
96
+ **Backend apps:**
97
+ | Package | Version | Purpose |
98
+ |---|---|---|
99
+ | `@t3-oss/env-core` | ^0.13 | Environment variable validation for Node.js |
100
+ | `zod` | ^3.24 | Schema validation |
101
+ | `dotenv` | ^16.4 | Load `.env` files (backend only — Next.js handles this natively) |
102
+
103
+ ### Environment Variables
104
+
105
+ | Variable | Where | Description |
106
+ |---|---|---|
107
+ | `NEXT_PUBLIC_FRONTEND_URL` | Next.js client | Frontend URL for redirects, CORS, metadata |
108
+
109
+ Additional variables are added by feature blueprints (auth, db, etc.).
110
+
111
+ ---
112
+
113
+ ## Monorepo Wiring
114
+
115
+ ### Next.js App (`apps/web/`)
116
+
117
+ The env files live inside the app directory — no shared package needed. Each Next.js app manages its own env validation.
118
+
119
+ **File structure:**
120
+ ```
121
+ apps/web/
122
+ ├── src/env/
123
+ │ ├── client.ts # Client env schema + validation
124
+ │ └── server.ts # Server env schema + validation
125
+ ├── next.config.ts # Imports both env files for build-time validation
126
+ ├── .env.example # Documented env template
127
+ └── .env.local # Local values (gitignored)
128
+ ```
129
+
130
+ **`next.config.ts` integration:**
131
+ ```typescript
132
+ import "./src/env/server";
133
+ import "./src/env/client";
134
+ ```
135
+
136
+ **Consuming env in code:**
137
+ ```typescript
138
+ // In server components, API routes, server actions:
139
+ import { serverEnv } from "~/env/server";
140
+ const dbUrl = serverEnv.DATABASE_URL;
141
+
142
+ // In client components:
143
+ import { clientEnv } from "~/env/client";
144
+ const apiUrl = clientEnv.NEXT_PUBLIC_API_URL;
145
+ ```
146
+
147
+ ### Backend App (`apis/server/`)
148
+
149
+ **File structure:**
150
+ ```
151
+ apis/server/
152
+ ├── src/
153
+ │ ├── env.ts # Server env schema + validation
154
+ │ └── index.ts # Imports env.ts at top
155
+ ├── .env.example # Documented env template
156
+ └── .env.local # Local values (gitignored)
157
+ ```
158
+
159
+ **Entry point integration:**
160
+ ```typescript
161
+ // src/index.ts
162
+ import { env } from "./env.js";
163
+ const port = env.PORT;
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Single-Repo Adaptation
169
+
170
+ For standalone applications (Next.js or backend) without a monorepo, the patterns are identical — only file placement differs slightly.
171
+
172
+ ### Path Mapping
173
+
174
+ | Aspect | Monorepo | Single-Repo |
175
+ |--------|----------|-------------|
176
+ | Next.js env location | `apps/web/src/env/` | `src/env/` |
177
+ | Backend env location | `apis/server/src/env.ts` | `src/env.ts` |
178
+ | `.env.example` location | Per-app (e.g., `apps/web/.env.example`) | Project root `.env.example` |
179
+ | `.env.local` location | Per-app (e.g., `apps/web/.env.local`) | Project root `.env.local` |
180
+ | Import path | `~/env/server` or `~/env/client` | `~/env/server` or `@/env/server` |
181
+
182
+ ### What Stays the Same
183
+
184
+ All core patterns are project-type-agnostic:
185
+ - `@t3-oss/env-nextjs` for Next.js, `@t3-oss/env-core` for backend
186
+ - Zod schemas for validation
187
+ - Client/server split (two files) for Next.js
188
+ - Build-time validation via `next.config.ts` import
189
+ - `.env.example` documentation pattern
190
+ - `emptyStringAsUndefined: true`
191
+
192
+ ---
193
+
194
+ ## File Manifest
195
+
196
+ | File | Purpose | Monorepo Target | Single-Repo Target |
197
+ |---|---|---|---|
198
+ | `files/nextjs/env/client.ts` | Next.js client env schema | `apps/web/src/env/client.ts` | `src/env/client.ts` |
199
+ | `files/nextjs/env/server.ts` | Next.js server env schema | `apps/web/src/env/server.ts` | `src/env/server.ts` |
200
+ | `files/nextjs/.env.example` | Documented env template (Next.js) | `apps/web/.env.example` | `.env.example` |
201
+ | `files/nextjs/.env.local` | Empty local env file (Next.js) | `apps/web/.env.local` | `.env.local` |
202
+ | `files/server/env.ts` | Backend env schema (`@t3-oss/env-core`) | `apis/server/src/env.ts` | `src/env.ts` |
203
+ | `files/server/.env.example` | Documented env template (backend) | `apis/server/.env.example` | `.env.example` |
204
+ | `files/server/.env.local` | Empty local env file (backend) | `apis/server/.env.local` | `.env.local` |
205
+
206
+ ---
207
+
208
+ ## Integration Steps
209
+
210
+ ### Phase 1: Next.js App Setup
211
+
212
+ 1. Create `src/env/` directory in the target Next.js app
213
+ 2. Copy `env/client.ts` — replace `{{APP_NAME}}` in comments
214
+ 3. Copy `env/server.ts` — replace `{{APP_NAME}}` in comments
215
+ 4. If an existing `env.ts` file exists at the app root:
216
+ - Read it to extract any existing variables
217
+ - Merge them into the appropriate file (client or server) based on the `NEXT_PUBLIC_` prefix
218
+ - Remove the old `env.ts`
219
+ 5. Update `next.config.ts` — add imports at the top:
220
+ ```typescript
221
+ import "./src/env/server";
222
+ import "./src/env/client";
223
+ ```
224
+ If existing `import "./env"` is present, replace it with the two new imports.
225
+ 6. Copy `.env.example` — replace `{{APP_NAME}}`
226
+ 7. Create `.env.local` (empty)
227
+ 8. If other blueprints are already installed, pre-populate their env vars into the appropriate schema files
228
+
229
+ ### Phase 2: Backend App Setup (if present)
230
+
231
+ 9. Copy `env.ts` to `src/env.ts` in the backend app — replace `{{APP_NAME}}`
232
+ 10. Update the app's entry point (e.g., `src/index.ts`) to import `env.ts`:
233
+ ```typescript
234
+ import { env } from "./env.js";
235
+ ```
236
+ 11. Copy `.env.example` — replace `{{APP_NAME}}`
237
+ 12. Create `.env.local` (empty)
238
+
239
+ ### Phase 3: Dependency Installation
240
+
241
+ 13. For each Next.js app: ensure `@t3-oss/env-nextjs` and `zod` are in `dependencies`
242
+ 14. For each backend app: ensure `@t3-oss/env-core`, `zod`, and `dotenv` are in `dependencies`
243
+
244
+ ### Phase 4: Verification
245
+
246
+ 15. Run `pnpm dev` (or equivalent) — env validation should run without errors
247
+ 16. Try removing a required variable from `.env.local` — build should fail with a clear error message
248
+
249
+ ---
250
+
251
+ ## Maintenance Hooks
252
+
253
+ ### Environment Variable Hooks
254
+
255
+ | When you... | Then do... | Why |
256
+ |---|---|---|
257
+ | Add a new env var in code | Add to `env/client.ts` or `env/server.ts` schema AND `.env.example` AND `.env.local` | Missing from schema = build-time crash; missing from example = teammates can't set up |
258
+ | Add a `NEXT_PUBLIC_*` var | Put it in `env/client.ts` with both `client` schema and `runtimeEnv` entries | Client vars must be explicitly mapped in Next.js |
259
+ | Add a server-only var to Next.js | Put it in `env/server.ts` (uses `experimental__runtimeEnv: process.env`) | Avoids listing every server var twice |
260
+ | Remove an env var | Remove from schema file, `.env.example`, and `.env.local` | Stale vars cause confusion |
261
+ | Add a new app to the monorepo | Create its own `env/` files — don't share env schemas between apps | Each app has different variable requirements |
262
+ | Change a var from optional to required | Update the Zod schema (remove `.optional()`) and ensure `.env.example` has a value | Will break builds for teammates with empty values |
263
+
264
+ ### Condensed Rules for project rules file
265
+
266
+ ```markdown
267
+ ### env-t3 maintenance
268
+ - After adding a new env var: add it to the env schema file (client.ts or server.ts), `.env.example`, and `.env.local`
269
+ - NEXT_PUBLIC_* vars go in env/client.ts with explicit runtimeEnv mapping; server vars go in env/server.ts
270
+ - After removing an env var: remove from schema, .env.example, and .env.local
271
+ - Never access process.env directly — always use the typed env objects (clientEnv, serverEnv, or env)
272
+ - Keep .env.example documented with section headers and local/production hints
273
+ ```
274
+
275
+ ---
276
+
277
+ ## What's Configurable
278
+
279
+ - Env file location (`src/env/` vs `env/`)
280
+ - Which apps get env setup (Next.js, backend, or both)
281
+ - Starting variables (pre-populated from other installed blueprints)
282
+ - PORT default value for backend apps
283
+
284
+ ## What's Opinionated
285
+
286
+ - **T3 Env** — the only supported env validation library (provides the best DX for Next.js client/server split)
287
+ - **Zod** — the only supported schema library (required by T3 Env)
288
+ - **Client/server split** — Next.js apps always get two files, not one combined file
289
+ - **Build-time validation** — env files are always imported in `next.config.ts`
290
+ - **`emptyStringAsUndefined`** — always enabled (prevents empty string foot-guns)
291
+ - **`.env.example` documentation** — always includes section headers and comments
292
+
293
+ ## Project Context Output
294
+
295
+ Appends to `.project-context.md` under `## Installed Blueprints`:
296
+
297
+ ```yaml
298
+ ### env-t3
299
+ blueprint: env-t3
300
+ choices:
301
+ nextjs_env_location: src/env/
302
+ backend_env_location: src/env.ts
303
+ apps_configured:
304
+ - name: web
305
+ type: nextjs
306
+ files:
307
+ - src/env/client.ts
308
+ - src/env/server.ts
309
+ - .env.example
310
+ - .env.local
311
+ - name: server
312
+ type: backend
313
+ files:
314
+ - src/env.ts
315
+ - .env.example
316
+ - .env.local
317
+ packages_added:
318
+ - "@t3-oss/env-nextjs"
319
+ - "@t3-oss/env-core"
320
+ - zod
321
+ - dotenv
322
+ ```
323
+
324
+ ---
325
+
326
+ ## References
327
+
328
+ - **T3 Env Docs:** https://env.t3.gg/docs/introduction
329
+ - **T3 Env Next.js:** https://env.t3.gg/docs/nextjs
330
+ - **T3 Env Core:** https://env.t3.gg/docs/core
331
+ - **Zod Docs:** https://zod.dev/
332
+ - **Next.js Environment Variables:** https://nextjs.org/docs/app/building-your-application/configuring/environment-variables
@@ -0,0 +1,17 @@
1
+ # =============================================================================
2
+ # {{APP_NAME}} — Environment Variables
3
+ # =============================================================================
4
+ # Copy this file to .env.local and fill in the values.
5
+ # Feature blueprints will add their own variables — check their BLUEPRINT.md.
6
+
7
+ # -----------------------------------------------------------------------------
8
+ # App
9
+ # -----------------------------------------------------------------------------
10
+
11
+ # Frontend URL (used for redirects, CORS, and metadata)
12
+ # Local: http://localhost:3000 | Production: https://yourdomain.com
13
+ NEXT_PUBLIC_FRONTEND_URL=http://localhost:3000
14
+
15
+ # CONFIGURE: Feature blueprints add variables here:
16
+ # - /scaffold-auth adds: BETTER_AUTH_URL, BETTER_AUTH_SECRET, GOOGLE_CLIENT_ID, etc.
17
+ # - /scaffold-db adds: DATABASE_URL (in packages/db/.env for monorepos)
@@ -0,0 +1,13 @@
1
+ import { createEnv } from "@t3-oss/env-nextjs";
2
+ import { z } from "zod";
3
+
4
+ export const clientEnv = createEnv({
5
+ client: {
6
+ NEXT_PUBLIC_FRONTEND_URL: z.string().url(),
7
+ // CONFIGURE: Feature blueprints add client env vars here
8
+ // e.g., NEXT_PUBLIC_API_URL: z.string().url(),
9
+ },
10
+ runtimeEnv: {
11
+ NEXT_PUBLIC_FRONTEND_URL: process.env.NEXT_PUBLIC_FRONTEND_URL,
12
+ },
13
+ });
@@ -0,0 +1,12 @@
1
+ import { createEnv } from "@t3-oss/env-nextjs";
2
+ import { z } from "zod";
3
+
4
+ export const serverEnv = createEnv({
5
+ server: {
6
+ // CONFIGURE: Feature blueprints add server env vars here
7
+ // e.g., DATABASE_URL: z.string().url(),
8
+ // e.g., BETTER_AUTH_SECRET: z.string().min(32),
9
+ },
10
+ experimental__runtimeEnv: process.env,
11
+ emptyStringAsUndefined: true,
12
+ });
@@ -0,0 +1,14 @@
1
+ # =============================================================================
2
+ # {{APP_NAME}} Server — Environment Variables
3
+ # =============================================================================
4
+ # Copy this file to .env.local and fill in the values.
5
+
6
+ # -----------------------------------------------------------------------------
7
+ # Server Configuration
8
+ # -----------------------------------------------------------------------------
9
+
10
+ # Port the server listens on
11
+ # Local: 4000 | Production: Set by hosting platform
12
+ PORT=4000
13
+
14
+ # CONFIGURE: Add server-specific variables below
@@ -0,0 +1,17 @@
1
+ import "dotenv/config";
2
+ import { createEnv } from "@t3-oss/env-core";
3
+ import { z } from "zod";
4
+
5
+ export const env = createEnv({
6
+ server: {
7
+ PORT: z.preprocess(
8
+ (s) => parseInt(String(s), 10) || undefined,
9
+ z.number().min(1).default(4000),
10
+ ),
11
+ // CONFIGURE: Add server env vars here
12
+ // e.g., DATABASE_URL: z.string().url(),
13
+ // e.g., REDIS_URL: z.string().min(1),
14
+ },
15
+ runtimeEnv: process.env,
16
+ emptyStringAsUndefined: true,
17
+ });