@farm.js/create-app 0.1.0-beta.7 → 0.1.0-beta.71

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 (173) hide show
  1. package/README.md +38 -6
  2. package/bin/create-farm-app.js +7 -2
  3. package/dist/index.js +3298 -16
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +3294 -14
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/utils.js +9 -6
  8. package/dist/utils.js.map +1 -1
  9. package/dist/utils.mjs +9 -6
  10. package/dist/utils.mjs.map +1 -1
  11. package/package.json +2 -2
  12. package/templates/_integrations/better-auth/preact/farm.config.ts +17 -0
  13. package/templates/_integrations/better-auth/preact/src/app/dashboard/page.tsx +73 -0
  14. package/templates/_integrations/better-auth/preact/src/app/layout.tsx +14 -0
  15. package/templates/_integrations/better-auth/preact/src/app/page.tsx +36 -0
  16. package/templates/_integrations/better-auth/preact/src/app/sign-in/page.tsx +10 -0
  17. package/templates/_integrations/better-auth/preact/src/app/sign-up/page.tsx +10 -0
  18. package/templates/_integrations/better-auth/preact/src/components/auth-form.tsx +92 -0
  19. package/templates/_integrations/better-auth/preact/src/components/auth-shell.tsx +16 -0
  20. package/templates/_integrations/better-auth/preact/src/lib/auth-client.ts +5 -0
  21. package/templates/_integrations/better-auth/solid/farm.config.ts +17 -0
  22. package/templates/_integrations/better-auth/solid/src/app/dashboard/page.tsx +67 -0
  23. package/templates/_integrations/better-auth/solid/src/app/layout.tsx +14 -0
  24. package/templates/_integrations/better-auth/solid/src/app/page.tsx +36 -0
  25. package/templates/_integrations/better-auth/solid/src/app/sign-in/page.tsx +10 -0
  26. package/templates/_integrations/better-auth/solid/src/app/sign-up/page.tsx +10 -0
  27. package/templates/_integrations/better-auth/solid/src/components/auth-form.tsx +91 -0
  28. package/templates/_integrations/better-auth/solid/src/components/auth-shell.tsx +16 -0
  29. package/templates/_integrations/better-auth/solid/src/lib/auth-client.ts +5 -0
  30. package/templates/_integrations/better-auth/svelte/farm.config.ts +17 -0
  31. package/templates/_integrations/better-auth/svelte/src/app/dashboard/page.svelte +62 -0
  32. package/templates/_integrations/better-auth/svelte/src/app/layout.svelte +20 -0
  33. package/templates/_integrations/better-auth/svelte/src/app/page.svelte +32 -0
  34. package/templates/_integrations/better-auth/svelte/src/app/sign-in/page.svelte +10 -0
  35. package/templates/_integrations/better-auth/svelte/src/app/sign-up/page.svelte +10 -0
  36. package/templates/_integrations/better-auth/svelte/src/components/auth-form.svelte +83 -0
  37. package/templates/_integrations/better-auth/svelte/src/components/auth-shell.svelte +16 -0
  38. package/templates/_integrations/better-auth/svelte/src/components/resource-links.svelte +47 -0
  39. package/templates/_integrations/better-auth/svelte/src/lib/auth-client.ts +5 -0
  40. package/templates/_integrations/better-auth/vue/farm.config.ts +17 -0
  41. package/templates/_integrations/better-auth/vue/src/app/dashboard/page.vue +62 -0
  42. package/templates/_integrations/better-auth/vue/src/app/layout.vue +20 -0
  43. package/templates/_integrations/better-auth/vue/src/app/page.vue +34 -0
  44. package/templates/_integrations/better-auth/vue/src/app/sign-in/page.vue +12 -0
  45. package/templates/_integrations/better-auth/vue/src/app/sign-up/page.vue +12 -0
  46. package/templates/_integrations/better-auth/vue/src/components/auth-form.vue +86 -0
  47. package/templates/_integrations/better-auth/vue/src/components/auth-shell.vue +15 -0
  48. package/templates/_integrations/better-auth/vue/src/components/resource-links.vue +43 -0
  49. package/templates/_integrations/better-auth/vue/src/lib/auth-client.ts +5 -0
  50. package/templates/_renderers/preact/farm.config.ts +12 -0
  51. package/templates/_renderers/preact/package.json +26 -0
  52. package/templates/_renderers/preact/src/app/api/greeting/route.ts +15 -0
  53. package/templates/_renderers/preact/src/app/layout.tsx +16 -0
  54. package/templates/_renderers/preact/src/app/page.tsx +66 -0
  55. package/templates/_renderers/preact/src/app/preact.css +26 -0
  56. package/templates/_renderers/preact/src/components/resource-links.tsx +71 -0
  57. package/templates/_renderers/preact/src/lib/api-client.ts +4 -0
  58. package/templates/_renderers/preact/src/lib/api.generated.ts +7 -0
  59. package/templates/_renderers/preact/tsconfig.json +25 -0
  60. package/templates/_renderers/solid/farm.config.ts +12 -0
  61. package/templates/_renderers/solid/package.json +25 -0
  62. package/templates/_renderers/solid/src/app/api/greeting/route.ts +15 -0
  63. package/templates/_renderers/solid/src/app/layout.tsx +15 -0
  64. package/templates/_renderers/solid/src/app/page.tsx +56 -0
  65. package/templates/_renderers/solid/src/app/solid.css +22 -0
  66. package/templates/_renderers/solid/src/components/resource-links.tsx +71 -0
  67. package/templates/_renderers/solid/src/lib/api-client.ts +4 -0
  68. package/templates/_renderers/solid/src/lib/api.generated.ts +7 -0
  69. package/templates/_renderers/solid/tsconfig.json +25 -0
  70. package/templates/_renderers/svelte/farm.config.ts +9 -0
  71. package/templates/_renderers/svelte/package.json +28 -0
  72. package/templates/_renderers/svelte/src/app/api/greeting/route.ts +15 -0
  73. package/templates/_renderers/svelte/src/app/layout.svelte +21 -0
  74. package/templates/_renderers/svelte/src/app/page.svelte +64 -0
  75. package/templates/_renderers/svelte/src/app/svelte.css +26 -0
  76. package/templates/_renderers/svelte/src/components/resource-links.svelte +31 -0
  77. package/templates/_renderers/svelte/src/lib/api-client.ts +4 -0
  78. package/templates/_renderers/svelte/src/lib/api.generated.ts +7 -0
  79. package/templates/_renderers/svelte/tsconfig.json +23 -0
  80. package/templates/_renderers/vue/farm.config.ts +12 -0
  81. package/templates/_renderers/vue/package.json +26 -0
  82. package/templates/_renderers/vue/src/app/api/greeting/route.ts +15 -0
  83. package/templates/_renderers/vue/src/app/layout.vue +21 -0
  84. package/templates/_renderers/vue/src/app/page.vue +69 -0
  85. package/templates/_renderers/vue/src/app/vue.css +26 -0
  86. package/templates/_renderers/vue/src/components/resource-links.vue +33 -0
  87. package/templates/_renderers/vue/src/env.d.ts +7 -0
  88. package/templates/_renderers/vue/src/lib/api-client.ts +4 -0
  89. package/templates/_renderers/vue/src/lib/api.generated.ts +7 -0
  90. package/templates/_renderers/vue/tsconfig.json +23 -0
  91. package/templates/auth/.env.example +6 -0
  92. package/templates/auth/README.md +95 -0
  93. package/templates/auth/docs.config.ts +33 -0
  94. package/templates/auth/docs.json +36 -0
  95. package/templates/auth/farm.config.ts +20 -0
  96. package/templates/auth/gitignore +10 -0
  97. package/templates/auth/package.json +34 -0
  98. package/templates/auth/pnpm-workspace.yaml +13 -0
  99. package/templates/auth/src/app/dashboard/middleware.ts +13 -0
  100. package/templates/auth/src/app/dashboard/page.tsx +140 -0
  101. package/templates/auth/src/app/docs/page.md +29 -0
  102. package/templates/auth/src/app/error.tsx +25 -0
  103. package/templates/auth/src/app/globals.css +1064 -0
  104. package/templates/auth/src/app/layout.tsx +11 -0
  105. package/templates/auth/src/app/loading.tsx +15 -0
  106. package/templates/auth/src/app/not-found.tsx +26 -0
  107. package/templates/auth/src/app/page.tsx +46 -0
  108. package/templates/auth/src/app/sign-in/page.tsx +16 -0
  109. package/templates/auth/src/app/sign-up/page.tsx +16 -0
  110. package/templates/auth/src/components/auth-form.tsx +120 -0
  111. package/templates/auth/src/components/auth-shell.tsx +21 -0
  112. package/templates/auth/src/components/resource-links.tsx +78 -0
  113. package/templates/auth/src/components/sign-out-button.tsx +45 -0
  114. package/templates/auth/src/components/site-header.tsx +46 -0
  115. package/templates/auth/tsconfig.json +20 -0
  116. package/templates/basic/docs.config.ts +33 -0
  117. package/templates/basic/docs.json +36 -0
  118. package/templates/basic/farm.config.ts +9 -0
  119. package/templates/basic/package.json +7 -3
  120. package/templates/basic/pnpm-workspace.yaml +8 -0
  121. package/templates/basic/src/app/docs/page.md +29 -0
  122. package/templates/basic/src/app/globals.css +241 -0
  123. package/templates/basic/src/app/layout.tsx +3 -5
  124. package/templates/basic/src/app/page.tsx +20 -61
  125. package/templates/basic/src/components/resource-links.tsx +78 -0
  126. package/templates/basic/tsconfig.json +4 -0
  127. package/templates/better-auth/.env.example +3 -0
  128. package/templates/better-auth/README.md +89 -0
  129. package/templates/better-auth/docs.config.ts +33 -0
  130. package/templates/better-auth/docs.json +36 -0
  131. package/templates/better-auth/farm.config.ts +38 -0
  132. package/templates/better-auth/gitignore +10 -0
  133. package/templates/better-auth/package.json +36 -0
  134. package/templates/better-auth/pnpm-workspace.yaml +13 -0
  135. package/templates/better-auth/src/app/dashboard/middleware.ts +15 -0
  136. package/templates/better-auth/src/app/dashboard/page.tsx +188 -0
  137. package/templates/better-auth/src/app/docs/page.md +29 -0
  138. package/templates/better-auth/src/app/error.tsx +25 -0
  139. package/templates/better-auth/src/app/globals.css +1064 -0
  140. package/templates/better-auth/src/app/layout.tsx +11 -0
  141. package/templates/better-auth/src/app/loading.tsx +15 -0
  142. package/templates/better-auth/src/app/not-found.tsx +26 -0
  143. package/templates/better-auth/src/app/page.tsx +50 -0
  144. package/templates/better-auth/src/app/sign-in/page.tsx +16 -0
  145. package/templates/better-auth/src/app/sign-up/page.tsx +16 -0
  146. package/templates/better-auth/src/components/auth-form.tsx +120 -0
  147. package/templates/better-auth/src/components/auth-shell.tsx +21 -0
  148. package/templates/better-auth/src/components/resource-links.tsx +78 -0
  149. package/templates/better-auth/src/components/sign-out-button.tsx +45 -0
  150. package/templates/better-auth/src/components/site-header.tsx +46 -0
  151. package/templates/better-auth/src/lib/auth-client.ts +5 -0
  152. package/templates/better-auth/src/lib/auth.ts +50 -0
  153. package/templates/better-auth/src/lib/session.ts +8 -0
  154. package/templates/better-auth/tsconfig.json +20 -0
  155. package/templates/react-compiler/README.md +62 -0
  156. package/templates/react-compiler/docs.config.ts +33 -0
  157. package/templates/react-compiler/docs.json +36 -0
  158. package/templates/react-compiler/farm.config.ts +29 -0
  159. package/templates/react-compiler/gitignore +23 -0
  160. package/templates/react-compiler/package.json +34 -0
  161. package/templates/react-compiler/pnpm-workspace.yaml +8 -0
  162. package/templates/react-compiler/public/favicon.svg +5 -0
  163. package/templates/react-compiler/scripts/verify-experiment.mjs +113 -0
  164. package/templates/react-compiler/src/app/docs/page.md +29 -0
  165. package/templates/react-compiler/src/app/globals.css +470 -0
  166. package/templates/react-compiler/src/app/layout.tsx +22 -0
  167. package/templates/react-compiler/src/app/page.tsx +47 -0
  168. package/templates/react-compiler/src/components/compiler-comparison.tsx +93 -0
  169. package/templates/react-compiler/src/components/resource-links.tsx +78 -0
  170. package/templates/react-compiler/src/farm.d.ts +74 -0
  171. package/templates/react-compiler/src/lib/api.generated.ts +10 -0
  172. package/templates/react-compiler/tsconfig.json +24 -0
  173. package/templates/basic/src/app/about/page.tsx +0 -32
