fix: updated tanstack start to avoid vinxi issues#53
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR migrates from Vinxi to a Vite-based setup with the TanStack Start plugin, standardizes API route exports, and aligns package scripts and dependencies accordingly.
- Introduce
vite.config.tswith@tanstack/react-start/plugin/vite, TS path aliases, and Tailwind CSS; remove legacyapp.config.ts. - Rename API route exports in
models.tsandchat.tsfromAPIRoutetoroute. - Update
package.jsonscripts to use Vite commands, adjust TanStack package versions, and add an override for@tanstack/react-router.
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| vite.config.ts | Add Vite config with TanStack Start, TS paths, and Tailwind plugins. |
| app.config.ts | Remove obsolete TanStack React Start config file. |
| src/routes/api/models.ts | Rename exported API route constant from APIRoute to route. |
| src/routes/api/chat.ts | Rename exported API route constant from APIRoute to route. |
| src/routeTree.gen.ts | Update generated aliases and references for root and index routes. |
| package.json | Switch scripts to Vite, adjust TanStack dependency versions, add override. |
Comments suppressed due to low confidence (3)
src/routes/api/models.ts:17
- [nitpick] The generic export name
routemay be ambiguous when imported; consider using a more descriptive name likemodelsRouteto clarify its purpose.
export const route = createAPIFileRoute('/api/models')({
src/routes/api/chat.ts:7
- [nitpick] The generic export name
routemay be ambiguous when imported; consider using a more descriptive name likechatRouteto clarify its purpose.
export const route = createAPIFileRoute('/api/chat')({
package.json:26
- Downgrading
@tanstack/react-queryfrom^5.77.2to^5.66.5may introduce compatibility issues; please confirm that this version change aligns with other TanStack dependencies.
"@tanstack/react-query": "^5.66.5",
fdbe752 to
1b27025
Compare
1b27025 to
53110ca
Compare
zeucapua
left a comment
There was a problem hiding this comment.
Docker and running the dev server works fine, just getting a few errors on the console.
| @@ -1,11 +1,11 @@ | |||
| import { createAPIFileRoute } from '@tanstack/react-start/api' | |||
There was a problem hiding this comment.
The routes build fine now and work.
❯ nr build
> build
> vite build
vite v6.3.5 building for production...
Generated route tree in 49ms
✓ 2131 modules transformed.
.tanstack/start/build/client-dist/.vite/manifest.json 0.75 kB │ gzip: 0.29 kB
.tanstack/start/build/client-dist/assets/styles-CQwW1aux.css 40.46 kB │ gzip: 8.22 kB
.tanstack/start/build/client-dist/assets/index-Cial-gel.js 225.23 kB │ gzip: 65.85 kB
.tanstack/start/build/client-dist/assets/main-ZcC2hSab.js 420.19 kB │ gzip: 134.14 kB
✓ built in 1.40s
vite v6.3.5 building SSR bundle for production...
"H3Error", "MIMES", "callNodeListener", "createApp", "createAppEventHandler", "createError", "createEvent", "createRouter", "defineLazyEventHandler", "defineNodeListener", "defineNodeMiddleware", "defineRequestMiddleware", "defineResponseMiddleware", "defineWebSocket", "dynamicEventHandler", "fromNodeMiddleware", "fromPlainHandler", "fromWebHandler", "isCorsOriginAllowed", "isError", "isEventHandler", "isStream", "isWebResponse", "lazyEventHandler", "promisifyNodeListener", "sanitizeStatusCode", "sanitizeStatusMessage", "serveStatic", "splitCookiesString", "toEventHandler", "toNodeListener", "toPlainHandler", "toWebHandler" and "useBase" are imported from external module "h3" but never used in "node_modules/@tanstack/start-server-core/dist/esm/h3.js" and "node_modules/@tanstack/start-server-core/dist/esm/index.js".
"default" is imported from external module "react" but never used in "src/contexts/UserContext.tsx", "src/hooks/useLocalStorage.ts", "src/contexts/ModelContext.tsx", "src/components/ui/button.tsx", "src/components/ThemeToggle.tsx", "src/components/ui/dropdown-menu.tsx", "src/components/Header.tsx", "src/components/ServerSelector.tsx", "src/components/ui/textarea.tsx", "src/components/ChatInput.tsx" and "src/components/Chat.tsx".
✓ 61 modules transformed.
[plugin vite:css-post] Sourcemap is likely to be incorrect: a plugin (vite:css-post) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
✓ built in 128ms
✔ Generated public .output/public nitro 5:49:44 PM
ℹ Building Nitro Server (preset: node-server, compatibility date: 2024-11-13) nitro 5:49:44 PM
✔ Nitro Server built nitro 5:49:46 PM
├─ .output/server/chunks/_/_tanstack-start-manifest_v-CevWQBeX.mjs (661 B) (328 B gzip)
├─ .output/server/chunks/_/_tanstack-start-manifest_v-CevWQBeX.mjs.map (126 B) (124 B gzip)
├─ .output/server/chunks/_/_tanstack-start-server-fn-manifest_v-DtgTK7xl.mjs (177 B) (142 B gzip)
├─ .output/server/chunks/_/_tanstack-start-server-fn-manifest_v-DtgTK7xl.mjs.map (136 B) (130 B gzip)
├─ .output/server/chunks/_/index-fZH4EjzZ.mjs (22.9 kB) (5.62 kB gzip)
├─ .output/server/chunks/_/index-fZH4EjzZ.mjs.map (17.4 kB) (4.35 kB gzip)
├─ .output/server/chunks/_/ssr.mjs (82.3 kB) (19.7 kB gzip)
├─ .output/server/chunks/_/ssr.mjs.map (275 B) (192 B gzip)
├─ .output/server/index.mjs (149 kB) (37 kB gzip)
└─ .output/server/package.json (4.94 kB) (1.45 kB gzip)
Σ Total size: 5.27 MB (1.25 MB gzip)
✔ You can preview this build using node .output/server/index.mjs nitro 5:49:46 PM
✔ Client and Server bundles for TanStack Start have been successfully built.
If you regenerate the routes if in dev mode or via npx @tanstack/router-cli@latest generate, it's normal to see a message like this for the moment. They're still sorting some stuff out in the devinxied Tanstack start, but the routes do work.
❯ npx @tanstack/router-cli@latest generate
Route file "import { createServerFileRoute } from '@tanstack/react-start/server'
import { chatRequestSchema } from '../../lib/schemas'
import OpenAI from 'openai'
import type { Tool } from 'openai/resources/responses/responses.mjs'
import { streamText } from '../../lib/streaming'
export const ServerRoute = createServerFileRoute('/api/chat').methods({
async POST({ request }) {
const bearerToken = request.headers.get('Authorization')?.split(' ')[1]
try {
const body = await request.json()
// Ensure messages have the correct structure before validation
const formattedBody = {
...body,
messages: body.messages.map((msg: any) => ({
...msg,
parts: [
{
type: 'text',
text: msg.content,
},
],
})),
}
const result = chatRequestSchema.safeParse(formattedBody)
if (!result.success) {
console.error('Validation error:', result.error.errors)
return new Response(JSON.stringify({ error: result.error.errors }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
})
}
const { messages, servers, model } = result.data
if (messages.length === 0) {
return new Response(JSON.stringify({ error: 'No messages provided' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
})
}
// Function to sanitize server labels for OpenAI API requirements
const sanitizeServerLabel = (name: string): string => {
return name
.replace(/[^a-zA-Z0-9\-_]/g, '_') // Replace invalid chars with underscore
.replace(/^[^a-zA-Z]/, 'server_') // Ensure it starts with a letter
.replace(/_{2,}/g, '_') // Replace multiple underscores with single one
}
const tools = Object.entries(servers)
.filter(([_, server]) => server.status === 'connected')
.map(([_id, server]) => ({
type: 'mcp',
server_label: sanitizeServerLabel(server.name),
server_url: server.url,
require_approval: 'never',
headers: {
Authorization: `Bearer ${bearerToken}`,
},
})) satisfies Tool[]
// Format the conversation history into a single input string with proper message parts
const input = messages
.map((msg) => ({
role: msg.role,
parts: [
{
type: 'text',
text: msg.content,
},
],
}))
.map(
(msg) =>
`${msg.role === 'user' ? 'User' : 'Assistant'}: ${msg.parts[0].text}`,
)
.join('\n\n')
const client = new OpenAI()
const answer = await client.responses.create({
model,
tools,
input,
stream: true,
})
return streamText(answer)
} catch (error) {
console.error('Error in chat route:', error)
return new Response(JSON.stringify({ error: 'Internal server error' }), {
status: 500,
headers: { 'Content-Type': 'application/json' },
})
}
},
})
" does not export any route piece. This is likely a mistake.
Route file "import { createServerFileRoute } from '@tanstack/react-start/server'
import OpenAI from 'openai'
const SUPPORTED_MODEL_PREFIXES = [
'gpt-4o',
'chatgpt-4o',
'gpt-4.1',
'o1',
'o3',
'o4-mini',
]
function isSupportedModel(id: string) {
return SUPPORTED_MODEL_PREFIXES.some((prefix) => id.startsWith(prefix))
}
export const ServerRoute = createServerFileRoute('/api/models').methods({
async GET({ request }) {
try {
const client = new OpenAI()
const models = await client.models.list()
const filtered = models.data
.filter((model) => isSupportedModel(model.id))
.sort((a, b) => a.id.localeCompare(b.id))
return new Response(JSON.stringify(filtered), {
headers: { 'Content-Type': 'application/json' },
})
} catch (error) {
console.error('Error fetching models:', error)
return new Response(JSON.stringify({ error: 'Failed to fetch models' }), {
status: 500,
headers: { 'Content-Type': 'application/json' },
})
}
},
})
" does not export any route piece. This is likely a mistake.
Generated route tree in 71ms
Docker builds were failing and local builds started failing yesterday. Tanstack start removed vinxi, and we were running into issues where some dependencies, most likely due to `^` in package json versions, were not compatible with our current tanstack setup. I pulled all depenencies related to tanstack start from a newly created tanstack start project and removed vinxi, added vite as per the new setup, and modified some api routes that required a change. Since tanstack no longer uses vinxi, there is also no longer an app.config.ts. It's been replaced with a vite.config.ts.
Docker builds were failing and local builds started failing yesterday. Tanstack start removed vinxi, and we were running into issues where some dependencies, most likely due to `^` in package json versions, were not compatible with our current tanstack setup. I pulled all depenencies related to tanstack start from a newly created tanstack start project and removed vinxi, added vite as per the new setup, and modified some api routes that required a change. Since tanstack no longer uses vinxi, there is also no longer an app.config.ts. It's been replaced with a vite.config.ts.
Docker builds were failing and local builds started failing yesterday. Tanstack start removed vinxi, and we were running into issues where some dependencies, most likely due to
^in package json versions, were not compatible with our current tanstack setup.I pulled all depenencies related to tanstack start from a newly created tanstack start project and removed vinxi, added vite as per the new setup, and modified some api routes that required a change.
Since tanstack no longer uses vinxi, there is also no longer an app.config.ts. It's been replaced with a vite.config.ts.