create-starbase 5.0.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 +94 -0
- package/dist/index.d.ts +2 -0
- package/package.json +54 -0
- package/template/.claude/commands/audit.md +14 -0
- package/template/.claude/commands/review.md +23 -0
- package/template/.editorconfig +14 -0
- package/template/.env +1 -0
- package/template/.env.example +1 -0
- package/template/.nvmrc +1 -0
- package/template/.prettierignore +12 -0
- package/template/.prettierrc.json +7 -0
- package/template/.vscode/extensions.json +8 -0
- package/template/.vscode/settings.json +48 -0
- package/template/CLAUDE.md +109 -0
- package/template/README.md +46 -0
- package/template/eslint.config.js +27 -0
- package/template/index.html +47 -0
- package/template/package.json +51 -0
- package/template/src/lib/queries/github.ts +13 -0
- package/template/src/lib/queries/index.ts +1 -0
- package/template/src/lib/theme/app.css +3 -0
- package/template/src/lib/theme/base.css +37 -0
- package/template/src/lib/theme/tailwind.css +167 -0
- package/template/src/lib/utils/cn.ts +16 -0
- package/template/src/lib/utils/darkMode.ts +44 -0
- package/template/src/lib/utils/index.ts +2 -0
- package/template/src/main.tsx +38 -0
- package/template/src/routeTree.gen.ts +77 -0
- package/template/src/routes/__root.tsx +49 -0
- package/template/src/routes/index.tsx +29 -0
- package/template/src/routes/liftoff.tsx +22 -0
- package/template/src/ui/atoms/Button.tsx +106 -0
- package/template/src/ui/atoms/Code.tsx +52 -0
- package/template/src/ui/atoms/Link.tsx +78 -0
- package/template/src/ui/atoms/StarbaseLogo.tsx +19 -0
- package/template/src/ui/molecules/DarkModeToggle.tsx +29 -0
- package/template/src/ui/molecules/PageHeader.tsx +35 -0
- package/template/src/ui/molecules/Stargazers.tsx +24 -0
- package/template/src/ui/organisms/.gitkeep +0 -0
- package/template/src/ui/templates/.gitkeep +0 -0
- package/template/tsconfig.app.json +39 -0
- package/template/tsconfig.json +7 -0
- package/template/tsconfig.node.json +26 -0
- package/template/vite.config.ts +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Starbase v5
|
|
2
|
+
|
|
3
|
+
Starbase is a personal, opinionated front-end starter kit built on Vite, TypeScript, React and Tailwind CSS. It's been one of my favorite passion projects for over 8 years now, and v5 is its most ambitious launch yet.
|
|
4
|
+
|
|
5
|
+
For most of its life, Starbase solved a very specific problem: you don't have to write Webpack configs from scratch. That problem doesn't really exist anymore. Vite handles bundling beautifully, and the value of a boilerplate that just wires up a build tool has dropped to near zero.
|
|
6
|
+
|
|
7
|
+
So v5 asks a different question: what if the boilerplate encoded _how you build_, not just _what you build with_?
|
|
8
|
+
|
|
9
|
+
## The mission
|
|
10
|
+
|
|
11
|
+
The hard part of modern front-end development isn't getting a dev server running. It's maintaining consistency -- naming conventions, component architecture, accessibility standards, file organization -- across a codebase that grows over time, especially when AI tooling is doing a lot of the heavy lifting.
|
|
12
|
+
|
|
13
|
+
Starbase v5 is built around [Claude Code](https://docs.anthropic.com/en/docs/claude-code). The baseline components aren't throwaway demos. They're reference implementations that Claude pattern-matches against when generating new code. Every atom, molecule, and organism is a teaching artifact. The result is an AI-assisted workflow where generated code actually looks like _your_ code.
|
|
14
|
+
|
|
15
|
+
## Stack
|
|
16
|
+
|
|
17
|
+
| Tool | Role |
|
|
18
|
+
| -------------------------------------------------- | -------------------------------------------------------------- |
|
|
19
|
+
| [Vite](https://vite.dev/) | Build tooling and dev server |
|
|
20
|
+
| [TypeScript](https://www.typescriptlang.org/) | Type safety |
|
|
21
|
+
| [React](https://react.dev/) | UI library |
|
|
22
|
+
| [Tailwind CSS](https://tailwindcss.com/) | Utility-first styling with a semantic `sb-` color token system |
|
|
23
|
+
| [TanStack Router](https://tanstack.com/router) | File-based routing |
|
|
24
|
+
| [TanStack React Query](https://tanstack.com/query) | Server state and data fetching |
|
|
25
|
+
| [Motion](https://motion.dev/) | Animation |
|
|
26
|
+
| [ESLint](https://eslint.org/) | Linting (with react-x and react-dom plugins) |
|
|
27
|
+
| [Prettier](https://prettier.io/) | Formatting |
|
|
28
|
+
|
|
29
|
+
See [`template/package.json`](template/package.json) for the full dependency list.
|
|
30
|
+
|
|
31
|
+
## Architecture
|
|
32
|
+
|
|
33
|
+
Components follow [Atomic Design](https://atomicdesign.bradfrost.com/chapter-2/):
|
|
34
|
+
|
|
35
|
+
- **Atoms** -- Smallest building blocks. HTML-level primitives like buttons, inputs, links, and icons.
|
|
36
|
+
- **Molecules** -- Small groups of atoms functioning together as a unit. A dark mode toggle, a page header.
|
|
37
|
+
- **Organisms** -- Larger sections composed of molecules and atoms. Full-width layouts, distinct page sections.
|
|
38
|
+
- **Templates** -- Page-level layout structures that define where things go and how they relate.
|
|
39
|
+
|
|
40
|
+
Everything else is organized by concern:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
src/
|
|
44
|
+
lib/
|
|
45
|
+
queries/ # React Query options, organized by API domain
|
|
46
|
+
theme/ # Tailwind CSS and theme config
|
|
47
|
+
utils/ # Utility functions (cn, darkMode, etc.)
|
|
48
|
+
ui/
|
|
49
|
+
atoms/ # Button, Link, Code, StarbaseLogo
|
|
50
|
+
molecules/ # DarkModeToggle, PageHeader, Stargazers
|
|
51
|
+
organisms/
|
|
52
|
+
templates/
|
|
53
|
+
routes/ # TanStack Router file-based routes
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Imports use path aliases everywhere -- `from 'atoms/Button'` instead of `from '../../ui/atoms/Button'`. If you find yourself reaching for a relative path, that's a sign a new alias is needed.
|
|
57
|
+
|
|
58
|
+
## `CLAUDE.md`
|
|
59
|
+
|
|
60
|
+
This is the north star of the project. It's a living document that maps development preferences directly to codebase patterns -- accessibility standards, import conventions, component architecture, color tokens, writing style, and more.
|
|
61
|
+
|
|
62
|
+
It's not a personality dump. It's a working contract between you and Claude that says: here's how I like things done, and here are the reference implementations to prove it. When Claude generates code in a Starbase project, it builds on these conventions instead of guessing.
|
|
63
|
+
|
|
64
|
+
Read it. Evolve it. It's designed to grow with the project.
|
|
65
|
+
|
|
66
|
+
## Claude Code commands
|
|
67
|
+
|
|
68
|
+
Starbase ships with custom [Claude Code commands](https://docs.anthropic.com/en/docs/claude-code/tutorials#create-custom-slash-commands) that go beyond what a linter can catch:
|
|
69
|
+
|
|
70
|
+
- **`/audit`** -- Scans the codebase for drift against CLAUDE.md conventions. Raw color values bypassing the token system, components at the wrong atomic level, accessibility regressions, import violations. Architecture enforcement, automated.
|
|
71
|
+
- **`/review`** -- Reviews the current branch's changes against CLAUDE.md. Like a PR review from someone who actually read the style guide.
|
|
72
|
+
|
|
73
|
+
More commands are on the launchpad. The goal is a suite of tools that handle the mechanical parts of maintaining consistency so you can focus on building.
|
|
74
|
+
|
|
75
|
+
## Liftoff
|
|
76
|
+
|
|
77
|
+
Scaffold a new project, install dependencies, and you're in orbit:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm create starbase@latest my-project
|
|
81
|
+
cd my-project
|
|
82
|
+
npm install
|
|
83
|
+
npm run dev
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## History
|
|
87
|
+
|
|
88
|
+
Starbase is built and maintained by [Brian Staruk](https://brian.staruk.net), a Boston-based web developer with 20+ years of experience who's never quite gotten over the urge to nerd out in public. Go Sox. That impulse is the main reason this project has been actively maintained since 2017 -- through four major versions, each one reflecting whatever felt like the right way to build for the web at the time. PostCSS, Webpack, TypeScript, Tailwind -- it picked up tools as they matured and dropped them when something better came along.
|
|
89
|
+
|
|
90
|
+
v5 is the biggest shift yet. The build tool problem is solved. The new problem is encoding taste and standards so that AI tooling can extend your work faithfully. That's the mission now.
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
MIT
|
package/dist/index.d.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-starbase",
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"author": "Brian Staruk <brian@staruk.net>",
|
|
6
|
+
"contributors": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Brian Staruk",
|
|
9
|
+
"email": "brian@staruk.net",
|
|
10
|
+
"url": "https://brian.staruk.net"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"description": "Create a new Starbase project with Vite, TypeScript, and React.",
|
|
14
|
+
"homepage": "https://github.com/bstaruk/starbase",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/bstaruk/starbase.git"
|
|
18
|
+
},
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/bstaruk/starbase/issues",
|
|
21
|
+
"email": "brian@staruk.net"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"bin": {
|
|
26
|
+
"create-starbase": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"template"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"format": "prettier --write .",
|
|
35
|
+
"lint": "eslint .",
|
|
36
|
+
"start": "npm run build && node ./dist/index.js",
|
|
37
|
+
"prepare": "husky"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@commitlint/cli": "^20.4.1",
|
|
41
|
+
"@commitlint/config-conventional": "^20.4.1",
|
|
42
|
+
"@types/node": "^20.11.0",
|
|
43
|
+
"husky": "^9.1.7",
|
|
44
|
+
"lint-staged": "^16.2.7",
|
|
45
|
+
"prettier": "^3.8.1",
|
|
46
|
+
"typescript": "^5.3.0"
|
|
47
|
+
},
|
|
48
|
+
"lint-staged": {
|
|
49
|
+
"*.{js,jsx,ts,tsx,css,md,json}": "prettier --write"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=20"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Perform an audit of this codebase. Read CLAUDE.md first — it is the source of truth for all conventions, standards, and architectural decisions. Every finding should be measured against what's documented there.
|
|
2
|
+
|
|
3
|
+
Focus: $ARGUMENTS
|
|
4
|
+
|
|
5
|
+
If a focus was provided, narrow the audit to those areas. Otherwise, audit broadly across all conventions in CLAUDE.md — accessibility, component patterns, import conventions, color tokens, etc.
|
|
6
|
+
|
|
7
|
+
For each finding, report:
|
|
8
|
+
|
|
9
|
+
- What the issue is
|
|
10
|
+
- Which CLAUDE.md convention it violates (or which WCAG criterion, if accessibility-related)
|
|
11
|
+
- Where in the code it occurs (file and line)
|
|
12
|
+
- A recommended fix
|
|
13
|
+
|
|
14
|
+
Group findings by severity: critical, moderate, minor. If everything passes, say so.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Review the changes on the current branch compared to the base branch.
|
|
2
|
+
|
|
3
|
+
Base branch: $ARGUMENTS
|
|
4
|
+
|
|
5
|
+
If a base branch was provided, use it. Otherwise, default to `develop`.
|
|
6
|
+
|
|
7
|
+
Start by reading CLAUDE.md — it is the source of truth for all conventions and standards. Then run `git diff <base>...HEAD` to get the full diff of this branch.
|
|
8
|
+
|
|
9
|
+
Review every change against the conventions in CLAUDE.md. Check for:
|
|
10
|
+
|
|
11
|
+
- Violations of documented patterns (imports, component structure, utils organization, etc.)
|
|
12
|
+
- Accessibility regressions (WCAG 2.2 AA)
|
|
13
|
+
- Correctness and potential bugs
|
|
14
|
+
- Anything that contradicts the project's stated opinions
|
|
15
|
+
|
|
16
|
+
For each finding, report:
|
|
17
|
+
|
|
18
|
+
- What the issue is
|
|
19
|
+
- Which convention or standard it violates
|
|
20
|
+
- The file and line
|
|
21
|
+
- A recommended fix
|
|
22
|
+
|
|
23
|
+
If everything looks good, say so. Keep the review focused on what actually changed — don't audit the entire codebase, just the diff.
|
package/template/.env
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VITE_DEVTOOLS=false
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VITE_DEVTOOLS=true
|
package/template/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
v24
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Format w/ prettier on save
|
|
3
|
+
"editor.formatOnSave": true,
|
|
4
|
+
|
|
5
|
+
// Prefer path aliases over relative imports
|
|
6
|
+
"typescript.preferences.importModuleSpecifier": "non-relative",
|
|
7
|
+
"javascript.preferences.importModuleSpecifier": "non-relative",
|
|
8
|
+
|
|
9
|
+
// Defer JS linting to ESLint Extension
|
|
10
|
+
"eslint.validate": [
|
|
11
|
+
"javascript",
|
|
12
|
+
"typescript",
|
|
13
|
+
"javascriptreact",
|
|
14
|
+
"typescriptreact"
|
|
15
|
+
],
|
|
16
|
+
|
|
17
|
+
"files.associations": {
|
|
18
|
+
"*.css": "tailwindcss"
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
// Fix-all ESLint on save
|
|
22
|
+
"editor.codeActionsOnSave": {
|
|
23
|
+
"source.fixAll.eslint": "explicit"
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
// Tailwind CSS IntelliSense settings
|
|
27
|
+
"tailwindCSS.experimental.classRegex": [
|
|
28
|
+
["cn\\(([^)]*)\\)", "(?:'|\"|`)([^\"'`]*)(?:'|\"|`)"]
|
|
29
|
+
],
|
|
30
|
+
|
|
31
|
+
// Replace "index.tsx" with "Component" for "Component/index.tsx" in editor tabs
|
|
32
|
+
"workbench.editor.customLabels.enabled": true,
|
|
33
|
+
"workbench.editor.customLabels.patterns": {
|
|
34
|
+
"**/index.ts": "${dirname}",
|
|
35
|
+
"**/index.tsx": "${dirname}"
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
// TanStack Router autogen files
|
|
39
|
+
"files.readonlyInclude": {
|
|
40
|
+
"**/routeTree.gen.ts": true
|
|
41
|
+
},
|
|
42
|
+
"files.watcherExclude": {
|
|
43
|
+
"**/routeTree.gen.ts": true
|
|
44
|
+
},
|
|
45
|
+
"search.exclude": {
|
|
46
|
+
"**/routeTree.gen.ts": true
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
> _"Simplicity is the ultimate sophistication."_
|
|
4
|
+
|
|
5
|
+
Starbase is a personal, opinionated boilerplate — it reflects deliberately chosen tools, patterns, and workflows. Decisions should favor informed preference over broad appeal. When in doubt, optimize for productivity and consistency with the existing stack, not generality. That said, preference never trumps code quality — clean, correct, well-structured code wins every time. Opinion only applies when the choice is genuinely a matter of taste.
|
|
6
|
+
|
|
7
|
+
This file captures conventions, patterns, and lessons learned from working on this project. It is meant to evolve — when we discover a useful pattern or convention worth preserving, suggest adding it here.
|
|
8
|
+
|
|
9
|
+
## Accessibility
|
|
10
|
+
|
|
11
|
+
Inclusivity and accessibility are more important than any other aspect of the user experience. Unstyled, semantic HTML that works for everyone is better than a polished UI that excludes people.
|
|
12
|
+
|
|
13
|
+
- Target **WCAG 2.2 AA** compliance as the baseline for all work
|
|
14
|
+
- Use semantic HTML elements — prefer native behavior over custom JS (e.g., `<button>` over `<div onClick>`, `<nav>` over `<div class="nav">`)
|
|
15
|
+
- All interactive elements must be keyboard-accessible and have visible focus indicators
|
|
16
|
+
- Images need meaningful `alt` text (or `alt=""` for purely decorative images)
|
|
17
|
+
- Color alone must never be the only way to convey information — pair it with text, icons, or patterns
|
|
18
|
+
- Ensure sufficient color contrast ratios (4.5:1 for normal text, 3:1 for large text)
|
|
19
|
+
- Test with screen readers when building new interactive patterns
|
|
20
|
+
- When in doubt between a flashy feature and an accessible one, choose accessible
|
|
21
|
+
|
|
22
|
+
## Import Conventions
|
|
23
|
+
|
|
24
|
+
- **Always use aliased paths** — never relative imports
|
|
25
|
+
- `from 'utils'` not `from '../../lib/utils/darkMode'`
|
|
26
|
+
- `from 'atoms/Button'` not `from '../ui/atoms/Button'`
|
|
27
|
+
- If a relative path seems necessary, that means a new alias is needed — update both `tsconfig.app.json` `paths` and `vite.config.ts` `resolve.alias`
|
|
28
|
+
- See `tsconfig.app.json` `paths` for the current list of aliases
|
|
29
|
+
|
|
30
|
+
## Utils Organization
|
|
31
|
+
|
|
32
|
+
- All utils live in `src/lib/utils/` as individual files (e.g., `cn.ts`, `darkMode.ts`)
|
|
33
|
+
- Every util must be re-exported from `src/lib/utils/index.ts` so consumers import from `'utils'`
|
|
34
|
+
- Single-export utils use `export * from './cn'` (flat import: `import { cn } from 'utils'`)
|
|
35
|
+
- Multi-function utils use `export * as darkMode from './darkMode'` (namespaced import: `import { darkMode } from 'utils'`, then `darkMode.applyTheme()`)
|
|
36
|
+
- Pattern: create the file, add the re-export to `index.ts`, import via `'utils'`
|
|
37
|
+
|
|
38
|
+
## Queries Organization
|
|
39
|
+
|
|
40
|
+
All query/mutation options live in `src/lib/queries/`, organized by API domain — one file per domain (e.g., `github.ts`, `users.ts`, `products.ts`).
|
|
41
|
+
|
|
42
|
+
- Every domain file must be re-exported from `src/lib/queries/index.ts` as a namespace: `export * as github from './github'`
|
|
43
|
+
- Consumers import via the `'queries'` alias: `import { github } from 'queries'`, then `github.repoQueryOptions()`
|
|
44
|
+
- Domain files group all related concerns: query options, mutation options, and associated types
|
|
45
|
+
- One file per API domain/data source, not one file per query — this is what keeps the structure scalable
|
|
46
|
+
- Pattern: create the domain file, add the namespaced re-export to `index.ts`, import via `'queries'`
|
|
47
|
+
|
|
48
|
+
### Barrel Export Rules (applies to both utils and queries)
|
|
49
|
+
|
|
50
|
+
The re-export pattern depends on the content of the file:
|
|
51
|
+
|
|
52
|
+
- **Single-export files** → flat: `export * from './cn'` (import as `{ cn }`)
|
|
53
|
+
- **Multi-export domain files** → namespaced: `export * as github from './github'` (import as `{ github }`, then `github.thing()`)
|
|
54
|
+
|
|
55
|
+
Query domain files are always multi-export, so they always use namespaced re-exports.
|
|
56
|
+
|
|
57
|
+
## Component Patterns
|
|
58
|
+
|
|
59
|
+
Components follow [Atomic Design](https://atomicdesign.bradfrost.com/chapter-2/) and live in `src/ui/`:
|
|
60
|
+
|
|
61
|
+
- **Atoms** (`atoms/`) — Smallest building blocks that can't be broken down further without losing meaning. HTML-level primitives: buttons, inputs, labels, links, icons. Each has its own distinct properties (size variants, color, font) but no dependency on other custom components.
|
|
62
|
+
- **Molecules** (`molecules/`) — Small groups of atoms functioning together as a single unit. A search form (label + input + button), a labeled toggle, a stat with an icon. Each molecule does one thing well — single responsibility.
|
|
63
|
+
- **Organisms** (`organisms/`) — Larger, distinct sections composed of molecules, atoms, or other organisms. A site header (logo + nav + search), a product grid, a comment thread. Organisms provide context — they show how smaller pieces work together in a meaningful section.
|
|
64
|
+
- **Templates** (`templates/`) — Page-level layout structures that arrange organisms and molecules into a content hierarchy. Focus is on spatial arrangement and content slots, not final content. Defines where things go and how they relate.
|
|
65
|
+
|
|
66
|
+
Reference: [Atomic Design by Brad Frost](https://atomicdesign.bradfrost.com/table-of-contents/)
|
|
67
|
+
|
|
68
|
+
- Theme prefix: `sb-` (starbase) for all color tokens
|
|
69
|
+
|
|
70
|
+
## Libraries
|
|
71
|
+
|
|
72
|
+
Preferred libraries already in the project — reach for these before writing custom solutions or adding alternatives:
|
|
73
|
+
|
|
74
|
+
- **js-cookie** — Cookie read/write
|
|
75
|
+
- **usehooks-ts** — Common React hooks (prefer over writing custom hooks when a suitable one exists)
|
|
76
|
+
- **clsx** + **tailwind-merge** (via `cn()`) — Conditional/merged class names
|
|
77
|
+
- **react-icons** — Icon sets (currently using `react-icons/lu` for Lucide icons)
|
|
78
|
+
- **@tanstack/react-query** — Server state / data fetching
|
|
79
|
+
- **@tanstack/react-router** — Routing
|
|
80
|
+
- **motion** — Animation (import from `motion/react`)
|
|
81
|
+
|
|
82
|
+
See `package.json` for the full dependency list.
|
|
83
|
+
|
|
84
|
+
When adding a new library, always do a fresh web search for the latest docs, changelog, and community status. Do not rely on cached or training data — APIs change, packages get deprecated, and better alternatives emerge.
|
|
85
|
+
|
|
86
|
+
## Color Token System
|
|
87
|
+
|
|
88
|
+
- CSS variables defined in `src/lib/theme/tailwind.css`
|
|
89
|
+
- Dark mode: `.dark` class on `<html>`, with flash-prevention script in `index.html`
|
|
90
|
+
- Cookie: `theme-preference` with values `light`, `dark`, or absent (system default)
|
|
91
|
+
|
|
92
|
+
## Writing Style
|
|
93
|
+
|
|
94
|
+
- Never reference conversations, past edits, or memories in code comments, commit messages, or documentation
|
|
95
|
+
- Keep everything matter-of-fact and readable for any future developer
|
|
96
|
+
- No "as we discussed", "per our earlier change", or similar phrasing
|
|
97
|
+
|
|
98
|
+
## Git
|
|
99
|
+
|
|
100
|
+
- **Never commit, push, or run destructive git commands** — read-only git operations (diff, status, log, etc.) are fine
|
|
101
|
+
- After every code change, provide a [Conventional Commit](https://www.conventionalcommits.org/) message ready to copy+paste
|
|
102
|
+
- Format: `type(scope): description` — e.g., `feat(ui): add dark mode toggle atom`
|
|
103
|
+
- Common types: `feat`, `fix`, `chore`, `style`, `refactor`, `docs`, `test`
|
|
104
|
+
- Keep the description concise and lowercase
|
|
105
|
+
|
|
106
|
+
## Working Together
|
|
107
|
+
|
|
108
|
+
- This file is a living document — suggest additions when we land on a convention worth preserving
|
|
109
|
+
- Goal is to fine-tune how we collaborate over time so good patterns stick
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Starbase
|
|
2
|
+
|
|
3
|
+
Welcome aboard. Here's what you need to know.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
| Command | Description |
|
|
8
|
+
| ----------------- | ------------------------------------ |
|
|
9
|
+
| `npm run dev` | Start the Vite dev server |
|
|
10
|
+
| `npm run build` | Type-check and build for production |
|
|
11
|
+
| `npm run preview` | Preview the production build locally |
|
|
12
|
+
| `npm run lint` | Run ESLint |
|
|
13
|
+
| `npm run format` | Run Prettier |
|
|
14
|
+
|
|
15
|
+
## Project structure
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
src/
|
|
19
|
+
lib/
|
|
20
|
+
queries/ # React Query options, organized by API domain
|
|
21
|
+
theme/ # Tailwind CSS and theme config
|
|
22
|
+
utils/ # Utility functions (cn, darkMode, etc.)
|
|
23
|
+
ui/
|
|
24
|
+
atoms/ # Smallest building blocks (Button, Link, Code)
|
|
25
|
+
molecules/ # Functional groups of atoms (DarkModeToggle, PageHeader)
|
|
26
|
+
organisms/ # Larger composed sections
|
|
27
|
+
templates/ # Page-level layout structures
|
|
28
|
+
routes/ # TanStack Router file-based routes
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Components follow [Atomic Design](https://atomicdesign.bradfrost.com/chapter-2/). Imports use path aliases -- `from 'atoms/Button'`, not relative paths.
|
|
32
|
+
|
|
33
|
+
## CLAUDE.md
|
|
34
|
+
|
|
35
|
+
Start here. It's the source of truth for all conventions, patterns, and architectural decisions. It's also what makes [Claude Code](https://docs.anthropic.com/en/docs/claude-code) work well with this project -- read it, build on it, evolve it.
|
|
36
|
+
|
|
37
|
+
## Claude Code commands
|
|
38
|
+
|
|
39
|
+
- **`/audit`** -- Scan the codebase for drift against CLAUDE.md conventions
|
|
40
|
+
- **`/review`** -- Review current branch changes against CLAUDE.md
|
|
41
|
+
|
|
42
|
+
## Learn more
|
|
43
|
+
|
|
44
|
+
- [Starbase on GitHub](https://github.com/bstaruk/starbase) -- full docs, history, and mission
|
|
45
|
+
- [Atomic Design](https://atomicdesign.bradfrost.com/chapter-2/) -- the component methodology
|
|
46
|
+
- [Claude Code docs](https://docs.anthropic.com/en/docs/claude-code) -- getting the most out of the AI workflow
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import globals from 'globals';
|
|
3
|
+
import reactDom from 'eslint-plugin-react-dom';
|
|
4
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
5
|
+
import reactRefresh from 'eslint-plugin-react-refresh';
|
|
6
|
+
import reactX from 'eslint-plugin-react-x';
|
|
7
|
+
import tseslint from 'typescript-eslint';
|
|
8
|
+
import { defineConfig, globalIgnores } from 'eslint/config';
|
|
9
|
+
|
|
10
|
+
export default defineConfig([
|
|
11
|
+
globalIgnores(['dist', 'src/routeTree.gen.ts']),
|
|
12
|
+
{
|
|
13
|
+
files: ['**/*.{ts,tsx}'],
|
|
14
|
+
extends: [
|
|
15
|
+
js.configs.recommended,
|
|
16
|
+
tseslint.configs.recommended,
|
|
17
|
+
reactX.configs['recommended-typescript'],
|
|
18
|
+
reactDom.configs.recommended,
|
|
19
|
+
reactHooks.configs.flat.recommended,
|
|
20
|
+
reactRefresh.configs.vite,
|
|
21
|
+
],
|
|
22
|
+
languageOptions: {
|
|
23
|
+
ecmaVersion: 2020,
|
|
24
|
+
globals: globals.browser,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
]);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" style="background-color: #f5f5f4">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Starbase</title>
|
|
8
|
+
<script>
|
|
9
|
+
// Inline script to prevent dark mode flash
|
|
10
|
+
(function () {
|
|
11
|
+
const COOKIE_NAME = 'theme-preference';
|
|
12
|
+
const DARK_CLASS = 'dark';
|
|
13
|
+
|
|
14
|
+
// Get theme preference from cookie
|
|
15
|
+
const getCookie = (name) => {
|
|
16
|
+
const cookie = document.cookie
|
|
17
|
+
.split('; ')
|
|
18
|
+
.find((row) => row.startsWith(name + '='));
|
|
19
|
+
return cookie ? cookie.split('=')[1] : null;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const preference = getCookie(COOKIE_NAME) || 'system';
|
|
23
|
+
|
|
24
|
+
// Determine effective theme (default is light)
|
|
25
|
+
let theme = 'light';
|
|
26
|
+
if (preference === 'dark') {
|
|
27
|
+
theme = 'dark';
|
|
28
|
+
} else if (preference === 'system') {
|
|
29
|
+
theme = window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
30
|
+
? 'dark'
|
|
31
|
+
: 'light';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Apply dark class only if dark mode
|
|
35
|
+
if (theme === 'dark') {
|
|
36
|
+
document.documentElement.classList.add(DARK_CLASS);
|
|
37
|
+
document.documentElement.style.backgroundColor = '#09090b';
|
|
38
|
+
}
|
|
39
|
+
})();
|
|
40
|
+
</script>
|
|
41
|
+
</head>
|
|
42
|
+
|
|
43
|
+
<body>
|
|
44
|
+
<div id="root"></div>
|
|
45
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "template",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc -b && vite build",
|
|
9
|
+
"format": "prettier --write .",
|
|
10
|
+
"lint": "eslint .",
|
|
11
|
+
"preview": "vite preview"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@fontsource/bricolage-grotesque": "^5.2.10",
|
|
15
|
+
"@fontsource/nunito": "^5.2.7",
|
|
16
|
+
"@fontsource/roboto-mono": "^5.2.8",
|
|
17
|
+
"@tanstack/react-query": "^5.90.20",
|
|
18
|
+
"@tanstack/react-query-devtools": "^5.91.3",
|
|
19
|
+
"@tanstack/react-router": "^1.158.1",
|
|
20
|
+
"@tanstack/react-router-devtools": "^1.158.1",
|
|
21
|
+
"clsx": "^2.1.1",
|
|
22
|
+
"js-cookie": "^3.0.5",
|
|
23
|
+
"motion": "^12.33.0",
|
|
24
|
+
"react": "^19.2.0",
|
|
25
|
+
"react-dom": "^19.2.0",
|
|
26
|
+
"react-icons": "^5.5.0",
|
|
27
|
+
"tailwind-merge": "^3.4.0",
|
|
28
|
+
"usehooks-ts": "^3.1.1"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@eslint/js": "^9.39.1",
|
|
32
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
33
|
+
"@tanstack/router-plugin": "^1.158.1",
|
|
34
|
+
"@types/js-cookie": "^3.0.6",
|
|
35
|
+
"@types/node": "^24.10.1",
|
|
36
|
+
"@types/react": "^19.2.5",
|
|
37
|
+
"@types/react-dom": "^19.2.3",
|
|
38
|
+
"@vitejs/plugin-react": "^5.1.1",
|
|
39
|
+
"eslint": "^9.39.1",
|
|
40
|
+
"eslint-plugin-react-dom": "^2.11.0",
|
|
41
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
42
|
+
"eslint-plugin-react-refresh": "^0.4.24",
|
|
43
|
+
"eslint-plugin-react-x": "^2.11.0",
|
|
44
|
+
"globals": "^16.5.0",
|
|
45
|
+
"prettier": "^3.8.1",
|
|
46
|
+
"tailwindcss": "^4.1.18",
|
|
47
|
+
"typescript": "~5.9.3",
|
|
48
|
+
"typescript-eslint": "^8.46.4",
|
|
49
|
+
"vite": "^7.2.4"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { queryOptions } from '@tanstack/react-query';
|
|
2
|
+
|
|
3
|
+
export function starbaseRepoQueryOptions() {
|
|
4
|
+
return queryOptions({
|
|
5
|
+
queryKey: ['github', 'repos', 'bstaruk', 'starbase'],
|
|
6
|
+
queryFn: async () => {
|
|
7
|
+
const res = await fetch('https://api.github.com/repos/bstaruk/starbase');
|
|
8
|
+
if (!res.ok) throw new Error('Failed to fetch repo data');
|
|
9
|
+
return res.json() as Promise<{ stargazers_count: number }>;
|
|
10
|
+
},
|
|
11
|
+
staleTime: 5 * 60 * 1000,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as github from './github';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
@layer base {
|
|
2
|
+
html {
|
|
3
|
+
scrollbar-gutter: stable;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
body {
|
|
7
|
+
@apply font-sans text-base underline-offset-4 bg-sb-surface text-sb-fg;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
h1,
|
|
11
|
+
h2,
|
|
12
|
+
h3,
|
|
13
|
+
h4,
|
|
14
|
+
h5 {
|
|
15
|
+
@apply font-display font-medium;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
h1 {
|
|
19
|
+
@apply text-h1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
h2 {
|
|
23
|
+
@apply text-h2;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
h3 {
|
|
27
|
+
@apply text-h3;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
h4 {
|
|
31
|
+
@apply text-h4;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
h5 {
|
|
35
|
+
@apply text-h5;
|
|
36
|
+
}
|
|
37
|
+
}
|