@@ -1 +1,242 @@
1
+ @import "@fontsource-variable/geist/wght.css";
2
+ @import "@fontsource-variable/geist-mono/wght.css";
1
3
  @import "tailwindcss";
4
+
5
+ :root {
6
+ --paper: #000000;
7
+ --paper-soft: #080808;
8
+ --ink: #f5f5f5;
9
+ --ink-soft: #a1a1a1;
10
+ --ink-faint: #686868;
11
+ --line: rgb(255 255 255 / 0.12);
12
+ --line-strong: rgb(255 255 255 / 0.22);
13
+ --focus: #ffffff;
14
+ --font-sans: "Geist Variable", ui-sans-serif, system-ui, sans-serif;
15
+ --font-mono: "Geist Mono Variable", ui-monospace, monospace;
16
+ color-scheme: dark;
17
+ color: var(--ink);
18
+ font-family: var(--font-sans);
19
+ font-synthesis: none;
20
+ }
21
+
22
+ * {
23
+ box-sizing: border-box;
24
+ }
25
+
26
+ html {
27
+ min-width: 320px;
28
+ min-height: 100%;
29
+ background: var(--paper);
30
+ }
31
+
32
+ body {
33
+ min-height: 100vh;
34
+ margin: 0;
35
+ background: var(--paper);
36
+ color: var(--ink);
37
+ font-family: var(--font-sans);
38
+ text-rendering: optimizeLegibility;
39
+ }
40
+
41
+ button,
42
+ input {
43
+ font: inherit;
44
+ }
45
+
46
+ a {
47
+ color: inherit;
48
+ text-decoration: none;
49
+ -webkit-tap-highlight-color: transparent;
50
+ }
51
+
52
+ code {
53
+ font-family: var(--font-mono);
54
+ }
55
+
56
+ ::selection {
57
+ background: white;
58
+ color: black;
59
+ }
60
+
61
+ :focus-visible {
62
+ outline: 2px solid var(--focus);
63
+ outline-offset: 3px;
64
+ }
65
+
66
+ .landing-main {
67
+ position: relative;
68
+ isolation: isolate;
69
+ width: 100%;
70
+ min-height: 100vh;
71
+ overflow: hidden;
72
+ background: var(--paper);
73
+ }
74
+
75
+ .hero-section {
76
+ position: relative;
77
+ display: flex;
78
+ width: 100%;
79
+ overflow: hidden;
80
+ min-height: 100vh;
81
+ align-items: center;
82
+ justify-content: flex-start;
83
+ padding: clamp(2rem, 6vh, 4rem) clamp(1.25rem, 7vw, 6rem);
84
+ }
85
+
86
+ .hero-section::before,
87
+ .hero-section::after {
88
+ position: absolute;
89
+ width: 9px;
90
+ height: 9px;
91
+ border-color: rgb(255 255 255 / 0.3);
92
+ content: "";
93
+ pointer-events: none;
94
+ }
95
+
96
+ .hero-section::before {
97
+ top: -1px;
98
+ left: -1px;
99
+ border-top: 1px solid;
100
+ border-left: 1px solid;
101
+ }
102
+
103
+ .hero-section::after {
104
+ right: 0;
105
+ bottom: -1px;
106
+ border-right: 1px solid;
107
+ border-bottom: 1px solid;
108
+ }
109
+
110
+ .hero-copy {
111
+ width: min(100%, 680px);
112
+ margin: 0;
113
+ }
114
+
115
+ .eyebrow-row {
116
+ display: flex;
117
+ align-items: center;
118
+ gap: 0.65rem;
119
+ color: var(--ink-faint);
120
+ font-family: var(--font-mono);
121
+ font-size: 0.67rem;
122
+ text-transform: uppercase;
123
+ }
124
+
125
+ .eyebrow-row span:first-child {
126
+ color: var(--ink);
127
+ }
128
+
129
+ .hero-copy h1 {
130
+ max-width: 620px;
131
+ margin: 1.4rem 0 0;
132
+ font-size: clamp(1.85rem, 4vw, 3.2rem);
133
+ font-weight: 510;
134
+ letter-spacing: -0.05em;
135
+ line-height: 1.05;
136
+ }
137
+
138
+ .hero-copy h1 code {
139
+ border: 1px solid var(--line);
140
+ background: rgb(255 255 255 / 0.07);
141
+ padding: 0.04em 0.2em;
142
+ font-size: 0.78em;
143
+ font-weight: 450;
144
+ letter-spacing: -0.035em;
145
+ white-space: nowrap;
146
+ }
147
+
148
+ .command-list {
149
+ max-width: 520px;
150
+ margin-top: 1.75rem;
151
+ border-block: 1px solid var(--line);
152
+ }
153
+
154
+ .command-row {
155
+ display: grid;
156
+ min-width: 0;
157
+ grid-template-columns: auto minmax(0, 1fr);
158
+ align-items: center;
159
+ gap: 0.8rem;
160
+ padding: 0.9rem 0;
161
+ }
162
+
163
+ .command-row + .command-row {
164
+ border-top: 1px solid var(--line);
165
+ }
166
+
167
+ .command-row > span {
168
+ color: var(--ink-faint);
169
+ font-family: var(--font-mono);
170
+ font-size: 0.62rem;
171
+ }
172
+
173
+ .command-row code {
174
+ color: var(--ink);
175
+ font-size: 0.75rem;
176
+ overflow-wrap: anywhere;
177
+ }
178
+
179
+ .resource-links {
180
+ display: flex;
181
+ flex-wrap: wrap;
182
+ gap: 0.65rem;
183
+ margin-top: 1.5rem;
184
+ color: var(--ink-soft);
185
+ font-family: var(--font-mono);
186
+ font-size: 0.68rem;
187
+ text-transform: uppercase;
188
+ }
189
+
190
+ .resource-link-item {
191
+ display: inline-flex;
192
+ align-items: center;
193
+ gap: 0.65rem;
194
+ white-space: nowrap;
195
+ }
196
+
197
+ .resource-separator {
198
+ color: var(--ink-faint);
199
+ user-select: none;
200
+ }
201
+
202
+ .resource-links a {
203
+ display: inline-flex;
204
+ align-items: center;
205
+ gap: 0.45rem;
206
+ border-bottom: 1px solid transparent;
207
+ padding-block: 0.2rem;
208
+ transition:
209
+ border-color 150ms ease,
210
+ color 150ms ease;
211
+ }
212
+
213
+ .resource-icon {
214
+ width: 0.85rem;
215
+ height: 0.85rem;
216
+ flex: 0 0 auto;
217
+ }
218
+
219
+ .resource-links a:hover {
220
+ border-color: currentColor;
221
+ color: var(--ink);
222
+ }
223
+
224
+ @media (max-width: 620px) {
225
+ .hero-section {
226
+ padding: 2rem 1.25rem;
227
+ }
228
+
229
+ .hero-copy h1 {
230
+ font-size: clamp(1.85rem, 9vw, 2.5rem);
231
+ overflow-wrap: anywhere;
232
+ }
233
+ }
234
+
235
+ @media (prefers-reduced-motion: reduce) {
236
+ *,
237
+ *::before,
238
+ *::after {
239
+ scroll-behavior: auto !important;
240
+ transition-duration: 0.01ms !important;
241
+ }
242
+ }
@@ -2,8 +2,8 @@ import type { LayoutProps, Metadata } from "@farm.js/core";
2
2
  import "./globals.css";
