create-monolayer-app 0.1.0-canary.1
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 +54 -0
- package/bin/index.js +179 -0
- package/package.json +29 -0
- package/template/.agents/skills/react-router/SKILL.md +122 -0
- package/template/.agents/skills/react-router/references/data-mode.md +165 -0
- package/template/.agents/skills/react-router/references/declarative-mode.md +123 -0
- package/template/.agents/skills/react-router/references/framework-mode.md +213 -0
- package/template/.agents/skills/react-router/references/rsc.md +90 -0
- package/template/.claude/CLAUDE.md +126 -0
- package/template/.dockerignore +4 -0
- package/template/.vscode/settings.json +62 -0
- package/template/AGENTS.md +126 -0
- package/template/README.md +87 -0
- package/template/_gitignore +7 -0
- package/template/app/app.css +16 -0
- package/template/app/root.tsx +76 -0
- package/template/app/routes/home.tsx +13 -0
- package/template/app/routes.ts +3 -0
- package/template/app/welcome/logo-dark.svg +23 -0
- package/template/app/welcome/logo-light.svg +23 -0
- package/template/app/welcome/welcome.tsx +89 -0
- package/template/oxfmt.config.ts +7 -0
- package/template/oxlint.config.ts +34 -0
- package/template/package.json +34 -0
- package/template/public/favicon.ico +0 -0
- package/template/react-router.config.ts +7 -0
- package/template/tsconfig.json +27 -0
- package/template/vite.config.ts +10 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Framework Mode
|
|
2
|
+
|
|
3
|
+
Framework Mode is React Router's full-stack mode. It uses the React Router Vite plugin, route config in `app/routes.ts`, route modules, generated route types, and rendering strategies such as SSR, SPA mode, and pre-rendering.
|
|
4
|
+
|
|
5
|
+
Use this reference after the main skill identifies a Framework Mode app.
|
|
6
|
+
|
|
7
|
+
## Read the Local Docs by Mode
|
|
8
|
+
|
|
9
|
+
Start with:
|
|
10
|
+
|
|
11
|
+
```txt
|
|
12
|
+
react-router/docs/start/modes.md
|
|
13
|
+
react-router/docs/start/framework/index.md
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Then use the Framework docs under:
|
|
17
|
+
|
|
18
|
+
```txt
|
|
19
|
+
react-router/docs/start/framework/
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Those files cover installation, routing, route modules, data loading, actions, navigation, pending UI, rendering, deploying, and testing. For task-specific details, read relevant files in:
|
|
23
|
+
|
|
24
|
+
```txt
|
|
25
|
+
react-router/docs/how-to/
|
|
26
|
+
react-router/docs/explanation/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Always check the `[MODES: framework, ...]` marker in a doc before applying it.
|
|
30
|
+
|
|
31
|
+
## Framework Shape
|
|
32
|
+
|
|
33
|
+
Examples usually assume the default `appDirectory` of `app`. Check `react-router.config.ts` before assuming exact paths.
|
|
34
|
+
|
|
35
|
+
Look for these files and conventions:
|
|
36
|
+
|
|
37
|
+
```txt
|
|
38
|
+
react-router.config.ts
|
|
39
|
+
app/root.tsx
|
|
40
|
+
app/routes.ts
|
|
41
|
+
app/routes/**/*.tsx
|
|
42
|
+
route modules importing from ./+types/...
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Typical route module:
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import type { Route } from "./+types/product";
|
|
49
|
+
|
|
50
|
+
export async function loader({ params }: Route.LoaderArgs) {
|
|
51
|
+
return { product: await getProduct(params.productId) };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default function Product({ loaderData }: Route.ComponentProps) {
|
|
55
|
+
return <h1>{loaderData.product.name}</h1>;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Route Configuration
|
|
60
|
+
|
|
61
|
+
Framework apps use `app/routes.ts`. Many apps use file-system routing via `flatRoutes()`, but manual route config is also supported.
|
|
62
|
+
|
|
63
|
+
Before editing routes, read:
|
|
64
|
+
|
|
65
|
+
```txt
|
|
66
|
+
react-router/docs/start/framework/routing.md
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
If the app uses file-route conventions, read:
|
|
70
|
+
|
|
71
|
+
```txt
|
|
72
|
+
react-router/docs/how-to/file-route-conventions.md
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Route Modules
|
|
76
|
+
|
|
77
|
+
Route modules are the main unit of Framework Mode. Before adding or changing route exports, read:
|
|
78
|
+
|
|
79
|
+
```txt
|
|
80
|
+
react-router/docs/start/framework/route-module.md
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Common exports include:
|
|
84
|
+
|
|
85
|
+
| Export | Use |
|
|
86
|
+
| --------------------------------- | ------------------------------------------------------------------- |
|
|
87
|
+
| `default` | Route component rendered for the match |
|
|
88
|
+
| `loader` | Server data loading for SSR/pre-rendering/server data requests |
|
|
89
|
+
| `clientLoader` | Browser-only data loading or supplementing server loader data |
|
|
90
|
+
| `action` | Server mutation called by `<Form>`, `useSubmit`, or fetchers |
|
|
91
|
+
| `clientAction` | Browser-only mutation or client-side wrapper around a server action |
|
|
92
|
+
| `ErrorBoundary` | UI for errors thrown by this route's loaders/actions/component |
|
|
93
|
+
| `HydrateFallback` | Initial fallback while client loader hydration runs |
|
|
94
|
+
| `links` / `meta` | Route document links and metadata |
|
|
95
|
+
| `handle` | Arbitrary route metadata consumed via `useMatches` |
|
|
96
|
+
| `shouldRevalidate` | Overrides default loader revalidation behavior |
|
|
97
|
+
| `middleware` / `clientMiddleware` | Server/client request pipeline hooks when enabled |
|
|
98
|
+
|
|
99
|
+
Use generated `Route.*` types from `./+types/<route>` for route module args and props.
|
|
100
|
+
|
|
101
|
+
## Layout and Root Route Rules
|
|
102
|
+
|
|
103
|
+
- `app/root.tsx` is the root route and should contain global document/app shell concerns.
|
|
104
|
+
- Put global providers, app-wide nav, app-wide footer, scripts/meta/links, and document structure in `root.tsx` when appropriate.
|
|
105
|
+
- Use nested routes/layout routes for section-specific layouts.
|
|
106
|
+
- Do not flatten routes that should share UI or data boundaries.
|
|
107
|
+
|
|
108
|
+
Useful docs:
|
|
109
|
+
|
|
110
|
+
```txt
|
|
111
|
+
react-router/docs/explanation/special-files.md
|
|
112
|
+
react-router/docs/start/framework/routing.md
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Data and Mutations
|
|
116
|
+
|
|
117
|
+
Before working on route data:
|
|
118
|
+
|
|
119
|
+
```txt
|
|
120
|
+
react-router/docs/start/framework/data-loading.md
|
|
121
|
+
react-router/docs/start/framework/actions.md
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Framework rules:
|
|
125
|
+
|
|
126
|
+
- Load route data with `loader` or `clientLoader`.
|
|
127
|
+
- Mutate route data with `action` or `clientAction`.
|
|
128
|
+
- Prefer route loaders/actions over ad hoc `useEffect` fetching for route data.
|
|
129
|
+
- Use `data()`/Responses and redirects according to the docs.
|
|
130
|
+
- Let React Router revalidate after actions unless the docs point you to `shouldRevalidate`.
|
|
131
|
+
- In SSR/server data routes, keep Node-only/database code in server-only modules and call it from `loader`/`action`, not from browser-rendered component code.
|
|
132
|
+
|
|
133
|
+
Common patterns:
|
|
134
|
+
|
|
135
|
+
- Validation failure from an action: return `data({ errors, values }, { status: 400 })`, then render errors from `Route.ComponentProps["actionData"]` or `fetcher.data`.
|
|
136
|
+
- Missing record in a loader: throw `data("Not Found", { status: 404 })` and render the route `ErrorBoundary`.
|
|
137
|
+
- Search/filter data: parse the route request URL/search params in the loader so the URL is shareable and bookmarkable.
|
|
138
|
+
|
|
139
|
+
## Forms, Fetchers, and Pending UI
|
|
140
|
+
|
|
141
|
+
For forms and pending UI, read:
|
|
142
|
+
|
|
143
|
+
```txt
|
|
144
|
+
react-router/docs/start/framework/actions.md
|
|
145
|
+
react-router/docs/start/framework/pending-ui.md
|
|
146
|
+
react-router/docs/how-to/fetchers.md
|
|
147
|
+
react-router/docs/explanation/form-vs-fetcher.md
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Rules of thumb:
|
|
151
|
+
|
|
152
|
+
- Search/filter form that updates the URL: `<Form method="get">`.
|
|
153
|
+
- Mutation that should change URL/history or redirect after completion: `<Form method="post">`.
|
|
154
|
+
- Mutation that should keep the user on the same page: `useFetcher` / `<fetcher.Form>`.
|
|
155
|
+
- Optimistic UI: derive from `fetcher.formData` or `navigation.formData`.
|
|
156
|
+
|
|
157
|
+
## Type Safety
|
|
158
|
+
|
|
159
|
+
Before changing generated route types or typed URL behavior, read:
|
|
160
|
+
|
|
161
|
+
```txt
|
|
162
|
+
react-router/docs/how-to/route-module-type-safety.md
|
|
163
|
+
react-router/docs/explanation/type-safety.md
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Rules:
|
|
167
|
+
|
|
168
|
+
- Import types from `./+types/<route>`.
|
|
169
|
+
- Use `Route.LoaderArgs`, `Route.ActionArgs`, `Route.ComponentProps`, etc.
|
|
170
|
+
- Use type-only imports where appropriate.
|
|
171
|
+
- Do not edit generated `.react-router/types` files.
|
|
172
|
+
|
|
173
|
+
## Metadata
|
|
174
|
+
|
|
175
|
+
Before changing `meta`, read:
|
|
176
|
+
|
|
177
|
+
```txt
|
|
178
|
+
react-router/docs/how-to/meta.md
|
|
179
|
+
react-router/docs/start/framework/route-module.md
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Important: `meta` receives `loaderData`; do not use deprecated `data` args.
|
|
183
|
+
|
|
184
|
+
## Rendering Strategy
|
|
185
|
+
|
|
186
|
+
Framework Mode can be SSR, SPA, pre-rendered, or mixed depending on config and route behavior. Before changing rendering behavior, read:
|
|
187
|
+
|
|
188
|
+
```txt
|
|
189
|
+
react-router/docs/start/framework/rendering.md
|
|
190
|
+
react-router/docs/how-to/spa.md
|
|
191
|
+
react-router/docs/how-to/pre-rendering.md
|
|
192
|
+
react-router/docs/explanation/hydration.md
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Middleware, Sessions, and Auth
|
|
196
|
+
|
|
197
|
+
Before implementing middleware or auth/session flows, read:
|
|
198
|
+
|
|
199
|
+
```txt
|
|
200
|
+
react-router/docs/how-to/middleware.md
|
|
201
|
+
react-router/docs/explanation/sessions-and-cookies.md
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Middleware and context APIs are version/config sensitive. Check the installed React Router version and the app's `react-router.config.ts` before implementing.
|
|
205
|
+
|
|
206
|
+
## RSC Framework
|
|
207
|
+
|
|
208
|
+
If this Framework app uses `unstable_reactRouterRSC` or `@vitejs/plugin-rsc`, also read:
|
|
209
|
+
|
|
210
|
+
```txt
|
|
211
|
+
references/rsc.md
|
|
212
|
+
react-router/docs/how-to/react-server-components.md
|
|
213
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# React Server Components (RSC)
|
|
2
|
+
|
|
3
|
+
React Router's RSC support is unstable and exists in two variants:
|
|
4
|
+
|
|
5
|
+
- **RSC Framework Mode**: Framework Mode with the unstable RSC Vite plugin.
|
|
6
|
+
- **RSC Data Mode**: lower-level RSC runtime APIs and manual bundler/server integration.
|
|
7
|
+
|
|
8
|
+
Use this reference in addition to `framework-mode.md` or `data-mode.md` after the main skill identifies an RSC app.
|
|
9
|
+
|
|
10
|
+
## Read the Local RSC Docs
|
|
11
|
+
|
|
12
|
+
Start with:
|
|
13
|
+
|
|
14
|
+
```txt
|
|
15
|
+
react-router/docs/how-to/react-server-components.md
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Then read the relevant base mode docs:
|
|
19
|
+
|
|
20
|
+
```txt
|
|
21
|
+
react-router/docs/start/framework/
|
|
22
|
+
react-router/docs/start/data/
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
RSC docs may describe differences from non-RSC mode rather than repeating every Framework/Data concept, so keep both layers in mind.
|
|
26
|
+
|
|
27
|
+
## Detect RSC Framework Mode
|
|
28
|
+
|
|
29
|
+
Look for:
|
|
30
|
+
|
|
31
|
+
- `unstable_reactRouterRSC` imported from `@react-router/dev/vite`
|
|
32
|
+
- `@vitejs/plugin-rsc`
|
|
33
|
+
- `vite.config.ts` with `plugins: [reactRouterRSC(), rsc()]`
|
|
34
|
+
- Framework route modules plus RSC route exports
|
|
35
|
+
- RSC entry files such as `entry.rsc`
|
|
36
|
+
|
|
37
|
+
RSC Framework Mode uses a different Vite plugin from non-RSC Framework Mode. Do not swap it for the regular `reactRouter()` plugin.
|
|
38
|
+
|
|
39
|
+
## Detect RSC Data Mode
|
|
40
|
+
|
|
41
|
+
Look for:
|
|
42
|
+
|
|
43
|
+
- `unstable_RSCRouteConfig`
|
|
44
|
+
- route config passed to lower-level RSC APIs
|
|
45
|
+
- APIs such as `unstable_matchRSCServerRequest`, `unstable_routeRSCServerRequest`, `unstable_RSCHydratedRouter`, or `unstable_RSCStaticRouter`
|
|
46
|
+
- custom bundler/server setup around RSC
|
|
47
|
+
|
|
48
|
+
RSC Data Mode is more manual than RSC Framework Mode. Match the app's bundler and server abstractions before changing routes or entries.
|
|
49
|
+
|
|
50
|
+
## RSC Route Module Differences
|
|
51
|
+
|
|
52
|
+
In RSC Framework Mode, many normal Framework Mode concepts still apply, but routes can use server component exports.
|
|
53
|
+
|
|
54
|
+
Important route-module concepts from the RSC docs include:
|
|
55
|
+
|
|
56
|
+
- `ServerComponent` instead of the usual client `default` component
|
|
57
|
+
- `ServerErrorBoundary` paired with `ErrorBoundary`
|
|
58
|
+
- `ServerLayout` paired with `Layout`
|
|
59
|
+
- `ServerHydrateFallback` paired with `HydrateFallback`
|
|
60
|
+
- server-rendered React elements returned from loaders/actions
|
|
61
|
+
|
|
62
|
+
A route module cannot export both the normal client component and its server component counterpart for the same role. Read the RSC docs before adding these exports.
|
|
63
|
+
|
|
64
|
+
## Client/Server Boundaries
|
|
65
|
+
|
|
66
|
+
RSC code must respect React's client/server split:
|
|
67
|
+
|
|
68
|
+
- Use `"use client"` for components that need hooks, browser APIs, or event handlers.
|
|
69
|
+
- Use server-only modules for server data access and secrets.
|
|
70
|
+
- In RSC Framework Mode, prefer the `server-only` and `client-only` boundary imports described in the docs.
|
|
71
|
+
- Do not assume `.server`/`.client` file naming works the same way in RSC Framework Mode; read the RSC docs before relying on those conventions.
|
|
72
|
+
|
|
73
|
+
## Data Loading in RSC
|
|
74
|
+
|
|
75
|
+
RSC changes where data can be loaded:
|
|
76
|
+
|
|
77
|
+
- Server Components can fetch data directly on the server.
|
|
78
|
+
- Loaders/actions may still exist and can have RSC-specific behavior.
|
|
79
|
+
- Client components still need client-safe data and cannot directly access server-only modules.
|
|
80
|
+
|
|
81
|
+
When choosing between a server component fetch, a loader, and a client loader/action, follow the RSC docs and match existing app patterns.
|
|
82
|
+
|
|
83
|
+
## Stability
|
|
84
|
+
|
|
85
|
+
RSC APIs are explicitly unstable. Before implementing or refactoring RSC code:
|
|
86
|
+
|
|
87
|
+
- Check the installed React Router version.
|
|
88
|
+
- Check the installed `@vitejs/plugin-rsc` version.
|
|
89
|
+
- Read the app's existing RSC entry/config files.
|
|
90
|
+
- Prefer minimal changes that match current patterns.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Ultracite Code Standards
|
|
2
|
+
|
|
3
|
+
This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
- **Format code**: `npm exec -- ultracite fix`
|
|
8
|
+
- **Check for issues**: `npm exec -- ultracite check`
|
|
9
|
+
- **Diagnose setup**: `npm exec -- ultracite doctor`
|
|
10
|
+
|
|
11
|
+
Oxlint + Oxfmt (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Core Principles
|
|
16
|
+
|
|
17
|
+
Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity.
|
|
18
|
+
|
|
19
|
+
### Type Safety & Explicitness
|
|
20
|
+
|
|
21
|
+
- Use explicit types for function parameters and return values when they enhance clarity
|
|
22
|
+
- Prefer `unknown` over `any` when the type is genuinely unknown
|
|
23
|
+
- Use const assertions (`as const`) for immutable values and literal types
|
|
24
|
+
- Leverage TypeScript's type narrowing instead of type assertions
|
|
25
|
+
- Use meaningful variable names instead of magic numbers - extract constants with descriptive names
|
|
26
|
+
|
|
27
|
+
### Modern JavaScript/TypeScript
|
|
28
|
+
|
|
29
|
+
- Use arrow functions for callbacks and short functions
|
|
30
|
+
- Prefer `for...of` loops over `.forEach()` and indexed `for` loops
|
|
31
|
+
- Use optional chaining (`?.`) and nullish coalescing (`??`) for safer property access
|
|
32
|
+
- Prefer template literals over string concatenation
|
|
33
|
+
- Use destructuring for object and array assignments
|
|
34
|
+
- Use `const` by default, `let` only when reassignment is needed, never `var`
|
|
35
|
+
|
|
36
|
+
### Async & Promises
|
|
37
|
+
|
|
38
|
+
- Always `await` promises in async functions - don't forget to use the return value
|
|
39
|
+
- Use `async/await` syntax instead of promise chains for better readability
|
|
40
|
+
- Handle errors appropriately in async code with try-catch blocks
|
|
41
|
+
- Don't use async functions as Promise executors
|
|
42
|
+
|
|
43
|
+
### React & JSX
|
|
44
|
+
|
|
45
|
+
- Use function components over class components
|
|
46
|
+
- Call hooks at the top level only, never conditionally
|
|
47
|
+
- Specify all dependencies in hook dependency arrays correctly
|
|
48
|
+
- Use the `key` prop for elements in iterables (prefer unique IDs over array indices)
|
|
49
|
+
- Nest children between opening and closing tags instead of passing as props
|
|
50
|
+
- Don't define components inside other components
|
|
51
|
+
- Use semantic HTML and ARIA attributes for accessibility:
|
|
52
|
+
- Provide meaningful alt text for images
|
|
53
|
+
- Use proper heading hierarchy
|
|
54
|
+
- Add labels for form inputs
|
|
55
|
+
- Include keyboard event handlers alongside mouse events
|
|
56
|
+
- Use semantic elements (`<button>`, `<nav>`, etc.) instead of divs with roles
|
|
57
|
+
|
|
58
|
+
### Error Handling & Debugging
|
|
59
|
+
|
|
60
|
+
- Remove `console.log`, `debugger`, and `alert` statements from production code
|
|
61
|
+
- Throw `Error` objects with descriptive messages, not strings or other values
|
|
62
|
+
- Use `try-catch` blocks meaningfully - don't catch errors just to rethrow them
|
|
63
|
+
- Prefer early returns over nested conditionals for error cases
|
|
64
|
+
|
|
65
|
+
### Code Organization
|
|
66
|
+
|
|
67
|
+
- Keep functions focused and under reasonable cognitive complexity limits
|
|
68
|
+
- Extract complex conditions into well-named boolean variables
|
|
69
|
+
- Use early returns to reduce nesting
|
|
70
|
+
- Prefer simple conditionals over nested ternary operators
|
|
71
|
+
- Group related code together and separate concerns
|
|
72
|
+
|
|
73
|
+
### Security
|
|
74
|
+
|
|
75
|
+
- Add `rel="noopener"` when using `target="_blank"` on links
|
|
76
|
+
- Avoid `dangerouslySetInnerHTML` unless absolutely necessary
|
|
77
|
+
- Don't use `eval()` or assign directly to `document.cookie`
|
|
78
|
+
- Validate and sanitize user input
|
|
79
|
+
|
|
80
|
+
### Performance
|
|
81
|
+
|
|
82
|
+
- Avoid spread syntax in accumulators within loops
|
|
83
|
+
- Use top-level regex literals instead of creating them in loops
|
|
84
|
+
- Prefer specific imports over namespace imports
|
|
85
|
+
- Avoid barrel files (index files that re-export everything)
|
|
86
|
+
- Use proper image components (e.g., Next.js `<Image>`) over `<img>` tags
|
|
87
|
+
|
|
88
|
+
### Framework-Specific Guidance
|
|
89
|
+
|
|
90
|
+
**Next.js:**
|
|
91
|
+
|
|
92
|
+
- Use Next.js `<Image>` component for images
|
|
93
|
+
- Use `next/head` or App Router metadata API for head elements
|
|
94
|
+
- Use Server Components for async data fetching instead of async Client Components
|
|
95
|
+
|
|
96
|
+
**React 19+:**
|
|
97
|
+
|
|
98
|
+
- Use ref as a prop instead of `React.forwardRef`
|
|
99
|
+
|
|
100
|
+
**Solid/Svelte/Vue/Qwik:**
|
|
101
|
+
|
|
102
|
+
- Use `class` and `for` attributes (not `className` or `htmlFor`)
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Testing
|
|
107
|
+
|
|
108
|
+
- Write assertions inside `it()` or `test()` blocks
|
|
109
|
+
- Avoid done callbacks in async tests - use async/await instead
|
|
110
|
+
- Don't use `.only` or `.skip` in committed code
|
|
111
|
+
- Keep test suites reasonably flat - avoid excessive `describe` nesting
|
|
112
|
+
|
|
113
|
+
## When Oxlint + Oxfmt Can't Help
|
|
114
|
+
|
|
115
|
+
Oxlint + Oxfmt's linter will catch most issues automatically. Focus your attention on:
|
|
116
|
+
|
|
117
|
+
1. **Business logic correctness** - Oxlint + Oxfmt can't validate your algorithms
|
|
118
|
+
2. **Meaningful naming** - Use descriptive names for functions, variables, and types
|
|
119
|
+
3. **Architecture decisions** - Component structure, data flow, and API design
|
|
120
|
+
4. **Edge cases** - Handle boundary conditions and error states
|
|
121
|
+
5. **User experience** - Accessibility, performance, and usability considerations
|
|
122
|
+
6. **Documentation** - Add comments for complex logic, but prefer self-documenting code
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
Most formatting and common issues are automatically fixed by Oxlint + Oxfmt. Run `npm exec -- ultracite fix` before committing to ensure compliance.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
3
|
+
"editor.formatOnPaste": true,
|
|
4
|
+
"editor.formatOnSave": true,
|
|
5
|
+
"emmet.showExpandedAbbreviation": "never",
|
|
6
|
+
"js/ts.tsdk.path": "node_modules/typescript/lib",
|
|
7
|
+
"js/ts.tsdk.promptToUseWorkspaceVersion": true,
|
|
8
|
+
"[astro]": {
|
|
9
|
+
"editor.defaultFormatter": "astro-build.astro-vscode"
|
|
10
|
+
},
|
|
11
|
+
"[css]": {
|
|
12
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
13
|
+
},
|
|
14
|
+
"[graphql]": {
|
|
15
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
16
|
+
},
|
|
17
|
+
"[handlebars]": {
|
|
18
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
19
|
+
},
|
|
20
|
+
"[html]": {
|
|
21
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
22
|
+
},
|
|
23
|
+
"[javascript]": {
|
|
24
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
25
|
+
},
|
|
26
|
+
"[javascriptreact]": {
|
|
27
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
28
|
+
},
|
|
29
|
+
"[json]": {
|
|
30
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
31
|
+
},
|
|
32
|
+
"[jsonc]": {
|
|
33
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
34
|
+
},
|
|
35
|
+
"[less]": {
|
|
36
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
37
|
+
},
|
|
38
|
+
"[markdown]": {
|
|
39
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
40
|
+
},
|
|
41
|
+
"[scss]": {
|
|
42
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
43
|
+
},
|
|
44
|
+
"[typescript]": {
|
|
45
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
46
|
+
},
|
|
47
|
+
"[typescriptreact]": {
|
|
48
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
49
|
+
},
|
|
50
|
+
"[vue-html]": {
|
|
51
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
52
|
+
},
|
|
53
|
+
"[vue]": {
|
|
54
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
55
|
+
},
|
|
56
|
+
"[yaml]": {
|
|
57
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
58
|
+
},
|
|
59
|
+
"editor.codeActionsOnSave": {
|
|
60
|
+
"source.fixAll.oxc": "explicit"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Ultracite Code Standards
|
|
2
|
+
|
|
3
|
+
This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
- **Format code**: `npm exec -- ultracite fix`
|
|
8
|
+
- **Check for issues**: `npm exec -- ultracite check`
|
|
9
|
+
- **Diagnose setup**: `npm exec -- ultracite doctor`
|
|
10
|
+
|
|
11
|
+
Oxlint + Oxfmt (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Core Principles
|
|
16
|
+
|
|
17
|
+
Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity.
|
|
18
|
+
|
|
19
|
+
### Type Safety & Explicitness
|
|
20
|
+
|
|
21
|
+
- Use explicit types for function parameters and return values when they enhance clarity
|
|
22
|
+
- Prefer `unknown` over `any` when the type is genuinely unknown
|
|
23
|
+
- Use const assertions (`as const`) for immutable values and literal types
|
|
24
|
+
- Leverage TypeScript's type narrowing instead of type assertions
|
|
25
|
+
- Use meaningful variable names instead of magic numbers - extract constants with descriptive names
|
|
26
|
+
|
|
27
|
+
### Modern JavaScript/TypeScript
|
|
28
|
+
|
|
29
|
+
- Use arrow functions for callbacks and short functions
|
|
30
|
+
- Prefer `for...of` loops over `.forEach()` and indexed `for` loops
|
|
31
|
+
- Use optional chaining (`?.`) and nullish coalescing (`??`) for safer property access
|
|
32
|
+
- Prefer template literals over string concatenation
|
|
33
|
+
- Use destructuring for object and array assignments
|
|
34
|
+
- Use `const` by default, `let` only when reassignment is needed, never `var`
|
|
35
|
+
|
|
36
|
+
### Async & Promises
|
|
37
|
+
|
|
38
|
+
- Always `await` promises in async functions - don't forget to use the return value
|
|
39
|
+
- Use `async/await` syntax instead of promise chains for better readability
|
|
40
|
+
- Handle errors appropriately in async code with try-catch blocks
|
|
41
|
+
- Don't use async functions as Promise executors
|
|
42
|
+
|
|
43
|
+
### React & JSX
|
|
44
|
+
|
|
45
|
+
- Use function components over class components
|
|
46
|
+
- Call hooks at the top level only, never conditionally
|
|
47
|
+
- Specify all dependencies in hook dependency arrays correctly
|
|
48
|
+
- Use the `key` prop for elements in iterables (prefer unique IDs over array indices)
|
|
49
|
+
- Nest children between opening and closing tags instead of passing as props
|
|
50
|
+
- Don't define components inside other components
|
|
51
|
+
- Use semantic HTML and ARIA attributes for accessibility:
|
|
52
|
+
- Provide meaningful alt text for images
|
|
53
|
+
- Use proper heading hierarchy
|
|
54
|
+
- Add labels for form inputs
|
|
55
|
+
- Include keyboard event handlers alongside mouse events
|
|
56
|
+
- Use semantic elements (`<button>`, `<nav>`, etc.) instead of divs with roles
|
|
57
|
+
|
|
58
|
+
### Error Handling & Debugging
|
|
59
|
+
|
|
60
|
+
- Remove `console.log`, `debugger`, and `alert` statements from production code
|
|
61
|
+
- Throw `Error` objects with descriptive messages, not strings or other values
|
|
62
|
+
- Use `try-catch` blocks meaningfully - don't catch errors just to rethrow them
|
|
63
|
+
- Prefer early returns over nested conditionals for error cases
|
|
64
|
+
|
|
65
|
+
### Code Organization
|
|
66
|
+
|
|
67
|
+
- Keep functions focused and under reasonable cognitive complexity limits
|
|
68
|
+
- Extract complex conditions into well-named boolean variables
|
|
69
|
+
- Use early returns to reduce nesting
|
|
70
|
+
- Prefer simple conditionals over nested ternary operators
|
|
71
|
+
- Group related code together and separate concerns
|
|
72
|
+
|
|
73
|
+
### Security
|
|
74
|
+
|
|
75
|
+
- Add `rel="noopener"` when using `target="_blank"` on links
|
|
76
|
+
- Avoid `dangerouslySetInnerHTML` unless absolutely necessary
|
|
77
|
+
- Don't use `eval()` or assign directly to `document.cookie`
|
|
78
|
+
- Validate and sanitize user input
|
|
79
|
+
|
|
80
|
+
### Performance
|
|
81
|
+
|
|
82
|
+
- Avoid spread syntax in accumulators within loops
|
|
83
|
+
- Use top-level regex literals instead of creating them in loops
|
|
84
|
+
- Prefer specific imports over namespace imports
|
|
85
|
+
- Avoid barrel files (index files that re-export everything)
|
|
86
|
+
- Use proper image components (e.g., Next.js `<Image>`) over `<img>` tags
|
|
87
|
+
|
|
88
|
+
### Framework-Specific Guidance
|
|
89
|
+
|
|
90
|
+
**Next.js:**
|
|
91
|
+
|
|
92
|
+
- Use Next.js `<Image>` component for images
|
|
93
|
+
- Use `next/head` or App Router metadata API for head elements
|
|
94
|
+
- Use Server Components for async data fetching instead of async Client Components
|
|
95
|
+
|
|
96
|
+
**React 19+:**
|
|
97
|
+
|
|
98
|
+
- Use ref as a prop instead of `React.forwardRef`
|
|
99
|
+
|
|
100
|
+
**Solid/Svelte/Vue/Qwik:**
|
|
101
|
+
|
|
102
|
+
- Use `class` and `for` attributes (not `className` or `htmlFor`)
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Testing
|
|
107
|
+
|
|
108
|
+
- Write assertions inside `it()` or `test()` blocks
|
|
109
|
+
- Avoid done callbacks in async tests - use async/await instead
|
|
110
|
+
- Don't use `.only` or `.skip` in committed code
|
|
111
|
+
- Keep test suites reasonably flat - avoid excessive `describe` nesting
|
|
112
|
+
|
|
113
|
+
## When Oxlint + Oxfmt Can't Help
|
|
114
|
+
|
|
115
|
+
Oxlint + Oxfmt's linter will catch most issues automatically. Focus your attention on:
|
|
116
|
+
|
|
117
|
+
1. **Business logic correctness** - Oxlint + Oxfmt can't validate your algorithms
|
|
118
|
+
2. **Meaningful naming** - Use descriptive names for functions, variables, and types
|
|
119
|
+
3. **Architecture decisions** - Component structure, data flow, and API design
|
|
120
|
+
4. **Edge cases** - Handle boundary conditions and error states
|
|
121
|
+
5. **User experience** - Accessibility, performance, and usability considerations
|
|
122
|
+
6. **Documentation** - Add comments for complex logic, but prefer self-documenting code
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
Most formatting and common issues are automatically fixed by Oxlint + Oxfmt. Run `npm exec -- ultracite fix` before committing to ensure compliance.
|