Skip to content

Commit d0767af

Browse files
Merge branch 'main' into markdown-relative-links
2 parents 390848b + 0bb8aff commit d0767af

File tree

173 files changed

+12670
-6397
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

173 files changed

+12670
-6397
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
node_modules
22
package-lock.json
33
yarn.lock
4-
convex/generated
4+
drizzle/migrations
55

66
.tanstack
77
.DS_Store

.prettierignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
**/public
44
pnpm-lock.yaml
55
routeTree.gen.ts
6-
convex/_generated
7-
convex/README.md
86
src/blog/tanstack-db-0.1-the-embedded-client-database-for-tanstack-query.md
97
.content-collections
108
.claude

.tanstack-start/server-routes/routeTree.gen.ts

Lines changed: 0 additions & 153 deletions
This file was deleted.

AGENTS.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,94 @@ loader: async ({ deps }) => {
7272
```
7373

7474
This ensures the loader only re-runs when the specific dependencies change, not when unrelated search params (like `expanded`, `viewMode`, etc.) change.
75+
76+
### Loaders Are Isomorphic
77+
78+
**Loaders in TanStack Start/Router are isomorphic and cannot call server logic unless via a call to a server function.**
79+
80+
Loaders run on both the server and client, so they cannot directly access server-only APIs (like file system, database connections, etc.). To perform server-side operations, loaders must call server functions (e.g., TanStack server functions created via `createServerFn()`, Convex queries/mutations, API routes, or other server functions).
81+
82+
**Bad:**
83+
84+
```typescript
85+
loader: async () => {
86+
// This won't work - direct server API access
87+
const data = await fs.readFile('data.json')
88+
return { data }
89+
}
90+
```
91+
92+
**Good:**
93+
94+
```typescript
95+
loader: async () => {
96+
// Call a server function instead (TanStack server function or Convex)
97+
// TanStack server functions created via createServerFn() can be called directly
98+
const data = await serverFn({ data: { id: '123' } })
99+
// or
100+
const data = await convex.query(api.data.getData)
101+
return { data }
102+
}
103+
```
104+
105+
## Server-Only Code and Environment Shaking
106+
107+
### TanStack Start Environment Shaking
108+
109+
**TanStack Start performs environment shaking - any code not referenced by a `createServerFn` handler is stripped from the client build.**
110+
111+
This means:
112+
113+
- Server-only code (database, file system, etc.) is automatically excluded from client bundles
114+
- Only code inside `createServerFn` handlers is included in server bundles
115+
- Code outside handlers is included in both server and client bundles
116+
117+
### Importing Server Functions
118+
119+
**Server functions wrapped in `createServerFn` can be safely imported statically in route files.**
120+
121+
**Bad - Dynamic imports in component code:**
122+
123+
```typescript
124+
// In a route component
125+
const rolesQuery = useQuery({
126+
queryFn: async () => {
127+
const { listRoles } = await import('~/utils/roles.server')
128+
return listRoles({ data: {} })
129+
},
130+
})
131+
```
132+
133+
This causes bundler issues because dynamic imports can't be properly tree-shaken, potentially pulling server-only code (like `Buffer`, `drizzle`, `postgres`) into the client bundle.
134+
135+
**Good - Static imports:**
136+
137+
```typescript
138+
// At the top of the route file
139+
import { listRoles } from '~/utils/roles.server'
140+
141+
// In component code
142+
const rolesQuery = useQuery({
143+
queryFn: async () => {
144+
return listRoles({ data: {} })
145+
},
146+
})
147+
```
148+
149+
Since `listRoles` is wrapped in `createServerFn`, TanStack Start will properly handle environment shaking and exclude server-only dependencies from the client bundle.
150+
151+
### Rules for Server-Only Imports
152+
153+
1. **Server functions** (`createServerFn` wrappers) can be imported statically anywhere
154+
2. **Direct server-only code** (database clients, file system, etc.) must ONLY be imported:
155+
- Inside `createServerFn` handlers
156+
- In separate server-only files (e.g., `*.server.ts`)
157+
- Never use dynamic imports (`await import()`) for server-only code in component code
158+
159+
## Development & Build Commands
160+
161+
### Use `build` for Testing Build Output
162+
163+
**The `dev` command does not end - it runs indefinitely in watch mode.**
164+
165+
When agents need to test build output or verify that the project builds successfully, use the `build` command instead of `dev`. The `build` command will complete and exit, making it suitable for automated testing and verification.

convex/README.md

Lines changed: 0 additions & 90 deletions
This file was deleted.

0 commit comments

Comments
 (0)