3
3
 
4
4
  export const metadata: Metadata = {
5
- title: "Farm.js App",
6
- description: "A modern React meta-framework built on Vite",
5
+ title: "FARMJS App",
6
+ description: "A framework for product-integrated apps",
7
7
  icons: {
8
8
  icon: [{ url: "/favicon.svg", type: "image/svg+xml", sizes: "any" }],
9
9
  },
@@ -16,9 +16,7 @@ export default function RootLayout({ children }: LayoutProps) {
16
16
  <meta charSet="utf-8" />
17
17
  <meta name="viewport" content="width=device-width, initial-scale=1" />
18
18
  </head>
19
- <body className="bg-gray-50 antialiased">
20
- <main className="min-h-screen">{children}</main>
21
- </body>
19
+ <body>{children}</body>
22
20
  </html>
23
21
  );
24
22
  }
@@ -1,70 +1,29 @@
1
- import { Link } from "@farm.js/core/client";
2
- import { FARM_VERSION } from "@farm.js/core/version";
1
+ import { ResourceLinks } from "../components/resource-links";
3
2
 
4
3
  export default function HomePage() {
5
4
  return (
6
- <div className="min-h-screen flex items-center justify-center p-8">
7
- <div className="max-w-4xl mx-auto text-center space-y-8">
8
- <div>
9
- <h1 className="text-6xl font-bold mb-4">
10
- <span className="bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
11
- 🚜 Welcome to Farm.js v{FARM_VERSION}
12
- </span>
13
- </h1>
14
-
15
- <p className="text-xl text-gray-600 max-w-2xl mx-auto">
16
- A modern React meta-framework built on Vite with Next.js-like semantics
17
- </p>
18
- </div>
5
+ <main className="landing-main">
6
+ <section className="hero-section">
7
+ <div className="hero-copy">
8
+ <div className="eyebrow-row">
9
+ <span>00</span>
10
+ <span>FARMJS / Basic starter</span>
11
+ </div>
19
12
 
20
- <div className="flex gap-4 justify-center flex-wrap">
21
- <Link
22
- href="/about"
23
- className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium shadow-md hover:shadow-lg"
24
- >
25
- About Page
26
- </Link>
13
+ <h1>
14
+ Edit <code>page.tsx</code> to begin.
15
+ </h1>
27
16
 
28
- <a
29
- href="https://farm.js.dev"
30
- target="_blank"
31
- rel="noopener noreferrer"
32
- className="px-6 py-3 border-2 border-blue-600 text-blue-600 rounded-lg hover:bg-blue-50 transition-colors font-medium"
33
- >
34
- Documentation
35
- </a>
36
- </div>
17
+ <div className="command-list" aria-label="Development command">
18
+ <div className="command-row">
19
+ <span>01</span>
20
+ <code>pnpm dev</code>
21
+ </div>
22
+ </div>
37
23
 
38
- <div className="bg-white rounded-lg shadow-xl p-8 text-left">
39
- <h2 className="text-2xl font-bold mb-6 text-gray-900">Features</h2>
40
- <ul className="space-y-3">
41
- <li className="flex items-start gap-3">
42
- <span className="text-2xl">🚀</span>
43
- <span className="text-gray-700">Blazing fast development with Vite</span>
44
- </li>
45
- <li className="flex items-start gap-3">
46
- <span className="text-2xl">⚛️</span>
47
- <span className="text-gray-700">React Server Components support</span>
48
- </li>
49
- <li className="flex items-start gap-3">
50
- <span className="text-2xl">🎯</span>
51
- <span className="text-gray-700">Next.js-like file-based routing</span>
52
- </li>
53
- <li className="flex items-start gap-3">
54
- <span className="text-2xl">🎨</span>
55
- <span className="text-gray-700">Tailwind CSS built-in</span>
56
- </li>
57
- <li className="flex items-start gap-3">
58
- <span className="text-2xl">📦</span>
59
- <span className="text-gray-700">Zero configuration setup</span>
60
- </li>
61
- <li className="flex items-start gap-3">
62
- <span className="text-2xl">🧪</span>
63
- <span className="text-gray-700">AI-friendly code structure</span>
64
- </li>
65
- </ul>
24
+ <ResourceLinks className="resource-links" />
66
25
  </div>
67
- </div>
68
- </div>
26
+ </section>
27
+ </main>
69
28
  );
70
29
  }
