From dafb284278764b7a1fd1b2f3900a57aa6e015358 Mon Sep 17 00:00:00 2001
From: Birk Skyum
Date: Tue, 11 Nov 2025 03:43:39 +0100
Subject: [PATCH 1/3] docs(solid-start): start-bun example
---
examples/solid/start-bun/.gitignore | 12 +
examples/solid/start-bun/.prettierignore | 3 +
.../solid/start-bun/.vscode/settings.json | 11 +
examples/solid/start-bun/README.md | 173 ++++++
examples/solid/start-bun/eslint.config.js | 5 +
examples/solid/start-bun/package.json | 41 ++
examples/solid/start-bun/prettier.config.js | 10 +
examples/solid/start-bun/public/favicon.ico | Bin 0 -> 3870 bytes
examples/solid/start-bun/public/logo192.png | Bin 0 -> 5347 bytes
examples/solid/start-bun/public/logo512.png | Bin 0 -> 9664 bytes
examples/solid/start-bun/public/manifest.json | 25 +
examples/solid/start-bun/public/robots.txt | 3 +
examples/solid/start-bun/server.ts | 556 ++++++++++++++++++
.../solid/start-bun/src/components/Header.tsx | 21 +
examples/solid/start-bun/src/logo.svg | 12 +
examples/solid/start-bun/src/routeTree.gen.ts | 135 +++++
examples/solid/start-bun/src/router.tsx | 13 +
.../solid/start-bun/src/routes/__root.tsx | 61 ++
.../start-bun/src/routes/api.demo-names.ts | 15 +
.../src/routes/demo.start.api-request.tsx | 42 ++
.../src/routes/demo.start.server-funcs.tsx | 96 +++
examples/solid/start-bun/src/routes/index.tsx | 39 ++
examples/solid/start-bun/src/styles.css | 15 +
examples/solid/start-bun/tsconfig.json | 36 ++
examples/solid/start-bun/vite.config.ts | 19 +
pnpm-lock.yaml | 210 +++++++
26 files changed, 1553 insertions(+)
create mode 100644 examples/solid/start-bun/.gitignore
create mode 100644 examples/solid/start-bun/.prettierignore
create mode 100644 examples/solid/start-bun/.vscode/settings.json
create mode 100644 examples/solid/start-bun/README.md
create mode 100644 examples/solid/start-bun/eslint.config.js
create mode 100644 examples/solid/start-bun/package.json
create mode 100644 examples/solid/start-bun/prettier.config.js
create mode 100644 examples/solid/start-bun/public/favicon.ico
create mode 100644 examples/solid/start-bun/public/logo192.png
create mode 100644 examples/solid/start-bun/public/logo512.png
create mode 100644 examples/solid/start-bun/public/manifest.json
create mode 100644 examples/solid/start-bun/public/robots.txt
create mode 100644 examples/solid/start-bun/server.ts
create mode 100644 examples/solid/start-bun/src/components/Header.tsx
create mode 100644 examples/solid/start-bun/src/logo.svg
create mode 100644 examples/solid/start-bun/src/routeTree.gen.ts
create mode 100644 examples/solid/start-bun/src/router.tsx
create mode 100644 examples/solid/start-bun/src/routes/__root.tsx
create mode 100644 examples/solid/start-bun/src/routes/api.demo-names.ts
create mode 100644 examples/solid/start-bun/src/routes/demo.start.api-request.tsx
create mode 100644 examples/solid/start-bun/src/routes/demo.start.server-funcs.tsx
create mode 100644 examples/solid/start-bun/src/routes/index.tsx
create mode 100644 examples/solid/start-bun/src/styles.css
create mode 100644 examples/solid/start-bun/tsconfig.json
create mode 100644 examples/solid/start-bun/vite.config.ts
diff --git a/examples/solid/start-bun/.gitignore b/examples/solid/start-bun/.gitignore
new file mode 100644
index 00000000000..029f7fba9a9
--- /dev/null
+++ b/examples/solid/start-bun/.gitignore
@@ -0,0 +1,12 @@
+node_modules
+.DS_Store
+dist
+dist-ssr
+*.local
+count.txt
+.env
+.nitro
+.tanstack
+.output
+.vinxi
+todos.json
diff --git a/examples/solid/start-bun/.prettierignore b/examples/solid/start-bun/.prettierignore
new file mode 100644
index 00000000000..5322d7feeae
--- /dev/null
+++ b/examples/solid/start-bun/.prettierignore
@@ -0,0 +1,3 @@
+package-lock.json
+pnpm-lock.yaml
+yarn.lock
\ No newline at end of file
diff --git a/examples/solid/start-bun/.vscode/settings.json b/examples/solid/start-bun/.vscode/settings.json
new file mode 100644
index 00000000000..00b5278e580
--- /dev/null
+++ b/examples/solid/start-bun/.vscode/settings.json
@@ -0,0 +1,11 @@
+{
+ "files.watcherExclude": {
+ "**/routeTree.gen.ts": true
+ },
+ "search.exclude": {
+ "**/routeTree.gen.ts": true
+ },
+ "files.readonlyInclude": {
+ "**/routeTree.gen.ts": true
+ }
+}
diff --git a/examples/solid/start-bun/README.md b/examples/solid/start-bun/README.md
new file mode 100644
index 00000000000..e659b0dd980
--- /dev/null
+++ b/examples/solid/start-bun/README.md
@@ -0,0 +1,173 @@
+# TanStack Start + Bun Production Server
+
+An optimized production server for TanStack Start applications using Bun, implementing intelligent static asset loading with configurable memory management.
+
+## š Features
+
+- **Hybrid Loading Strategy**: Small files are preloaded into memory, large files are served on-demand
+- **Configurable File Filtering**: Include/Exclude patterns for precise control
+- **Memory-efficient Response Generation**: Optimized for high performance
+- **Production-ready Caching Headers**: Automatic Cache-Control headers for optimal performance
+- **Detailed Logging**: Vite-like output for better overview
+
+## š¦ Installation
+
+This project was created with TanStack Start:
+
+```bash
+bunx create-start-app@latest
+```
+
+Install dependencies:
+
+```bash
+bun install
+```
+
+## šāāļø Development
+
+For development:
+
+```bash
+bun run dev
+```
+
+## šØ Production Build
+
+Build the application for production:
+
+```bash
+bun run build
+```
+
+## š Production Server with server.ts
+
+### Quick Start - Use in Your Project
+
+You can easily use this production server in your own TanStack Start project:
+
+1. **Copy the `server.ts` file** into your project root
+2. **Build your project** with `bun run build`
+3. **Start the server** directly with:
+ ```bash
+ bun run server.ts
+ ```
+
+Or add it to your `package.json` scripts:
+
+```json
+{
+ "scripts": {
+ "start": "bun run server.ts"
+ }
+}
+```
+
+Then run with:
+
+```bash
+bun run start
+```
+
+### Server Features
+
+The `server.ts` implements a high-performance production server with the following features:
+
+#### 1. Intelligent Asset Loading
+
+The server automatically decides which files to preload into memory and which to serve on-demand:
+
+- **In-Memory Loading**: Small files (default < 5MB) are loaded into memory at startup
+- **On-Demand Loading**: Large files are loaded from disk only when requested
+- **Optimized Performance**: Frequently used assets are served from memory
+
+#### 2. Configuration via Environment Variables
+
+```bash
+# Server Port (default: 3000)
+PORT=3000
+
+# Maximum file size for in-memory loading (in bytes, default: 5MB)
+STATIC_PRELOAD_MAX_BYTES=5242880
+
+# Include patterns (comma-separated, only these files will be preloaded)
+STATIC_PRELOAD_INCLUDE="*.js,*.css,*.woff2"
+
+# Exclude patterns (comma-separated, these files will be excluded)
+STATIC_PRELOAD_EXCLUDE="*.map,*.txt"
+
+# Enable detailed logging
+STATIC_PRELOAD_VERBOSE=true
+```
+
+### Example Configurations
+
+#### Minimal Memory Footprint
+
+```bash
+# Preload only critical assets
+STATIC_PRELOAD_MAX_BYTES=1048576 \
+STATIC_PRELOAD_INCLUDE="*.js,*.css" \
+STATIC_PRELOAD_EXCLUDE="*.map,vendor-*" \
+bun run start
+```
+
+#### Maximum Performance
+
+```bash
+# Preload all small assets
+STATIC_PRELOAD_MAX_BYTES=10485760 \
+bun run start
+```
+
+#### Debug Mode
+
+```bash
+# With detailed logging
+STATIC_PRELOAD_VERBOSE=true \
+bun run start
+```
+
+### Server Output
+
+The server displays a clear overview of all loaded assets at startup:
+
+```txt
+š¦ Loading static assets from ./dist/client...
+ Max preload size: 5.00 MB
+ Include patterns: *.js,*.css,*.woff2
+
+š Preloaded into memory:
+ /assets/index-a1b2c3d4.js 45.23 kB ā gzip: 15.83 kB
+ /assets/index-e5f6g7h8.css 12.45 kB ā gzip: 4.36 kB
+
+š¾ Served on-demand:
+ /assets/vendor-i9j0k1l2.js 245.67 kB ā gzip: 86.98 kB
+
+ā
Preloaded 2 files (57.68 KB) into memory
+ā¹ļø 1 files will be served on-demand (1 too large, 0 filtered)
+
+š Server running at http://localhost:3000
+```
+
+## Testing
+
+This project uses [Vitest](https://vitest.dev/) for testing. You can run the tests with:
+
+```bash
+bun run test
+```
+
+## Styling
+
+This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.
+
+## Linting & Formatting
+
+This project uses [eslint](https://eslint.org/) and [prettier](https://prettier.io/) for linting and formatting. Eslint is configured using [tanstack/eslint-config](https://tanstack.com/config/latest/docs/eslint). The following scripts are available:
+
+```bash
+bun run lint
+bun run format
+bun run check
+```
diff --git a/examples/solid/start-bun/eslint.config.js b/examples/solid/start-bun/eslint.config.js
new file mode 100644
index 00000000000..676b32a87ff
--- /dev/null
+++ b/examples/solid/start-bun/eslint.config.js
@@ -0,0 +1,5 @@
+// @ts-check
+
+import { tanstackConfig } from '@tanstack/eslint-config'
+
+export default [...tanstackConfig]
diff --git a/examples/solid/start-bun/package.json b/examples/solid/start-bun/package.json
new file mode 100644
index 00000000000..0693dbf89a7
--- /dev/null
+++ b/examples/solid/start-bun/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "tanstack-solid-start-bun-hosting",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite dev --port 3000",
+ "start": "bun run server.ts",
+ "build": "vite build",
+ "serve": "vite preview",
+ "test": "vitest run",
+ "lint": "eslint",
+ "format": "prettier",
+ "check": "prettier --write . && eslint --fix"
+ },
+ "dependencies": {
+ "@tailwindcss/vite": "^4.1.13",
+ "@tanstack/solid-devtools": "^0.7.0",
+ "@tanstack/solid-router": "^1.135.2",
+ "@tanstack/solid-router-devtools": "^1.135.2",
+ "@tanstack/solid-router-ssr-query": "^1.135.2",
+ "@tanstack/solid-start": "^1.135.2",
+ "@tanstack/router-plugin": "^1.135.2",
+ "solid-js": "^1.9.10",
+ "tailwindcss": "^4.1.13",
+ "vite-tsconfig-paths": "^5.1.4"
+ },
+ "devDependencies": {
+ "@tanstack/eslint-config": "^0.3.2",
+ "@testing-library/dom": "^10.4.1",
+ "@solidjs/testing-library": "^0.8.10",
+ "@types/bun": "^1.2.22",
+ "@types/node": "22.10.2",
+ "vite-plugin-solid": "^2.11.10",
+ "jsdom": "^27.0.0",
+ "prettier": "^3.6.2",
+ "typescript": "^5.9.2",
+ "vite": "^7.1.7",
+ "vitest": "^3.2.4",
+ "web-vitals": "^5.1.0"
+ }
+}
diff --git a/examples/solid/start-bun/prettier.config.js b/examples/solid/start-bun/prettier.config.js
new file mode 100644
index 00000000000..f7279f7ba51
--- /dev/null
+++ b/examples/solid/start-bun/prettier.config.js
@@ -0,0 +1,10 @@
+// @ts-check
+
+/** @type {import('prettier').Config} */
+const config = {
+ semi: false,
+ singleQuote: true,
+ trailingComma: 'all',
+}
+
+export default config
diff --git a/examples/solid/start-bun/public/favicon.ico b/examples/solid/start-bun/public/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..a11777cc471a4344702741ab1c8a588998b1311a
GIT binary patch
literal 3870
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
baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@
literal 0
HcmV?d00001
diff --git a/examples/solid/start-bun/public/logo192.png b/examples/solid/start-bun/public/logo192.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc44b0a3796c0e0a64c3d858ca038bd4570465d9
GIT binary patch
literal 5347
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
b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN
literal 0
HcmV?d00001
diff --git a/examples/solid/start-bun/public/manifest.json b/examples/solid/start-bun/public/manifest.json
new file mode 100644
index 00000000000..078ef501162
--- /dev/null
+++ b/examples/solid/start-bun/public/manifest.json
@@ -0,0 +1,25 @@
+{
+ "short_name": "TanStack App",
+ "name": "Create TanStack App Sample",
+ "icons": [
+ {
+ "src": "favicon.ico",
+ "sizes": "64x64 32x32 24x24 16x16",
+ "type": "image/x-icon"
+ },
+ {
+ "src": "logo192.png",
+ "type": "image/png",
+ "sizes": "192x192"
+ },
+ {
+ "src": "logo512.png",
+ "type": "image/png",
+ "sizes": "512x512"
+ }
+ ],
+ "start_url": ".",
+ "display": "standalone",
+ "theme_color": "#000000",
+ "background_color": "#ffffff"
+}
diff --git a/examples/solid/start-bun/public/robots.txt b/examples/solid/start-bun/public/robots.txt
new file mode 100644
index 00000000000..e9e57dc4d41
--- /dev/null
+++ b/examples/solid/start-bun/public/robots.txt
@@ -0,0 +1,3 @@
+# https://www.robotstxt.org/robotstxt.html
+User-agent: *
+Disallow:
diff --git a/examples/solid/start-bun/server.ts b/examples/solid/start-bun/server.ts
new file mode 100644
index 00000000000..be8d3b1ed5a
--- /dev/null
+++ b/examples/solid/start-bun/server.ts
@@ -0,0 +1,556 @@
+/**
+ * TanStack Start Production Server with Bun
+ *
+ * A high-performance production server for TanStack Start applications that
+ * implements intelligent static asset loading with configurable memory management.
+ *
+ * Features:
+ * - Hybrid loading strategy (preload small files, serve large files on-demand)
+ * - Configurable file filtering with include/exclude patterns
+ * - Memory-efficient response generation
+ * - Production-ready caching headers
+ *
+ * Environment Variables:
+ *
+ * PORT (number)
+ * - Server port number
+ * - Default: 3000
+ *
+ * ASSET_PRELOAD_MAX_SIZE (number)
+ * - Maximum file size in bytes to preload into memory
+ * - Files larger than this will be served on-demand from disk
+ * - Default: 5242880 (5MB)
+ * - Example: ASSET_PRELOAD_MAX_SIZE=5242880 (5MB)
+ *
+ * ASSET_PRELOAD_INCLUDE_PATTERNS (string)
+ * - Comma-separated list of glob patterns for files to include
+ * - If specified, only matching files are eligible for preloading
+ * - Patterns are matched against filenames only, not full paths
+ * - Example: ASSET_PRELOAD_INCLUDE_PATTERNS="*.js,*.css,*.woff2"
+ *
+ * ASSET_PRELOAD_EXCLUDE_PATTERNS (string)
+ * - Comma-separated list of glob patterns for files to exclude
+ * - Applied after include patterns
+ * - Patterns are matched against filenames only, not full paths
+ * - Example: ASSET_PRELOAD_EXCLUDE_PATTERNS="*.map,*.txt"
+ *
+ * ASSET_PRELOAD_VERBOSE_LOGGING (boolean)
+ * - Enable detailed logging of loaded and skipped files
+ * - Default: false
+ * - Set to "true" to enable verbose output
+ *
+ * ASSET_PRELOAD_ENABLE_ETAG (boolean)
+ * - Enable ETag generation for preloaded assets
+ * - Default: true
+ * - Set to "false" to disable ETag support
+ *
+ * ASSET_PRELOAD_ENABLE_GZIP (boolean)
+ * - Enable Gzip compression for eligible assets
+ * - Default: true
+ * - Set to "false" to disable Gzip compression
+ *
+ * ASSET_PRELOAD_GZIP_MIN_SIZE (number)
+ * - Minimum file size in bytes required for Gzip compression
+ * - Files smaller than this will not be compressed
+ * - Default: 1024 (1KB)
+ *
+ * ASSET_PRELOAD_GZIP_MIME_TYPES (string)
+ * - Comma-separated list of MIME types eligible for Gzip compression
+ * - Supports partial matching for types ending with "/"
+ * - Default: text/,application/javascript,application/json,application/xml,image/svg+xml
+ *
+ * Usage:
+ * bun run server.ts
+ */
+
+import path from 'node:path'
+
+// Configuration
+const SERVER_PORT = Number(process.env.PORT ?? 3000)
+const CLIENT_DIRECTORY = './dist/client'
+const SERVER_ENTRY_POINT = './dist/server/server.js'
+
+// Logging utilities for professional output
+const log = {
+ info: (message: string) => {
+ console.log(`[INFO] ${message}`)
+ },
+ success: (message: string) => {
+ console.log(`[SUCCESS] ${message}`)
+ },
+ warning: (message: string) => {
+ console.log(`[WARNING] ${message}`)
+ },
+ error: (message: string) => {
+ console.log(`[ERROR] ${message}`)
+ },
+ header: (message: string) => {
+ console.log(`\n${message}\n`)
+ },
+}
+
+// Preloading configuration from environment variables
+const MAX_PRELOAD_BYTES = Number(
+ process.env.ASSET_PRELOAD_MAX_SIZE ?? 5 * 1024 * 1024, // 5MB default
+)
+
+// Parse comma-separated include patterns (no defaults)
+const INCLUDE_PATTERNS = (process.env.ASSET_PRELOAD_INCLUDE_PATTERNS ?? '')
+ .split(',')
+ .map((s) => s.trim())
+ .filter(Boolean)
+ .map((pattern: string) => convertGlobToRegExp(pattern))
+
+// Parse comma-separated exclude patterns (no defaults)
+const EXCLUDE_PATTERNS = (process.env.ASSET_PRELOAD_EXCLUDE_PATTERNS ?? '')
+ .split(',')
+ .map((s) => s.trim())
+ .filter(Boolean)
+ .map((pattern: string) => convertGlobToRegExp(pattern))
+
+// Verbose logging flag
+const VERBOSE = process.env.ASSET_PRELOAD_VERBOSE_LOGGING === 'true'
+
+// Optional ETag feature
+const ENABLE_ETAG = (process.env.ASSET_PRELOAD_ENABLE_ETAG ?? 'true') === 'true'
+
+// Optional Gzip feature
+const ENABLE_GZIP = (process.env.ASSET_PRELOAD_ENABLE_GZIP ?? 'true') === 'true'
+const GZIP_MIN_BYTES = Number(process.env.ASSET_PRELOAD_GZIP_MIN_SIZE ?? 1024) // 1KB
+const GZIP_TYPES = (
+ process.env.ASSET_PRELOAD_GZIP_MIME_TYPES ??
+ 'text/,application/javascript,application/json,application/xml,image/svg+xml'
+)
+ .split(',')
+ .map((v) => v.trim())
+ .filter(Boolean)
+
+/**
+ * Convert a simple glob pattern to a regular expression
+ * Supports * wildcard for matching any characters
+ */
+function convertGlobToRegExp(globPattern: string): RegExp {
+ // Escape regex special chars except *, then replace * with .*
+ const escapedPattern = globPattern
+ .replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&')
+ .replace(/\*/g, '.*')
+ return new RegExp(`^${escapedPattern}$`, 'i')
+}
+
+/**
+ * Compute ETag for a given data buffer
+ */
+function computeEtag(data: Uint8Array): string {
+ const hash = Bun.hash(data)
+ return `W/"${hash.toString(16)}-${data.byteLength.toString()}"`
+}
+
+/**
+ * Metadata for preloaded static assets
+ */
+interface AssetMetadata {
+ route: string
+ size: number
+ type: string
+}
+
+/**
+ * In-memory asset with ETag and Gzip support
+ */
+interface InMemoryAsset {
+ raw: Uint8Array
+ gz?: Uint8Array
+ etag?: string
+ type: string
+ immutable: boolean
+ size: number
+}
+
+/**
+ * Result of static asset preloading process
+ */
+interface PreloadResult {
+ routes: Record Response | Promise>
+ loaded: AssetMetadata[]
+ skipped: AssetMetadata[]
+}
+
+/**
+ * Check if a file is eligible for preloading based on configured patterns
+ */
+function isFileEligibleForPreloading(relativePath: string): boolean {
+ const fileName = relativePath.split(/[/\\]/).pop() ?? relativePath
+
+ // If include patterns are specified, file must match at least one
+ if (INCLUDE_PATTERNS.length > 0) {
+ if (!INCLUDE_PATTERNS.some((pattern) => pattern.test(fileName))) {
+ return false
+ }
+ }
+
+ // If exclude patterns are specified, file must not match any
+ if (EXCLUDE_PATTERNS.some((pattern) => pattern.test(fileName))) {
+ return false
+ }
+
+ return true
+}
+
+/**
+ * Check if a MIME type is compressible
+ */
+function isMimeTypeCompressible(mimeType: string): boolean {
+ return GZIP_TYPES.some((type) =>
+ type.endsWith('/') ? mimeType.startsWith(type) : mimeType === type,
+ )
+}
+
+/**
+ * Conditionally compress data based on size and MIME type
+ */
+function compressDataIfAppropriate(
+ data: Uint8Array,
+ mimeType: string,
+): Uint8Array | undefined {
+ if (!ENABLE_GZIP) return undefined
+ if (data.byteLength < GZIP_MIN_BYTES) return undefined
+ if (!isMimeTypeCompressible(mimeType)) return undefined
+ try {
+ return Bun.gzipSync(data.buffer as ArrayBuffer)
+ } catch {
+ return undefined
+ }
+}
+
+/**
+ * Create response handler function with ETag and Gzip support
+ */
+function createResponseHandler(
+ asset: InMemoryAsset,
+): (req: Request) => Response {
+ return (req: Request) => {
+ const headers: Record = {
+ 'Content-Type': asset.type,
+ 'Cache-Control': asset.immutable
+ ? 'public, max-age=31536000, immutable'
+ : 'public, max-age=3600',
+ }
+
+ if (ENABLE_ETAG && asset.etag) {
+ const ifNone = req.headers.get('if-none-match')
+ if (ifNone && ifNone === asset.etag) {
+ return new Response(null, {
+ status: 304,
+ headers: { ETag: asset.etag },
+ })
+ }
+ headers.ETag = asset.etag
+ }
+
+ if (
+ ENABLE_GZIP &&
+ asset.gz &&
+ req.headers.get('accept-encoding')?.includes('gzip')
+ ) {
+ headers['Content-Encoding'] = 'gzip'
+ headers['Content-Length'] = String(asset.gz.byteLength)
+ const gzCopy = new Uint8Array(asset.gz)
+ return new Response(gzCopy, { status: 200, headers })
+ }
+
+ headers['Content-Length'] = String(asset.raw.byteLength)
+ const rawCopy = new Uint8Array(asset.raw)
+ return new Response(rawCopy, { status: 200, headers })
+ }
+}
+
+/**
+ * Create composite glob pattern from include patterns
+ */
+function createCompositeGlobPattern(): Bun.Glob {
+ const raw = (process.env.ASSET_PRELOAD_INCLUDE_PATTERNS ?? '')
+ .split(',')
+ .map((s) => s.trim())
+ .filter(Boolean)
+ if (raw.length === 0) return new Bun.Glob('**/*')
+ if (raw.length === 1) return new Bun.Glob(raw[0])
+ return new Bun.Glob(`{${raw.join(',')}}`)
+}
+
+/**
+ * Initialize static routes with intelligent preloading strategy
+ * Small files are loaded into memory, large files are served on-demand
+ */
+async function initializeStaticRoutes(
+ clientDirectory: string,
+): Promise {
+ const routes: Record Response | Promise> =
+ {}
+ const loaded: AssetMetadata[] = []
+ const skipped: AssetMetadata[] = []
+
+ log.info(`Loading static assets from ${clientDirectory}...`)
+ if (VERBOSE) {
+ console.log(
+ `Max preload size: ${(MAX_PRELOAD_BYTES / 1024 / 1024).toFixed(2)} MB`,
+ )
+ if (INCLUDE_PATTERNS.length > 0) {
+ console.log(
+ `Include patterns: ${process.env.ASSET_PRELOAD_INCLUDE_PATTERNS ?? ''}`,
+ )
+ }
+ if (EXCLUDE_PATTERNS.length > 0) {
+ console.log(
+ `Exclude patterns: ${process.env.ASSET_PRELOAD_EXCLUDE_PATTERNS ?? ''}`,
+ )
+ }
+ }
+
+ let totalPreloadedBytes = 0
+
+ try {
+ const glob = createCompositeGlobPattern()
+ for await (const relativePath of glob.scan({ cwd: clientDirectory })) {
+ const filepath = path.join(clientDirectory, relativePath)
+ const route = `/${relativePath.split(path.sep).join(path.posix.sep)}`
+
+ try {
+ // Get file metadata
+ const file = Bun.file(filepath)
+
+ // Skip if file doesn't exist or is empty
+ if (!(await file.exists()) || file.size === 0) {
+ continue
+ }
+
+ const metadata: AssetMetadata = {
+ route,
+ size: file.size,
+ type: file.type || 'application/octet-stream',
+ }
+
+ // Determine if file should be preloaded
+ const matchesPattern = isFileEligibleForPreloading(relativePath)
+ const withinSizeLimit = file.size <= MAX_PRELOAD_BYTES
+
+ if (matchesPattern && withinSizeLimit) {
+ // Preload small files into memory with ETag and Gzip support
+ const bytes = new Uint8Array(await file.arrayBuffer())
+ const gz = compressDataIfAppropriate(bytes, metadata.type)
+ const etag = ENABLE_ETAG ? computeEtag(bytes) : undefined
+ const asset: InMemoryAsset = {
+ raw: bytes,
+ gz,
+ etag,
+ type: metadata.type,
+ immutable: true,
+ size: bytes.byteLength,
+ }
+ routes[route] = createResponseHandler(asset)
+
+ loaded.push({ ...metadata, size: bytes.byteLength })
+ totalPreloadedBytes += bytes.byteLength
+ } else {
+ // Serve large or filtered files on-demand
+ routes[route] = () => {
+ const fileOnDemand = Bun.file(filepath)
+ return new Response(fileOnDemand, {
+ headers: {
+ 'Content-Type': metadata.type,
+ 'Cache-Control': 'public, max-age=3600',
+ },
+ })
+ }
+
+ skipped.push(metadata)
+ }
+ } catch (error: unknown) {
+ if (error instanceof Error && error.name !== 'EISDIR') {
+ log.error(`Failed to load ${filepath}: ${error.message}`)
+ }
+ }
+ }
+
+ // Show detailed file overview only when verbose mode is enabled
+ if (VERBOSE && (loaded.length > 0 || skipped.length > 0)) {
+ const allFiles = [...loaded, ...skipped].sort((a, b) =>
+ a.route.localeCompare(b.route),
+ )
+
+ // Calculate max path length for alignment
+ const maxPathLength = Math.min(
+ Math.max(...allFiles.map((f) => f.route.length)),
+ 60,
+ )
+
+ // Format file size with KB and actual gzip size
+ const formatFileSize = (bytes: number, gzBytes?: number) => {
+ const kb = bytes / 1024
+ const sizeStr = kb < 100 ? kb.toFixed(2) : kb.toFixed(1)
+
+ if (gzBytes !== undefined) {
+ const gzKb = gzBytes / 1024
+ const gzStr = gzKb < 100 ? gzKb.toFixed(2) : gzKb.toFixed(1)
+ return {
+ size: sizeStr,
+ gzip: gzStr,
+ }
+ }
+
+ // Rough gzip estimation (typically 30-70% compression) if no actual gzip data
+ const gzipKb = kb * 0.35
+ return {
+ size: sizeStr,
+ gzip: gzipKb < 100 ? gzipKb.toFixed(2) : gzipKb.toFixed(1),
+ }
+ }
+
+ if (loaded.length > 0) {
+ console.log('\nš Preloaded into memory:')
+ console.log(
+ 'Path ā Size ā Gzip Size',
+ )
+ loaded
+ .sort((a, b) => a.route.localeCompare(b.route))
+ .forEach((file) => {
+ const { size, gzip } = formatFileSize(file.size)
+ const paddedPath = file.route.padEnd(maxPathLength)
+ const sizeStr = `${size.padStart(7)} kB`
+ const gzipStr = `${gzip.padStart(7)} kB`
+ console.log(`${paddedPath} ā ${sizeStr} ā ${gzipStr}`)
+ })
+ }
+
+ if (skipped.length > 0) {
+ console.log('\nš¾ Served on-demand:')
+ console.log(
+ 'Path ā Size ā Gzip Size',
+ )
+ skipped
+ .sort((a, b) => a.route.localeCompare(b.route))
+ .forEach((file) => {
+ const { size, gzip } = formatFileSize(file.size)
+ const paddedPath = file.route.padEnd(maxPathLength)
+ const sizeStr = `${size.padStart(7)} kB`
+ const gzipStr = `${gzip.padStart(7)} kB`
+ console.log(`${paddedPath} ā ${sizeStr} ā ${gzipStr}`)
+ })
+ }
+ }
+
+ // Show detailed verbose info if enabled
+ if (VERBOSE) {
+ if (loaded.length > 0 || skipped.length > 0) {
+ const allFiles = [...loaded, ...skipped].sort((a, b) =>
+ a.route.localeCompare(b.route),
+ )
+ console.log('\nš Detailed file information:')
+ console.log(
+ 'Status ā Path ā MIME Type ā Reason',
+ )
+ allFiles.forEach((file) => {
+ const isPreloaded = loaded.includes(file)
+ const status = isPreloaded ? 'MEMORY' : 'ON-DEMAND'
+ const reason =
+ !isPreloaded && file.size > MAX_PRELOAD_BYTES
+ ? 'too large'
+ : !isPreloaded
+ ? 'filtered'
+ : 'preloaded'
+ const route =
+ file.route.length > 30
+ ? file.route.substring(0, 27) + '...'
+ : file.route
+ console.log(
+ `${status.padEnd(12)} ā ${route.padEnd(30)} ā ${file.type.padEnd(28)} ā ${reason.padEnd(10)}`,
+ )
+ })
+ } else {
+ console.log('\nš No files found to display')
+ }
+ }
+
+ // Log summary after the file list
+ console.log() // Empty line for separation
+ if (loaded.length > 0) {
+ log.success(
+ `Preloaded ${String(loaded.length)} files (${(totalPreloadedBytes / 1024 / 1024).toFixed(2)} MB) into memory`,
+ )
+ } else {
+ log.info('No files preloaded into memory')
+ }
+
+ if (skipped.length > 0) {
+ const tooLarge = skipped.filter((f) => f.size > MAX_PRELOAD_BYTES).length
+ const filtered = skipped.length - tooLarge
+ log.info(
+ `${String(skipped.length)} files will be served on-demand (${String(tooLarge)} too large, ${String(filtered)} filtered)`,
+ )
+ }
+ } catch (error) {
+ log.error(
+ `Failed to load static files from ${clientDirectory}: ${String(error)}`,
+ )
+ }
+
+ return { routes, loaded, skipped }
+}
+
+/**
+ * Initialize the server
+ */
+async function initializeServer() {
+ log.header('Starting Production Server')
+
+ // Load TanStack Start server handler
+ let handler: { fetch: (request: Request) => Response | Promise }
+ try {
+ const serverModule = (await import(SERVER_ENTRY_POINT)) as {
+ default: { fetch: (request: Request) => Response | Promise }
+ }
+ handler = serverModule.default
+ log.success('TanStack Start application handler initialized')
+ } catch (error) {
+ log.error(`Failed to load server handler: ${String(error)}`)
+ process.exit(1)
+ }
+
+ // Build static routes with intelligent preloading
+ const { routes } = await initializeStaticRoutes(CLIENT_DIRECTORY)
+
+ // Create Bun server
+ const server = Bun.serve({
+ port: SERVER_PORT,
+
+ routes: {
+ // Serve static assets (preloaded or on-demand)
+ ...routes,
+
+ // Fallback to TanStack Start handler for all other routes
+ '/*': (req: Request) => {
+ try {
+ return handler.fetch(req)
+ } catch (error) {
+ log.error(`Server handler error: ${String(error)}`)
+ return new Response('Internal Server Error', { status: 500 })
+ }
+ },
+ },
+
+ // Global error handler
+ error(error) {
+ log.error(
+ `Uncaught server error: ${error instanceof Error ? error.message : String(error)}`,
+ )
+ return new Response('Internal Server Error', { status: 500 })
+ },
+ })
+
+ log.success(`Server listening on http://localhost:${String(server.port)}`)
+}
+
+// Initialize the server
+initializeServer().catch((error: unknown) => {
+ log.error(`Failed to start server: ${String(error)}`)
+ process.exit(1)
+})
diff --git a/examples/solid/start-bun/src/components/Header.tsx b/examples/solid/start-bun/src/components/Header.tsx
new file mode 100644
index 00000000000..6591627eaeb
--- /dev/null
+++ b/examples/solid/start-bun/src/components/Header.tsx
@@ -0,0 +1,21 @@
+import { Link } from '@tanstack/solid-router'
+
+export default function Header() {
+ return (
+
+
+
+ )
+}
diff --git a/examples/solid/start-bun/src/logo.svg b/examples/solid/start-bun/src/logo.svg
new file mode 100644
index 00000000000..fe53fe8d0d2
--- /dev/null
+++ b/examples/solid/start-bun/src/logo.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/examples/solid/start-bun/src/routeTree.gen.ts b/examples/solid/start-bun/src/routeTree.gen.ts
new file mode 100644
index 00000000000..19009b2f5bb
--- /dev/null
+++ b/examples/solid/start-bun/src/routeTree.gen.ts
@@ -0,0 +1,135 @@
+/* eslint-disable */
+
+// @ts-nocheck
+
+// noinspection JSUnusedGlobalSymbols
+
+// This file was automatically generated by TanStack Router.
+// You should NOT make any changes in this file as it will be overwritten.
+// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
+
+import { Route as rootRouteImport } from './routes/__root'
+import { Route as IndexRouteImport } from './routes/index'
+import { Route as ApiDemoNamesRouteImport } from './routes/api.demo-names'
+import { Route as DemoStartServerFuncsRouteImport } from './routes/demo.start.server-funcs'
+import { Route as DemoStartApiRequestRouteImport } from './routes/demo.start.api-request'
+
+const IndexRoute = IndexRouteImport.update({
+ id: '/',
+ path: '/',
+ getParentRoute: () => rootRouteImport,
+} as any)
+const ApiDemoNamesRoute = ApiDemoNamesRouteImport.update({
+ id: '/api/demo-names',
+ path: '/api/demo-names',
+ getParentRoute: () => rootRouteImport,
+} as any)
+const DemoStartServerFuncsRoute = DemoStartServerFuncsRouteImport.update({
+ id: '/demo/start/server-funcs',
+ path: '/demo/start/server-funcs',
+ getParentRoute: () => rootRouteImport,
+} as any)
+const DemoStartApiRequestRoute = DemoStartApiRequestRouteImport.update({
+ id: '/demo/start/api-request',
+ path: '/demo/start/api-request',
+ getParentRoute: () => rootRouteImport,
+} as any)
+
+export interface FileRoutesByFullPath {
+ '/': typeof IndexRoute
+ '/api/demo-names': typeof ApiDemoNamesRoute
+ '/demo/start/api-request': typeof DemoStartApiRequestRoute
+ '/demo/start/server-funcs': typeof DemoStartServerFuncsRoute
+}
+export interface FileRoutesByTo {
+ '/': typeof IndexRoute
+ '/api/demo-names': typeof ApiDemoNamesRoute
+ '/demo/start/api-request': typeof DemoStartApiRequestRoute
+ '/demo/start/server-funcs': typeof DemoStartServerFuncsRoute
+}
+export interface FileRoutesById {
+ __root__: typeof rootRouteImport
+ '/': typeof IndexRoute
+ '/api/demo-names': typeof ApiDemoNamesRoute
+ '/demo/start/api-request': typeof DemoStartApiRequestRoute
+ '/demo/start/server-funcs': typeof DemoStartServerFuncsRoute
+}
+export interface FileRouteTypes {
+ fileRoutesByFullPath: FileRoutesByFullPath
+ fullPaths:
+ | '/'
+ | '/api/demo-names'
+ | '/demo/start/api-request'
+ | '/demo/start/server-funcs'
+ fileRoutesByTo: FileRoutesByTo
+ to:
+ | '/'
+ | '/api/demo-names'
+ | '/demo/start/api-request'
+ | '/demo/start/server-funcs'
+ id:
+ | '__root__'
+ | '/'
+ | '/api/demo-names'
+ | '/demo/start/api-request'
+ | '/demo/start/server-funcs'
+ fileRoutesById: FileRoutesById
+}
+export interface RootRouteChildren {
+ IndexRoute: typeof IndexRoute
+ ApiDemoNamesRoute: typeof ApiDemoNamesRoute
+ DemoStartApiRequestRoute: typeof DemoStartApiRequestRoute
+ DemoStartServerFuncsRoute: typeof DemoStartServerFuncsRoute
+}
+
+declare module '@tanstack/solid-router' {
+ interface FileRoutesByPath {
+ '/': {
+ id: '/'
+ path: '/'
+ fullPath: '/'
+ preLoaderRoute: typeof IndexRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ '/api/demo-names': {
+ id: '/api/demo-names'
+ path: '/api/demo-names'
+ fullPath: '/api/demo-names'
+ preLoaderRoute: typeof ApiDemoNamesRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ '/demo/start/server-funcs': {
+ id: '/demo/start/server-funcs'
+ path: '/demo/start/server-funcs'
+ fullPath: '/demo/start/server-funcs'
+ preLoaderRoute: typeof DemoStartServerFuncsRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ '/demo/start/api-request': {
+ id: '/demo/start/api-request'
+ path: '/demo/start/api-request'
+ fullPath: '/demo/start/api-request'
+ preLoaderRoute: typeof DemoStartApiRequestRouteImport
+ parentRoute: typeof rootRouteImport
+ }
+ }
+}
+
+const rootRouteChildren: RootRouteChildren = {
+ IndexRoute: IndexRoute,
+ ApiDemoNamesRoute: ApiDemoNamesRoute,
+ DemoStartApiRequestRoute: DemoStartApiRequestRoute,
+ DemoStartServerFuncsRoute: DemoStartServerFuncsRoute,
+}
+export const routeTree = rootRouteImport
+ ._addFileChildren(rootRouteChildren)
+ ._addFileTypes()
+
+import type { getRouter } from './router.tsx'
+import type { createStart } from '@tanstack/solid-start'
+declare module '@tanstack/solid-start' {
+ interface Register {
+ ssr: true
+ router: Awaited>
+ }
+}
diff --git a/examples/solid/start-bun/src/router.tsx b/examples/solid/start-bun/src/router.tsx
new file mode 100644
index 00000000000..d9d23a5d844
--- /dev/null
+++ b/examples/solid/start-bun/src/router.tsx
@@ -0,0 +1,13 @@
+import { createRouter } from '@tanstack/solid-router'
+
+// Import the generated route tree
+import { routeTree } from './routeTree.gen'
+
+// Create a new router instance
+export const getRouter = () => {
+ return createRouter({
+ routeTree,
+ scrollRestoration: true,
+ defaultPreloadStaleTime: 0,
+ })
+}
diff --git a/examples/solid/start-bun/src/routes/__root.tsx b/examples/solid/start-bun/src/routes/__root.tsx
new file mode 100644
index 00000000000..890262db920
--- /dev/null
+++ b/examples/solid/start-bun/src/routes/__root.tsx
@@ -0,0 +1,61 @@
+import { TanStackDevtools } from '@tanstack/solid-devtools'
+import { HeadContent, Scripts, createRootRoute } from '@tanstack/solid-router'
+import { TanStackRouterDevtoolsPanel } from '@tanstack/solid-router-devtools'
+
+import { HydrationScript } from 'solid-js/web'
+import Header from '../components/Header'
+
+// import appCss from '../styles.css?url'
+import type { JSX } from 'solid-js'
+
+export const Route = createRootRoute({
+ head: () => ({
+ meta: [
+ {
+ charSet: 'utf-8',
+ },
+ {
+ name: 'viewport',
+ content: 'width=device-width, initial-scale=1',
+ },
+ {
+ title: 'TanStack Start Starter',
+ },
+ ],
+ links: [
+ // {
+ // rel: 'stylesheet',
+ // href: appCss,
+ // },
+ ],
+ }),
+
+ shellComponent: RootDocument,
+})
+
+function RootDocument({ children }: { children: JSX.Element }) {
+ return (
+
+
+
+
+
+
+
+ {children}
+ ,
+ },
+ ]}
+ />
+
+
+
+ )
+}
diff --git a/examples/solid/start-bun/src/routes/api.demo-names.ts b/examples/solid/start-bun/src/routes/api.demo-names.ts
new file mode 100644
index 00000000000..8dd0fea2970
--- /dev/null
+++ b/examples/solid/start-bun/src/routes/api.demo-names.ts
@@ -0,0 +1,15 @@
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/api/demo-names')({
+ server: {
+ handlers: {
+ GET: () => {
+ return new Response(JSON.stringify(['Alice', 'Bob', 'Charlie']), {
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ },
+ },
+ },
+})
diff --git a/examples/solid/start-bun/src/routes/demo.start.api-request.tsx b/examples/solid/start-bun/src/routes/demo.start.api-request.tsx
new file mode 100644
index 00000000000..e152aa31568
--- /dev/null
+++ b/examples/solid/start-bun/src/routes/demo.start.api-request.tsx
@@ -0,0 +1,42 @@
+import { createEffect, createSignal } from 'solid-js'
+import { createFileRoute } from '@tanstack/solid-router'
+
+function getNames() {
+ return fetch('/api/demo-names').then((res) => res.json())
+}
+
+export const Route = createFileRoute('/demo/start/api-request')({
+ component: Home,
+})
+
+function Home() {
+ const [names, setNames] = createSignal>([])
+
+ createEffect(() => {
+ getNames().then(setNames)
+ }, [])
+
+ return (
+
+
+
Start API Request Demo - Names List
+
+ {names().map((name) => (
+ -
+ {name}
+
+ ))}
+
+
+
+ )
+}
diff --git a/examples/solid/start-bun/src/routes/demo.start.server-funcs.tsx b/examples/solid/start-bun/src/routes/demo.start.server-funcs.tsx
new file mode 100644
index 00000000000..54561ecbb65
--- /dev/null
+++ b/examples/solid/start-bun/src/routes/demo.start.server-funcs.tsx
@@ -0,0 +1,96 @@
+import fs from 'node:fs'
+import { createSignal } from 'solid-js'
+import { createFileRoute, useRouter } from '@tanstack/solid-router'
+import { createServerFn } from '@tanstack/solid-start'
+
+const filePath = 'todos.json'
+
+async function readTodos() {
+ return JSON.parse(
+ await fs.promises.readFile(filePath, 'utf-8').catch(() =>
+ JSON.stringify(
+ [
+ { id: 1, name: 'Get groceries' },
+ { id: 2, name: 'Buy a new phone' },
+ ],
+ null,
+ 2,
+ ),
+ ),
+ )
+}
+
+const getTodos = createServerFn({
+ method: 'GET',
+}).handler(async () => await readTodos())
+
+const addTodo = createServerFn({ method: 'POST' })
+ .inputValidator((d: string) => d)
+ .handler(async ({ data }) => {
+ const todos = await readTodos()
+ todos.push({ id: todos.length + 1, name: data })
+ await fs.promises.writeFile(filePath, JSON.stringify(todos, null, 2))
+ return todos
+ })
+
+export const Route = createFileRoute('/demo/start/server-funcs')({
+ component: Home,
+ loader: async () => await getTodos(),
+})
+
+function Home() {
+ const router = useRouter()
+ let todos = Route.useLoaderData()
+
+ const [todo, setTodo] = createSignal('')
+
+ const submitTodo = async () => {
+ todos = await addTodo({ data: todo() })
+ setTodo('')
+ router.invalidate()
+ }
+
+ return (
+
+
+
Start Server Functions - Todo Example
+
+ {todos().map((t: any) => (
+ -
+ {t.name}
+
+ ))}
+
+
+ setTodo(e.target.value)}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter') {
+ submitTodo()
+ }
+ }}
+ placeholder="Enter a new todo..."
+ class="w-full px-4 py-3 rounded-lg border border-white/20 bg-white/10 backdrop-blur-sm text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent"
+ />
+
+
+
+
+ )
+}
diff --git a/examples/solid/start-bun/src/routes/index.tsx b/examples/solid/start-bun/src/routes/index.tsx
new file mode 100644
index 00000000000..244aacdd77b
--- /dev/null
+++ b/examples/solid/start-bun/src/routes/index.tsx
@@ -0,0 +1,39 @@
+import { createFileRoute } from '@tanstack/solid-router'
+import logo from '../logo.svg'
+
+export const Route = createFileRoute('/')({
+ component: App,
+})
+
+function App() {
+ return (
+
+
+
+
+ Edit src/routes/index.tsx and save to reload.
+
+
+ Learn React
+
+
+ Learn TanStack
+
+
+
+ )
+}
diff --git a/examples/solid/start-bun/src/styles.css b/examples/solid/start-bun/src/styles.css
new file mode 100644
index 00000000000..06f1bca4b05
--- /dev/null
+++ b/examples/solid/start-bun/src/styles.css
@@ -0,0 +1,15 @@
+@import 'tailwindcss';
+
+body {
+ @apply m-0;
+ font-family:
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
+ 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+code {
+ font-family:
+ source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
+}
diff --git a/examples/solid/start-bun/tsconfig.json b/examples/solid/start-bun/tsconfig.json
new file mode 100644
index 00000000000..70c9888deae
--- /dev/null
+++ b/examples/solid/start-bun/tsconfig.json
@@ -0,0 +1,36 @@
+{
+ "include": [
+ "**/*.ts",
+ "**/*.tsx",
+ "eslint.config.js",
+ "prettier.config.js",
+ "vite.config.js"
+ ],
+
+ "compilerOptions": {
+ "target": "ES2022",
+ "jsx": "preserve",
+ "jsxImportSource": "solid-js",
+ "module": "ESNext",
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "types": ["vite/client", "bun"],
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": false,
+ "noEmit": true,
+
+ /* Linting */
+ "skipLibCheck": true,
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/examples/solid/start-bun/vite.config.ts b/examples/solid/start-bun/vite.config.ts
new file mode 100644
index 00000000000..6d291c81dd5
--- /dev/null
+++ b/examples/solid/start-bun/vite.config.ts
@@ -0,0 +1,19 @@
+import { defineConfig } from 'vite'
+import { tanstackStart } from '@tanstack/solid-start/plugin/vite'
+import viteSolid from 'vite-plugin-solid'
+import viteTsConfigPaths from 'vite-tsconfig-paths'
+import tailwindcss from '@tailwindcss/vite'
+
+const config = defineConfig({
+ plugins: [
+ // this is the plugin that enables path aliases
+ viteTsConfigPaths({
+ projects: ['./tsconfig.json'],
+ }),
+ tailwindcss(),
+ tanstackStart(),
+ viteSolid(),
+ ],
+})
+
+export default config
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 868c3a3cd0f..4e4433c899a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7627,6 +7627,76 @@ importers:
specifier: ^5.1.4
version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+ examples/solid/start-bun:
+ dependencies:
+ '@tailwindcss/vite':
+ specifier: ^4.1.13
+ version: 4.1.17(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+ '@tanstack/router-plugin':
+ specifier: workspace:*
+ version: link:../../../packages/router-plugin
+ '@tanstack/solid-devtools':
+ specifier: ^0.7.0
+ version: 0.7.14(csstype@3.1.3)(solid-js@1.9.10)
+ '@tanstack/solid-router':
+ specifier: ^1.135.2
+ version: link:../../../packages/solid-router
+ '@tanstack/solid-router-devtools':
+ specifier: workspace:^
+ version: link:../../../packages/solid-router-devtools
+ '@tanstack/solid-router-ssr-query':
+ specifier: workspace:*
+ version: link:../../../packages/solid-router-ssr-query
+ '@tanstack/solid-start':
+ specifier: workspace:*
+ version: link:../../../packages/solid-start
+ solid-js:
+ specifier: 1.9.10
+ version: 1.9.10
+ tailwindcss:
+ specifier: ^4.1.13
+ version: 4.1.17
+ vite-tsconfig-paths:
+ specifier: ^5.1.4
+ version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+ devDependencies:
+ '@solidjs/testing-library':
+ specifier: ^0.8.10
+ version: 0.8.10(solid-js@1.9.10)
+ '@tanstack/eslint-config':
+ specifier: ^0.3.2
+ version: 0.3.2(@typescript-eslint/utils@8.44.1(eslint@9.22.0(jiti@2.6.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.22.0(jiti@2.6.1))(typescript@5.9.2)
+ '@testing-library/dom':
+ specifier: ^10.4.1
+ version: 10.4.1
+ '@types/bun':
+ specifier: ^1.2.22
+ version: 1.2.22(@types/react@19.2.2)
+ '@types/node':
+ specifier: 22.10.2
+ version: 22.10.2
+ jsdom:
+ specifier: ^27.0.0
+ version: 27.0.0(postcss@8.5.6)
+ prettier:
+ specifier: ^3.6.2
+ version: 3.6.2
+ typescript:
+ specifier: ^5.9.2
+ version: 5.9.2
+ vite:
+ specifier: ^7.1.7
+ version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+ vite-plugin-solid:
+ specifier: ^2.11.10
+ version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.10)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+ vitest:
+ specifier: ^3.2.4
+ version: 3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+ web-vitals:
+ specifier: ^5.1.0
+ version: 5.1.0
+
examples/solid/start-convex-better-auth:
dependencies:
'@convex-dev/better-auth':
@@ -12426,11 +12496,21 @@ packages:
peerDependencies:
solid-js: 1.9.10
+ '@solid-primitives/event-listener@2.4.3':
+ resolution: {integrity: sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg==}
+ peerDependencies:
+ solid-js: 1.9.10
+
'@solid-primitives/keyboard@1.3.0':
resolution: {integrity: sha512-0QX9O3eUaQorNNmXZn8a4efSByayIScVq+iGSwheD7m3SL/ACLM5oZlCNpTPLcemnVVfUPAHFiViEj86XpN5qw==}
peerDependencies:
solid-js: 1.9.10
+ '@solid-primitives/keyboard@1.3.3':
+ resolution: {integrity: sha512-9dQHTTgLBqyAI7aavtO+HnpTVJgWQA1ghBSrmLtMu1SMxLPDuLfuNr+Tk5udb4AL4Ojg7h9JrKOGEEDqsJXWJA==}
+ peerDependencies:
+ solid-js: 1.9.10
+
'@solid-primitives/media@2.3.0':
resolution: {integrity: sha512-7+C3wfbWnGE/WPoNsqcp/EeOP2aNNB92RCpsWhBth8E5lZo/J+rK6jMb7umVsK0zguT8HBpeXp1pFyFbcsHStA==}
peerDependencies:
@@ -12451,11 +12531,21 @@ packages:
peerDependencies:
solid-js: 1.9.10
+ '@solid-primitives/resize-observer@2.1.3':
+ resolution: {integrity: sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ==}
+ peerDependencies:
+ solid-js: 1.9.10
+
'@solid-primitives/rootless@1.5.0':
resolution: {integrity: sha512-YJ+EveQeDv9DLqfDKfsPAAGy2x3vBruoD23yn+nD2dT84QjoBxWT1T0qA0TMFjek6/xuN3flqnHtQ4r++4zdjg==}
peerDependencies:
solid-js: 1.9.10
+ '@solid-primitives/rootless@1.5.2':
+ resolution: {integrity: sha512-9HULb0QAzL2r47CCad0M+NKFtQ+LrGGNHZfteX/ThdGvKIg2o2GYhBooZubTCd/RTu2l2+Nw4s+dEfiDGvdrrQ==}
+ peerDependencies:
+ solid-js: 1.9.10
+
'@solid-primitives/scheduled@1.5.0':
resolution: {integrity: sha512-RVw24IRNh1FQ4DCMb3OahB70tXIwc5vH8nhR4nNPsXwUPQeuOkLsDI5BlxaPk0vyZgqw9lDpufgI3HnPwplgDw==}
peerDependencies:
@@ -12471,6 +12561,11 @@ packages:
peerDependencies:
solid-js: 1.9.10
+ '@solid-primitives/static-store@0.1.2':
+ resolution: {integrity: sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw==}
+ peerDependencies:
+ solid-js: 1.9.10
+
'@solid-primitives/styles@0.0.114':
resolution: {integrity: sha512-SFXr16mgr6LvZAIj6L7i59HHg+prAmIF8VP/U3C6jSHz68Eh1G71vaWr9vlJVpy/j6bh1N8QUzu5CgtvIC92OQ==}
peerDependencies:
@@ -12481,6 +12576,11 @@ packages:
peerDependencies:
solid-js: 1.9.10
+ '@solid-primitives/utils@6.3.2':
+ resolution: {integrity: sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==}
+ peerDependencies:
+ solid-js: 1.9.10
+
'@solidjs/meta@0.29.4':
resolution: {integrity: sha512-zdIWBGpR9zGx1p1bzIPqF5Gs+Ks/BH8R6fWhmUa/dcK1L2rUC8BAcZJzNRYBQv74kScf1TSOs0EY//Vd/I0V8g==}
peerDependencies:
@@ -12982,22 +13082,46 @@ packages:
resolution: {integrity: sha512-7Wwfw6wBv2Kc+OBNIJQzBSJ6q7GABtwVT+VOQ/7/Gl7z8z1rtEYUZrxUrNvbbrHY+J5/WNZNZjJjTWDf8nTUBw==}
engines: {node: '>=18'}
+ '@tanstack/devtools-client@0.0.4':
+ resolution: {integrity: sha512-LefnH9KE9uRDEWifc3QDcooskA8ikfs41bybDTgpYQpyTUspZnaEdUdya9Hry0KYxZ8nos0S3nNbsP79KHqr6Q==}
+ engines: {node: '>=18'}
+
'@tanstack/devtools-event-bus@0.3.2':
resolution: {integrity: sha512-yJT2As/drc+Epu0nsqCsJaKaLcaNGufiNxSlp/+/oeTD0jsBxF9/PJBfh66XVpYXkKr97b8689mSu7QMef0Rrw==}
engines: {node: '>=18'}
+ '@tanstack/devtools-event-bus@0.3.3':
+ resolution: {integrity: sha512-lWl88uLAz7ZhwNdLH6A3tBOSEuBCrvnY9Fzr5JPdzJRFdM5ZFdyNWz1Bf5l/F3GU57VodrN0KCFi9OA26H5Kpg==}
+ engines: {node: '>=18'}
+
+ '@tanstack/devtools-event-client@0.3.4':
+ resolution: {integrity: sha512-eq+PpuutUyubXu+ycC1GIiVwBs86NF/8yYJJAKSpPcJLWl6R/761F1H4F/9ziX6zKezltFUH1ah3Cz8Ah+KJrw==}
+ engines: {node: '>=18'}
+
'@tanstack/devtools-ui@0.3.5':
resolution: {integrity: sha512-DU8OfLntngnph+Tb7ivQvh4F4w+rDu6r01fXlhjq/Nmgdr0gtsOox4kdmyq5rCs+C6aPgP3M7+BE+fv4dN+VvA==}
engines: {node: '>=18'}
peerDependencies:
solid-js: 1.9.10
+ '@tanstack/devtools-ui@0.4.4':
+ resolution: {integrity: sha512-5xHXFyX3nom0UaNfiOM92o6ziaHjGo3mcSGe2HD5Xs8dWRZNpdZ0Smd0B9ddEhy0oB+gXyMzZgUJb9DmrZV0Mg==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ solid-js: 1.9.10
+
'@tanstack/devtools@0.6.14':
resolution: {integrity: sha512-dOtHoeLjjcHeNscu+ZEf89EFboQsy0ggb6pf8Sha59qBUeQbjUsaAvwP8Ogwg89oJxFQbTP7DKYNBNw5CxlNEA==}
engines: {node: '>=18'}
peerDependencies:
solid-js: 1.9.10
+ '@tanstack/devtools@0.8.1':
+ resolution: {integrity: sha512-ZyKX+IJvMaTY0TywdA6r6kbD6V+0dxWQVDGC3jd2q4RP9OMHzpXd0cKreDvqOGrAPtEUXpGBxW0AtsaauDWurQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ solid-js: 1.9.10
+
'@tanstack/eslint-config@0.3.2':
resolution: {integrity: sha512-2g+PuGR3GuvvCiR3xZs+IMqAvnYU9bvH+jRml0BFBSxHBj22xFCTNvJWhvgj7uICFF9IchDkFUto91xDPMu5cg==}
engines: {node: '>=18'}
@@ -13056,6 +13180,12 @@ packages:
react: ^19.2.0
react-dom: ^19.2.0
+ '@tanstack/solid-devtools@0.7.14':
+ resolution: {integrity: sha512-hyaB29d1fU2n9v2XeFEB6t2k5gKionK8mxxb9MNtF7qJheZ6z9259jU8OsBdA/f6v2oYck1K1Ia9+ooJsdy4jg==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ solid-js: 1.9.10
+
'@tanstack/solid-query-devtools@5.72.2':
resolution: {integrity: sha512-duYFN6EMsV0iwz1vV60GvxsQy3PXycgHhrucaik2yvJlRKrEYuHTYGqpRTy+P3JrFZkEzVLjevMnbzR4IIt5vw==}
peerDependencies:
@@ -23541,6 +23671,11 @@ snapshots:
'@solid-primitives/utils': 6.3.0(solid-js@1.9.10)
solid-js: 1.9.10
+ '@solid-primitives/event-listener@2.4.3(solid-js@1.9.10)':
+ dependencies:
+ '@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
+ solid-js: 1.9.10
+
'@solid-primitives/keyboard@1.3.0(solid-js@1.9.10)':
dependencies:
'@solid-primitives/event-listener': 2.4.0(solid-js@1.9.10)
@@ -23548,6 +23683,13 @@ snapshots:
'@solid-primitives/utils': 6.3.0(solid-js@1.9.10)
solid-js: 1.9.10
+ '@solid-primitives/keyboard@1.3.3(solid-js@1.9.10)':
+ dependencies:
+ '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10)
+ '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10)
+ '@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
+ solid-js: 1.9.10
+
'@solid-primitives/media@2.3.0(solid-js@1.9.10)':
dependencies:
'@solid-primitives/event-listener': 2.4.0(solid-js@1.9.10)
@@ -23573,11 +23715,24 @@ snapshots:
'@solid-primitives/utils': 6.3.0(solid-js@1.9.10)
solid-js: 1.9.10
+ '@solid-primitives/resize-observer@2.1.3(solid-js@1.9.10)':
+ dependencies:
+ '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10)
+ '@solid-primitives/rootless': 1.5.2(solid-js@1.9.10)
+ '@solid-primitives/static-store': 0.1.2(solid-js@1.9.10)
+ '@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
+ solid-js: 1.9.10
+
'@solid-primitives/rootless@1.5.0(solid-js@1.9.10)':
dependencies:
'@solid-primitives/utils': 6.3.0(solid-js@1.9.10)
solid-js: 1.9.10
+ '@solid-primitives/rootless@1.5.2(solid-js@1.9.10)':
+ dependencies:
+ '@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
+ solid-js: 1.9.10
+
'@solid-primitives/scheduled@1.5.0(solid-js@1.9.10)':
dependencies:
solid-js: 1.9.10
@@ -23592,6 +23747,11 @@ snapshots:
'@solid-primitives/utils': 6.3.0(solid-js@1.9.10)
solid-js: 1.9.10
+ '@solid-primitives/static-store@0.1.2(solid-js@1.9.10)':
+ dependencies:
+ '@solid-primitives/utils': 6.3.2(solid-js@1.9.10)
+ solid-js: 1.9.10
+
'@solid-primitives/styles@0.0.114(solid-js@1.9.10)':
dependencies:
'@solid-primitives/rootless': 1.5.0(solid-js@1.9.10)
@@ -23602,6 +23762,10 @@ snapshots:
dependencies:
solid-js: 1.9.10
+ '@solid-primitives/utils@6.3.2(solid-js@1.9.10)':
+ dependencies:
+ solid-js: 1.9.10
+
'@solidjs/meta@0.29.4(solid-js@1.9.10)':
dependencies:
solid-js: 1.9.10
@@ -24029,6 +24193,10 @@ snapshots:
- typescript
- vite
+ '@tanstack/devtools-client@0.0.4':
+ dependencies:
+ '@tanstack/devtools-event-client': 0.3.4
+
'@tanstack/devtools-event-bus@0.3.2':
dependencies:
ws: 8.18.3
@@ -24036,6 +24204,15 @@ snapshots:
- bufferutil
- utf-8-validate
+ '@tanstack/devtools-event-bus@0.3.3':
+ dependencies:
+ ws: 8.18.3
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+
+ '@tanstack/devtools-event-client@0.3.4': {}
+
'@tanstack/devtools-ui@0.3.5(csstype@3.1.3)(solid-js@1.9.10)':
dependencies:
clsx: 2.1.1
@@ -24044,6 +24221,14 @@ snapshots:
transitivePeerDependencies:
- csstype
+ '@tanstack/devtools-ui@0.4.4(csstype@3.1.3)(solid-js@1.9.10)':
+ dependencies:
+ clsx: 2.1.1
+ goober: 2.1.16(csstype@3.1.3)
+ solid-js: 1.9.10
+ transitivePeerDependencies:
+ - csstype
+
'@tanstack/devtools@0.6.14(csstype@3.1.3)(solid-js@1.9.10)':
dependencies:
'@solid-primitives/keyboard': 1.3.0(solid-js@1.9.10)
@@ -24057,6 +24242,22 @@ snapshots:
- csstype
- utf-8-validate
+ '@tanstack/devtools@0.8.1(csstype@3.1.3)(solid-js@1.9.10)':
+ dependencies:
+ '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.10)
+ '@solid-primitives/keyboard': 1.3.3(solid-js@1.9.10)
+ '@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.10)
+ '@tanstack/devtools-client': 0.0.4
+ '@tanstack/devtools-event-bus': 0.3.3
+ '@tanstack/devtools-ui': 0.4.4(csstype@3.1.3)(solid-js@1.9.10)
+ clsx: 2.1.1
+ goober: 2.1.16(csstype@3.1.3)
+ solid-js: 1.9.10
+ transitivePeerDependencies:
+ - bufferutil
+ - csstype
+ - utf-8-validate
+
'@tanstack/eslint-config@0.3.2(@typescript-eslint/utils@8.44.1(eslint@9.22.0(jiti@2.6.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.22.0(jiti@2.6.1))(typescript@5.9.2)':
dependencies:
'@eslint/js': 9.36.0
@@ -24133,6 +24334,15 @@ snapshots:
react: 19.2.0
react-dom: 19.2.0(react@19.2.0)
+ '@tanstack/solid-devtools@0.7.14(csstype@3.1.3)(solid-js@1.9.10)':
+ dependencies:
+ '@tanstack/devtools': 0.8.1(csstype@3.1.3)(solid-js@1.9.10)
+ solid-js: 1.9.10
+ transitivePeerDependencies:
+ - bufferutil
+ - csstype
+ - utf-8-validate
+
'@tanstack/solid-query-devtools@5.72.2(@tanstack/solid-query@5.90.9(solid-js@1.9.10))(solid-js@1.9.10)':
dependencies:
'@tanstack/query-devtools': 5.72.2
From b16000dd74780a89ecfe44233e40306a1c43c33c Mon Sep 17 00:00:00 2001
From: Birk Skyum
Date: Tue, 11 Nov 2025 03:50:09 +0100
Subject: [PATCH 2/3] fix ssr
---
examples/solid/start-bun/src/routes/__root.tsx | 10 +++++-----
examples/solid/start-bun/vite.config.ts | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/examples/solid/start-bun/src/routes/__root.tsx b/examples/solid/start-bun/src/routes/__root.tsx
index 890262db920..99c515ded4f 100644
--- a/examples/solid/start-bun/src/routes/__root.tsx
+++ b/examples/solid/start-bun/src/routes/__root.tsx
@@ -5,7 +5,7 @@ import { TanStackRouterDevtoolsPanel } from '@tanstack/solid-router-devtools'
import { HydrationScript } from 'solid-js/web'
import Header from '../components/Header'
-// import appCss from '../styles.css?url'
+import appCss from '../styles.css?url'
import type { JSX } from 'solid-js'
export const Route = createRootRoute({
@@ -23,10 +23,10 @@ export const Route = createRootRoute({
},
],
links: [
- // {
- // rel: 'stylesheet',
- // href: appCss,
- // },
+ {
+ rel: 'stylesheet',
+ href: appCss,
+ },
],
}),
diff --git a/examples/solid/start-bun/vite.config.ts b/examples/solid/start-bun/vite.config.ts
index 6d291c81dd5..0a49792ba5b 100644
--- a/examples/solid/start-bun/vite.config.ts
+++ b/examples/solid/start-bun/vite.config.ts
@@ -12,7 +12,7 @@ const config = defineConfig({
}),
tailwindcss(),
tanstackStart(),
- viteSolid(),
+ viteSolid({ ssr: true }),
],
})
From bcf58fd50d0adeeafe57328526d6a66944a545dd Mon Sep 17 00:00:00 2001
From: Birk Skyum
Date: Tue, 11 Nov 2025 03:59:00 +0100
Subject: [PATCH 3/3] refresh logo
---
examples/solid/start-bun/public/logo192.png | Bin 5347 -> 0 bytes
examples/solid/start-bun/public/logo512.png | Bin 9664 -> 0 bytes
examples/solid/start-bun/src/logo.svg | 13 +------------
.../src/routes/demo.start.server-funcs.tsx | 6 +++---
examples/solid/start-bun/src/routes/index.tsx | 4 ++--
5 files changed, 6 insertions(+), 17 deletions(-)
delete mode 100644 examples/solid/start-bun/public/logo192.png
delete mode 100644 examples/solid/start-bun/public/logo512.png
diff --git a/examples/solid/start-bun/public/logo192.png b/examples/solid/start-bun/public/logo192.png
deleted file mode 100644
index fc44b0a3796c0e0a64c3d858ca038bd4570465d9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 5347
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
b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN
diff --git a/examples/solid/start-bun/src/logo.svg b/examples/solid/start-bun/src/logo.svg
index fe53fe8d0d2..76c8c2ab6ce 100644
--- a/examples/solid/start-bun/src/logo.svg
+++ b/examples/solid/start-bun/src/logo.svg
@@ -1,12 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/examples/solid/start-bun/src/routes/demo.start.server-funcs.tsx b/examples/solid/start-bun/src/routes/demo.start.server-funcs.tsx
index 54561ecbb65..4e96ec85f3e 100644
--- a/examples/solid/start-bun/src/routes/demo.start.server-funcs.tsx
+++ b/examples/solid/start-bun/src/routes/demo.start.server-funcs.tsx
@@ -40,14 +40,14 @@ export const Route = createFileRoute('/demo/start/server-funcs')({
function Home() {
const router = useRouter()
- let todos = Route.useLoaderData()
+ const todos = Route.useLoaderData()
const [todo, setTodo] = createSignal('')
const submitTodo = async () => {
- todos = await addTodo({ data: todo() })
+ await addTodo({ data: todo() })
setTodo('')
- router.invalidate()
+ await router.invalidate()
}
return (
diff --git a/examples/solid/start-bun/src/routes/index.tsx b/examples/solid/start-bun/src/routes/index.tsx
index 244aacdd77b..a883efcc92c 100644
--- a/examples/solid/start-bun/src/routes/index.tsx
+++ b/examples/solid/start-bun/src/routes/index.tsx
@@ -19,11 +19,11 @@ function App() {
- Learn React
+ Learn Solid