@@ -0,0 +1,78 @@
1
+ interface ResourceLinkAction {
2
+ href: string;
3
+ label: string;
4
+ }
5
+
6
+ interface ResourceLinksProps {
7
+ className: string;
8
+ primary?: ResourceLinkAction;
9
+ }
10
+
11
+ function DocsIcon() {
12
+ return (
13
+ <svg
14
+ className="resource-icon"
15
+ viewBox="0 0 24 24"
16
+ fill="none"
17
+ stroke="currentColor"
18
+ strokeWidth="1.8"
19
+ strokeLinecap="round"
20
+ strokeLinejoin="round"
21
+ aria-hidden="true"
22
+ focusable="false"
23
+ >
24
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" />
25
+ <path d="M14 2v6h6M8 13h8M8 17h6" />
26
+ </svg>
27
+ );
28
+ }
29
+
30
+ function GitHubIcon() {
31
+ return (
32
+ <svg
33
+ className="resource-icon"
34
+ viewBox="0 0 24 24"
35
+ fill="currentColor"
36
+ aria-hidden="true"
37
+ focusable="false"
38
+ >
39
+ <path d="M12 .7a11.5 11.5 0 0 0-3.64 22.41c.58.1.79-.25.79-.56v-2.23c-3.22.7-3.9-1.37-3.9-1.37-.52-1.34-1.28-1.69-1.28-1.69-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.7 1.26 3.36.96.1-.75.4-1.26.73-1.55-2.57-.29-5.27-1.29-5.27-5.68 0-1.26.45-2.28 1.18-3.09-.12-.29-.51-1.47.11-3.05 0 0 .96-.31 3.16 1.18A10.95 10.95 0 0 1 12 6.1c.98 0 1.95.13 2.87.39 2.2-1.49 3.16-1.18 3.16-1.18.62 1.58.23 2.76.11 3.05.74.81 1.18 1.83 1.18 3.09 0 4.4-2.71 5.38-5.29 5.67.42.36.79 1.07.79 2.16v3.27c0 .31.21.67.8.56A11.5 11.5 0 0 0 12 .7Z" />
40
+ </svg>
41
+ );
42
+ }
43
+
44
+ function ResourceSeparator() {
45
+ return (
46
+ <span className="resource-separator" aria-hidden="true">
47
+ /
48
+ </span>
49
+ );
50
+ }
51
+
52
+ export function ResourceLinks({ className, primary }: ResourceLinksProps) {
53
+ return (
54
+ <nav className={className} aria-label="Starter resources">
55
+ {primary ? (
56
+ <span className="resource-link-item">
57
+ <a className="resource-link-primary" href={primary.href}>
58
+ {primary.label}
59
+ </a>
60
+ </span>
61
+ ) : null}
62
+ <span className="resource-link-item">
63
+ {primary ? <ResourceSeparator /> : null}
64
+ <a href="https://farm.js.dev">
65
+ <DocsIcon />
66
+ <span>Docs</span>
67
+ </a>
68
+ </span>
69
+ <span className="resource-link-item">
70
+ <ResourceSeparator />
71
+ <a href="https://github.com/farming-labs/farm.js">
72
+ <GitHubIcon />
73
+ <span>GitHub</span>
74
+ </a>
75
+ </span>
76
+ </nav>
77
+ );
78
+ }
@@ -6,6 +6,10 @@
6
6
  "module": "ESNext",
7
7
  "skipLibCheck": true,
8
8
  "moduleResolution": "bundler",
9
+ "baseUrl": ".",
10
+ "paths": {
11
+ "@/*": ["./src/*"]
12
+ },
9
13
  "allowImportingTsExtensions": true,
10
14
  "resolveJsonModule": true,
11
15
  "isolatedModules": true,
@@ -0,0 +1,3 @@
1
+ BETTER_AUTH_URL=http://localhost:3000
2
+ BETTER_AUTH_SECRET=replace-with-a-random-secret-at-least-32-characters
3
+ DATABASE_URL=postgresql://user:password@your-neon-pooler-host/database?sslmode=require
@@ -0,0 +1,89 @@
1
+ # FARMJS Better Auth Starter
2
+
3
+ A standalone authentication starter built with FARMJS, Better Auth, your selected UI renderer,
4
+ and Neon Postgres.
5
+
6
+ This project was generated from the Better Auth template included with `@farm.js/create-app`.
7
+
8
+ ## Included
9
+
10
+ - email and password sign-up and sign-in
11
+ - Better Auth session cookies
12
+ - a server-middleware-protected `/dashboard`
13
+ - pooled Postgres persistence and automatic Better Auth migrations
14
+ - a dark-first, one-page welcome screen set in Geist Sans and Geist Mono
15
+ - pending, error, unauthorized, loading, and not-found states
16
+ - responsive starter UI
17
+ - exact FARMJS beta dependencies for reproducible installs
18
+
19
+ ## Quick start
20
+
21
+ ```bash
22
+ pnpm create @farm.js/app@beta my-app --template better-auth --renderer solid --typescript
23
+ cd my-app
24
+ cp .env.example .env.local
25
+ ```
26
+
27
+ Generate a secret and place it in `BETTER_AUTH_SECRET`:
28
+
29
+ ```bash
30
+ openssl rand -base64 32
31
+ ```
32
+
33
+ Then install and start the app:
34
+
35
+ ```bash
36
+ pnpm install
37
+ pnpm dev
38
+ ```
39
+
40
+ Open [http://localhost:3000](http://localhost:3000), create an account, and continue to the protected dashboard.
41
+
42
+ ## How it is wired
43
+
44
+ - [`src/lib/auth.ts`](./src/lib/auth.ts) creates the Better Auth instance, configures the pooled
45
+ Postgres connection, and runs programmatic migrations.
46
+ - [`farm.config.ts`](./farm.config.ts) mounts that instance through `@farm.js/better-auth`.
47
+ - [`src/lib/auth-client.ts`](./src/lib/auth-client.ts) exposes the browser client.
48
+ - [`src/lib/session.ts`](./src/lib/session.ts) resolves the current request session on the server.
49
+ - [`src/app/dashboard/middleware.ts`](./src/app/dashboard/middleware.ts) redirects unauthenticated requests before the dashboard route runs.
50
+ - `src/app/dashboard/page.*` reads the already-authorized session and renders the account UI in the
51
+ selected renderer.
52
+
53
+ FARMJS owns the catch-all integration route, so the starter does not need a manual API route:
54
+
55
+ ```text
56
+ /api/auth/[...auth]
57
+ ```
58
+
59
+ ## Environment
60
+
61
+ | Variable | Purpose |
62
+ | -------------------- | ----------------------------------------- |
63
+ | `BETTER_AUTH_URL` | Public origin used by Better Auth |
64
+ | `BETTER_AUTH_SECRET` | Secret used to sign and encrypt auth data |
65
+ | `DATABASE_URL` | Pooled Postgres connection string |
66
+
67
+ Never commit `.env.local` or expose the database connection string.
68
+
69
+ ## Deployment note
70
+
71
+ The starter uses `pg` with a small connection pool suitable for a pooled Neon endpoint. Add
72
+ `DATABASE_URL`, `BETTER_AUTH_SECRET`, and the production `BETTER_AUTH_URL` to your deployment
73
+ environment before building.
74
+
75
+ The FARMJS deployment target is configured in [`farm.config.ts`](./farm.config.ts) for Vercel.
76
+
77
+ ## Commands
78
+
79
+ ```bash
80
+ pnpm dev # start the development server
81
+ pnpm type-check # run TypeScript checks
82
+ pnpm build # create the production build
83
+ pnpm check # type-check and build
84
+ pnpm run deploy -- --prod # deploy the prebuilt Farm output to Vercel
85
+ ```
86
+
87
+ ## License
88
+
89
+ MIT
@@ -0,0 +1,33 @@
1
+ import { defineDocs } from "@farming-labs/docs";
2
+
3
+ // Site-wide docs configuration, powered by the @farming-labs/farmjs framework.
4
+ // Farm auto-detects the installed adapter (because farm.config.ts sets
5
+ // `docs: { enabled: true }`), loads this file, and serves Markdown from
6
+ // src/app/docs.
7
+ //
8
+ // This typed config takes priority over docs.json. Keep docs.json in sync as
9
+ // the language-agnostic manifest: it is the fallback for frameworkless / non
10
+ // JS-TS setups and the source the docs cloud reads.
11
+ export default defineDocs({
12
+ entry: "docs",
13
+ docsPath: "/docs",
14
+ metadata: {
15
+ description: "Documentation for your Farm.js app.",
16
+ },
17
+ nav: {
18
+ title: "Farm App",
19
+ url: "/",
20
+ },
21
+ search: {
22
+ provider: "simple",
23
+ enabled: true,
24
+ maxResults: 12,
25
+ },
26
+ llmsTxt: {
27
+ enabled: true,
28
+ siteTitle: "Farm App Docs",
29
+ siteDescription: "Documentation for your Farm.js app.",
30
+ },
31
+ sitemap: true,
32
+ robots: true,
33
+ });
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://docs.farming-labs.dev/schema/docs.json",
3
+ "version": 1,
4
+ "entry": "docs",
5
+ "docsPath": "/docs",
6
+ "docs": {
7
+ "mode": "framework",
8
+ "runtime": "farm",
9
+ "root": "."
10
+ },
11
+ "content": {
12
+ "docsRoot": "src/app/docs"
13
+ },
14
+ "site": {
15
+ "name": "Farm App Docs"
16
+ },
17
+ "metadata": {
18
+ "description": "Documentation for your Farm.js app."
19
+ },
20
+ "nav": {
21
+ "title": "Farm App",
22
+ "url": "/"
23
+ },
24
+ "search": {
25
+ "provider": "simple",
26
+ "enabled": true,
27
+ "maxResults": 12
28
+ },
29
+ "llmsTxt": {
30
+ "enabled": true,
31
+ "siteTitle": "Farm App Docs",
32
+ "siteDescription": "Documentation for your Farm.js app."
33
+ },
34
+ "sitemap": true,
35
+ "robots": true
36
+ }
@@ -0,0 +1,38 @@
1
+ import { defineConfig } from "@farm.js/core";
2
+ import { betterAuth } from "@farm.js/better-auth";
3
+ import { auth } from "./src/lib/auth.ts";
4
+
5
+ export default defineConfig({
6
+ srcDir: "src",
7
+ theme: {
8
+ default: "dark",
9
+ },
10
+ // Docs are powered by the @farming-labs/farmjs framework. Farm auto-detects
11
+ // the installed adapter and reads docs.config.ts (docs.json is kept as a
12
+ // language-agnostic fallback/manifest); content lives in src/app/docs.
13
+ docs: {
14
+ enabled: true,
15
+ },
16
+ experimental: {
17
+ serverComponents: true,
18
+ },
19
+ vite: {
20
+ server: {
21
+ port: 3000,
22
+ strictPort: true,
23
+ },
24
+ },
25
+ integrations: {
26
+ auth: betterAuth({
27
+ instance: auth,
28
+ log(event) {
29
+ if (process.env.NODE_ENV !== "production") {
30
+ console.log("[better-auth]", event.phase, event.route?.path ?? "request");
31
+ }
32
+ },
33
+ }),
34
+ },
35
+ deploy: {
36
+ target: "vercel",
37
+ },
38
+ });
@@ -0,0 +1,10 @@
1
+ node_modules
2
+ .farm
3
+ .vercel
4
+ .data
5
+ .env
6
+ .env.local
7
+ .env.*.local
8
+ dist
9
+ *.log
10
+ .DS_Store
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "farmjs-better-auth-starter",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "farm dev",
7
+ "build": "farm build",
8
+ "check": "pnpm type-check && pnpm build",
9
+ "deploy": "farm deploy",
10
+ "type-check": "tsc --noEmit"
11
+ },
12
+ "dependencies": {
13
+ "@farm.js/better-auth": "0.1.0-beta.71",
14
+ "@farm.js/core": "0.1.0-beta.71",
15
+ "@farming-labs/docs": "0.2.111",
16
+ "@farming-labs/farmjs": "0.2.111",
17
+ "@farming-labs/theme": "0.2.111",
18
+ "@fontsource-variable/geist": "5.3.0",
19
+ "@fontsource-variable/geist-mono": "5.3.0",
20
+ "better-auth": "1.6.25",
21
+ "better-call": "1.3.7",
22
+ "pg": "8.22.0",
23
+ "react": "^19.0.0",
24
+ "react-dom": "^19.0.0"
25
+ },
26
+ "devDependencies": {
27
+ "@farm.js/cli": "0.1.0-beta.71",
28
+ "@types/node": "20.19.9",
29
+ "@types/pg": "8.20.0",
30
+ "@types/react": "^19.0.0",
31
+ "@types/react-dom": "^19.0.0",
32
+ "tailwindcss": "^4.0.0",
33
+ "typescript": "^5.3.3"
34
+ },
35
+ "packageManager": "pnpm@11.18.0"
36
+ }