CLI: Support Tanstack Start SPA

This commit is contained in:
Fuma Nama
2025-10-28 23:58:06 +08:00
parent 3668bafcad
commit eece4f8f92
34 changed files with 622 additions and 91 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'create-fumadocs-app': patch
---
Support Tanstack Start SPA
+1 -5
View File
@@ -1,18 +1,14 @@
node_modules
package-lock.json
yarn.lock
.DS_Store
.cache
.env
.vercel
.output
.nitro
/build/
/api/
/server/build
/public/build# Sentry Config File
.env.sentry-build-plugin
/public/build
/test-results/
/playwright-report/
/blob-report/
@@ -4,7 +4,7 @@ description: Your favourite docs framework.
icon: Rocket
---
Hey there! Fumadocs is a docs framework built for Next.js, but do you know it also works on Tanstack Start?
Hey there! Fumadocs is the docs framework that also works on Tanstack Start!
## Heading
+3 -1
View File
@@ -6,9 +6,10 @@
"scripts": {
"dev": "vite dev",
"build": "vite build",
"start": "node dist/server/server.js"
"start": "serve dist/client"
},
"dependencies": {
"@orama/orama": "^3.1.16",
"@tanstack/react-router": "^1.133.32",
"@tanstack/react-router-devtools": "^1.133.34",
"@tanstack/react-start": "^1.133.34",
@@ -29,6 +30,7 @@
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"@vitejs/plugin-react": "^5.1.0",
"serve": "^14.2.5",
"tailwindcss": "^4.1.16",
"typescript": "^5.9.3",
"vite-tsconfig-paths": "^5.1.4"
@@ -0,0 +1,51 @@
'use client';
import {
SearchDialog,
SearchDialogClose,
SearchDialogContent,
SearchDialogHeader,
SearchDialogIcon,
SearchDialogInput,
SearchDialogList,
SearchDialogOverlay,
type SharedProps,
} from 'fumadocs-ui/components/dialog/search';
import { useDocsSearch } from 'fumadocs-core/search/client';
import { create } from '@orama/orama';
import { useI18n } from 'fumadocs-ui/contexts/i18n';
function initOrama() {
return create({
schema: { _: 'string' },
// https://docs.orama.com/docs/orama-js/supported-languages
language: 'english',
});
}
export default function DefaultSearchDialog(props: SharedProps) {
const { locale } = useI18n(); // (optional) for i18n
const { search, setSearch, query } = useDocsSearch({
type: 'static',
initOrama,
locale,
});
return (
<SearchDialog
search={search}
onSearchChange={setSearch}
isLoading={query.isLoading}
{...props}
>
<SearchDialogOverlay />
<SearchDialogContent>
<SearchDialogHeader>
<SearchDialogIcon />
<SearchDialogInput />
<SearchDialogClose />
</SearchDialogHeader>
<SearchDialogList items={query.data !== 'empty' ? query.data : null} />
</SearchDialogContent>
</SearchDialog>
);
}
@@ -7,6 +7,7 @@ import {
import * as React from 'react';
import appCss from '@/styles/app.css?url';
import { RootProvider } from 'fumadocs-ui/provider/tanstack';
import SearchDialog from '@/components/search';
export const Route = createRootRoute({
head: () => ({
@@ -42,7 +43,7 @@ function RootDocument({ children }: { children: React.ReactNode }) {
<HeadContent />
</head>
<body className="flex flex-col min-h-screen">
<RootProvider>{children}</RootProvider>
<RootProvider search={{ SearchDialog }}>{children}</RootProvider>
<Scripts />
</body>
</html>
@@ -10,7 +10,7 @@ const server = createFromSource(source, {
export const Route = createFileRoute('/api/search')({
server: {
handlers: {
GET: async ({ request }) => server.GET(request),
GET: () => server.staticGET(),
},
},
});
@@ -75,28 +75,35 @@ function Page() {
);
}
function transformPageTree(tree: PageTree.Folder): PageTree.Folder {
function transform<T extends PageTree.Item | PageTree.Separator>(item: T) {
if (typeof item.icon !== 'string') return item;
function transformPageTree(root: PageTree.Root): PageTree.Root {
function mapNode<T extends PageTree.Node>(item: T): T {
if (typeof item.icon === 'string') {
item = {
...item,
icon: (
<span
dangerouslySetInnerHTML={{
__html: item.icon,
}}
/>
),
};
}
return {
...item,
icon: (
<span
dangerouslySetInnerHTML={{
__html: item.icon,
}}
/>
),
};
if (item.type === 'folder') {
return {
...item,
index: item.index ? mapNode(item.index) : undefined,
children: item.children.map(mapNode),
};
}
return item;
}
return {
...tree,
index: tree.index ? transform(tree.index) : undefined,
children: tree.children.map((item) => {
if (item.type === 'folder') return transformPageTree(item);
return transform(item);
}),
...root,
children: root.children.map(mapNode),
fallback: root.fallback ? transformPageTree(root.fallback) : undefined,
};
}
+2 -1
View File
@@ -24,12 +24,13 @@ export default defineConfig({
crawlLinks: true,
},
},
pages: [
{
path: '/docs',
},
{
path: '/docs/test',
path: '/api/search',
},
],
}),
@@ -4,7 +4,7 @@ description: Your favourite docs framework.
icon: Rocket
---
Hey there! Fumadocs is a docs framework built for Next.js, but do you know it also works on Tanstack Start?
Hey there! Fumadocs is the docs framework that also works on Tanstack Start!
## Heading
+1
View File
@@ -11,6 +11,7 @@ const templateDir = path.join(dir, '../template');
const templates = [
'react-router',
'tanstack-start',
'tanstack-start-spa',
'react-router-spa',
'waku',
['next-mdx', '+next+fuma-docs-mdx'],
+9 -1
View File
@@ -11,7 +11,8 @@ export interface TemplateInfo {
| 'waku'
| 'react-router'
| 'react-router-spa'
| 'tanstack-start';
| 'tanstack-start'
| 'tanstack-start-spa';
label: string;
appDir: string;
/**
@@ -58,6 +59,13 @@ export const templates: TemplateInfo[] = [
appDir: 'src',
rootProviderPath: 'routes/__root.tsx',
},
{
value: 'tanstack-start-spa',
label: 'Tanstack Start SPA: Fumadocs MDX (not RSC)',
hint: 'SPA mode allows you to host the site statically, compatible with a CDN.',
appDir: 'src',
rootProviderPath: 'routes/__root.tsx',
},
];
export const depVersions = versionPkg.dependencies;
@@ -79,6 +79,7 @@ See https://fumadocs.dev/docs/headless/search/orama-cloud for integrating Orama
const filePath = {
'+next+fuma-docs-mdx': '.next/server/app/static.json.body',
'tanstack-start': '.output/public/static.json',
'tanstack-start-spa': 'dist/client/static.json',
'react-router': 'build/client/static.json',
'react-router-spa': 'build/client/static.json',
waku: 'dist/public/static.json',
+5 -5
View File
@@ -48,12 +48,12 @@ export async function rootProvider(
name: 'search',
initializer: '{{ SearchDialog }}',
});
file.addImportDeclaration({
moduleSpecifier: specifier,
defaultImport: 'SearchDialog',
});
break;
}
file.addImportDeclaration({
moduleSpecifier: specifier,
defaultImport: 'SearchDialog',
});
},
});
await file.save();
@@ -0,0 +1,12 @@
This is a Tanstack Start application generated with
[Create Fumadocs](https://github.com/fuma-nama/fumadocs).
Run development server:
```bash
npm run dev
# or
pnpm dev
# or
yarn dev
```
@@ -0,0 +1,34 @@
---
title: Hello World
description: Your favourite docs framework.
icon: Rocket
---
Hey there! Fumadocs is the docs framework that also works on Tanstack Start!
## Heading
Hello World!
<Cards>
<Card
title="Learn more about Tanstack Start"
href="https://tanstack.com/start"
/>
<Card title="Learn more about Fumadocs" href="https://fumadocs.dev" />
</Cards>
### CodeBlock
```ts
console.log('Hello World');
```
#### Table
| Head | Description |
| ------------------------------- | ----------------------------------- |
| `hello` | Hello World |
| very **important** | Hey |
| _Surprisingly_ | Fumadocs |
| very long text that looks weird | hello world hello world hello world |
@@ -0,0 +1,12 @@
---
title: Test
description: This is another page
---
Hello World again!
## Installation
```npm
npm i fumadocs-core fumadocs-ui
```
@@ -0,0 +1,19 @@
node_modules
.DS_Store
.cache
.vercel
.output
.nitro
/build/
/api/
/server/build
/public/build
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
.tanstack
src/routeTree.gen.ts
.source
@@ -0,0 +1,38 @@
{
"name": "example-tanstack-start-spa",
"private": true,
"sideEffects": false,
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"start": "serve dist/client"
},
"dependencies": {
"@orama/orama": "^3.1.16",
"@tanstack/react-router": "^1.133.32",
"@tanstack/react-router-devtools": "^1.133.34",
"@tanstack/react-start": "^1.133.34",
"@tanstack/start-static-server-functions": "^1.133.34",
"fumadocs-core": "workspace:*",
"fumadocs-mdx": "workspace:*",
"fumadocs-ui": "workspace:*",
"lucide-static": "^0.548.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"tailwind-merge": "^3.3.1",
"vite": "^7.1.12"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.16",
"@types/mdx": "^2.0.13",
"@types/node": "^24.9.1",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"@vitejs/plugin-react": "^5.1.0",
"serve": "^14.2.5",
"tailwindcss": "^4.1.16",
"typescript": "^5.9.3",
"vite-tsconfig-paths": "^5.1.4"
}
}
@@ -0,0 +1,7 @@
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
export const docs = defineDocs({
dir: 'content/docs',
});
export default defineConfig();
@@ -0,0 +1,28 @@
import { Link } from '@tanstack/react-router';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
export function NotFound() {
return (
<HomeLayout
nav={{
title: 'Tanstack Start',
}}
className="text-center py-32 justify-center"
>
<div className="flex flex-col items-center gap-4">
<h1 className="text-6xl font-bold text-fd-muted-foreground">404</h1>
<h2 className="text-2xl font-semibold">Page Not Found</h2>
<p className="text-fd-muted-foreground max-w-md">
The page you are looking for might have been removed, had its name
changed, or is temporarily unavailable.
</p>
<Link
to="/"
className="mt-4 px-4 py-2 rounded-lg bg-fd-primary text-fd-primary-foreground font-medium text-sm hover:opacity-90 transition-opacity"
>
Back to Home
</Link>
</div>
</HomeLayout>
);
}
@@ -0,0 +1,51 @@
'use client';
import {
SearchDialog,
SearchDialogClose,
SearchDialogContent,
SearchDialogHeader,
SearchDialogIcon,
SearchDialogInput,
SearchDialogList,
SearchDialogOverlay,
type SharedProps,
} from 'fumadocs-ui/components/dialog/search';
import { useDocsSearch } from 'fumadocs-core/search/client';
import { create } from '@orama/orama';
import { useI18n } from 'fumadocs-ui/contexts/i18n';
function initOrama() {
return create({
schema: { _: 'string' },
// https://docs.orama.com/docs/orama-js/supported-languages
language: 'english',
});
}
export default function DefaultSearchDialog(props: SharedProps) {
const { locale } = useI18n(); // (optional) for i18n
const { search, setSearch, query } = useDocsSearch({
type: 'static',
initOrama,
locale,
});
return (
<SearchDialog
search={search}
onSearchChange={setSearch}
isLoading={query.isLoading}
{...props}
>
<SearchDialogOverlay />
<SearchDialogContent>
<SearchDialogHeader>
<SearchDialogIcon />
<SearchDialogInput />
<SearchDialogClose />
</SearchDialogHeader>
<SearchDialogList items={query.data !== 'empty' ? query.data : null} />
</SearchDialogContent>
</SearchDialog>
);
}
@@ -0,0 +1,9 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: 'Tanstack Start',
},
};
}
@@ -0,0 +1,15 @@
import { loader } from 'fumadocs-core/source';
import * as icons from 'lucide-static';
import { create, docs } from '@/.source';
export const source = loader({
source: await create.sourceAsync(docs.doc, docs.meta),
baseUrl: '/docs',
icon(icon) {
if (!icon) {
return;
}
if (icon in icons) return icons[icon as keyof typeof icons];
},
});
@@ -0,0 +1,12 @@
import { createRouter as createTanStackRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';
import { NotFound } from '@/components/not-found';
export function getRouter() {
return createTanStackRouter({
routeTree,
defaultPreload: 'intent',
scrollRestoration: true,
defaultNotFoundComponent: NotFound,
});
}
@@ -0,0 +1,51 @@
import {
createRootRoute,
HeadContent,
Outlet,
Scripts,
} from '@tanstack/react-router';
import * as React from 'react';
import appCss from '@/styles/app.css?url';
import { RootProvider } from 'fumadocs-ui/provider/tanstack';
import SearchDialog from '@/components/search';
export const Route = createRootRoute({
head: () => ({
meta: [
{
charSet: 'utf-8',
},
{
name: 'viewport',
content: 'width=device-width, initial-scale=1',
},
{
title: 'Fumadocs on TanStack Start',
},
],
links: [{ rel: 'stylesheet', href: appCss }],
}),
component: RootComponent,
});
function RootComponent() {
return (
<RootDocument>
<Outlet />
</RootDocument>
);
}
function RootDocument({ children }: { children: React.ReactNode }) {
return (
<html suppressHydrationWarning>
<head>
<HeadContent />
</head>
<body className="flex flex-col min-h-screen">
<RootProvider search={{ SearchDialog }}>{children}</RootProvider>
<Scripts />
</body>
</html>
);
}
@@ -0,0 +1,16 @@
import { createFileRoute } from '@tanstack/react-router';
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';
const server = createFromSource(source, {
// https://docs.orama.com/docs/orama-js/supported-languages
language: 'english',
});
export const Route = createFileRoute('/api/search')({
server: {
handlers: {
GET: () => server.staticGET(),
},
},
});
@@ -0,0 +1,109 @@
import { createFileRoute, notFound } from '@tanstack/react-router';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { createServerFn } from '@tanstack/react-start';
import { source } from '@/lib/source';
import type * as PageTree from 'fumadocs-core/page-tree';
import { useMemo } from 'react';
import { docs } from '@/.source';
import {
DocsBody,
DocsDescription,
DocsPage,
DocsTitle,
} from 'fumadocs-ui/page';
import defaultMdxComponents from 'fumadocs-ui/mdx';
import { createClientLoader } from 'fumadocs-mdx/runtime/vite';
import { baseOptions } from '@/lib/layout.shared';
import { staticFunctionMiddleware } from '@tanstack/start-static-server-functions';
export const Route = createFileRoute('/docs/$')({
component: Page,
loader: async ({ params }) => {
const slugs = params._splat?.split('/') ?? [];
const data = await loader({ data: slugs });
await clientLoader.preload(data.path);
return data;
},
});
const loader = createServerFn({
method: 'GET',
})
.inputValidator((slugs: string[]) => slugs)
.middleware([staticFunctionMiddleware])
.handler(async ({ data: slugs }) => {
const page = source.getPage(slugs);
if (!page) throw notFound();
return {
tree: source.pageTree as object,
path: page.path,
};
});
const clientLoader = createClientLoader(docs.doc, {
id: 'docs',
component({ toc, frontmatter, default: MDX }) {
return (
<DocsPage toc={toc}>
<DocsTitle>{frontmatter.title}</DocsTitle>
<DocsDescription>{frontmatter.description}</DocsDescription>
<DocsBody>
<MDX
components={{
...defaultMdxComponents,
}}
/>
</DocsBody>
</DocsPage>
);
},
});
function Page() {
const data = Route.useLoaderData();
const Content = clientLoader.getComponent(data.path);
const tree = useMemo(
() => transformPageTree(data.tree as PageTree.Folder),
[data.tree],
);
return (
<DocsLayout {...baseOptions()} tree={tree}>
<Content />
</DocsLayout>
);
}
function transformPageTree(root: PageTree.Root): PageTree.Root {
function mapNode<T extends PageTree.Node>(item: T): T {
if (typeof item.icon === 'string') {
item = {
...item,
icon: (
<span
dangerouslySetInnerHTML={{
__html: item.icon,
}}
/>
),
};
}
if (item.type === 'folder') {
return {
...item,
index: item.index ? mapNode(item.index) : undefined,
children: item.children.map(mapNode),
};
}
return item;
}
return {
...root,
children: root.children.map(mapNode),
fallback: root.fallback ? transformPageTree(root.fallback) : undefined,
};
}
@@ -0,0 +1,24 @@
import { createFileRoute, Link } from '@tanstack/react-router';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '@/lib/layout.shared';
export const Route = createFileRoute('/')({
component: Home,
});
function Home() {
return (
<HomeLayout {...baseOptions()} className="text-center py-32 justify-center">
<h1 className="font-medium text-xl mb-4">Fumadocs on Tanstack Start.</h1>
<Link
to="/docs/$"
params={{
_splat: '',
}}
className="px-3 py-2 rounded-lg bg-fd-primary text-fd-primary-foreground font-medium text-sm mx-auto"
>
Open Docs
</Link>
</HomeLayout>
);
}
@@ -0,0 +1,3 @@
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
@@ -0,0 +1,24 @@
{
"include": ["**/*.ts", "**/*.tsx"],
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"types": ["vite/client"],
"isolatedModules": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"target": "ES2022",
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@/.source": [".source"]
},
"noEmit": true
}
}
@@ -0,0 +1,39 @@
import react from '@vitejs/plugin-react';
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
import { defineConfig } from 'vite';
import tsConfigPaths from 'vite-tsconfig-paths';
import tailwindcss from '@tailwindcss/vite';
import mdx from 'fumadocs-mdx/vite';
export default defineConfig({
server: {
port: 3000,
},
plugins: [
mdx(await import('./source.config')),
tailwindcss(),
tsConfigPaths({
projects: ['./tsconfig.json'],
}),
tanstackStart({
spa: {
enabled: true,
prerender: {
outputPath: 'index.html',
enabled: true,
crawlLinks: true,
},
},
pages: [
{
path: '/docs',
},
{
path: '/api/search',
},
],
}),
react(),
],
});
@@ -4,7 +4,7 @@ description: Your favourite docs framework.
icon: Rocket
---
Hey there! Fumadocs is a docs framework built for Next.js, but do you know it also works on Tanstack Start?
Hey there! Fumadocs is the docs framework that also works on Tanstack Start!
## Heading
+9 -54
View File
@@ -756,7 +756,7 @@ importers:
devDependencies:
'@react-router/dev':
specifier: ^7.9.4
version: 7.9.4(@react-router/[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected]))(@types/[email protected])(@vitejs/[email protected]([email protected]([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])))([email protected])([email protected])([email protected])([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])
version: 7.9.4(@react-router/[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected]))(@types/[email protected])(@vitejs/[email protected]([email protected]([email protected]))(react[email protected]([email protected]([email protected]))([email protected]))(react@19.2.0)([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])))([email protected])([email protected])([email protected])([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])
'@tailwindcss/vite':
specifier: ^4.1.16
version: 4.1.16([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
@@ -823,7 +823,7 @@ importers:
devDependencies:
'@react-router/dev':
specifier: ^7.9.4
version: 7.9.4(@react-router/[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected]))(@types/[email protected])(@vitejs/[email protected]([email protected]([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])))([email protected])([email protected])([email protected])([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])
version: 7.9.4(@react-router/[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected]))(@types/[email protected])(@vitejs/[email protected]([email protected]([email protected]))(react[email protected]([email protected]([email protected]))([email protected]))(react@19.2.0)([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])))([email protected])([email protected])([email protected])([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])
'@tailwindcss/vite':
specifier: ^4.1.16
version: 4.1.16([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
@@ -954,7 +954,7 @@ importers:
devDependencies:
'@react-router/dev':
specifier: ^7.9.4
version: 7.9.4(@react-router/[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected]))(@types/[email protected])(@vitejs/[email protected]([email protected]([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])))([email protected])([email protected])([email protected])([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])
version: 7.9.4(@react-router/[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected]))(@types/[email protected])(@vitejs/[email protected]([email protected]([email protected]))(react[email protected]([email protected]([email protected]))([email protected]))(react@19.2.0)([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])))([email protected])([email protected])([email protected])([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])
'@tailwindcss/vite':
specifier: ^4.1.16
version: 4.1.16([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
@@ -1159,6 +1159,9 @@ importers:
examples/tanstack-start-spa:
dependencies:
'@orama/orama':
specifier: ^3.1.16
version: 3.1.16
'@tanstack/react-router':
specifier: ^1.133.32
version: 1.133.32([email protected]([email protected]))([email protected])
@@ -1214,6 +1217,9 @@ importers:
'@vitejs/plugin-react':
specifier: ^5.1.0
version: 5.1.0([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
serve:
specifier: ^14.2.5
version: 14.2.5
tailwindcss:
specifier: ^4.1.16
version: 4.1.16
@@ -12866,57 +12872,6 @@ snapshots:
- tsx
- yaml
'@react-router/[email protected](@react-router/[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected]))(@types/[email protected])(@vitejs/[email protected]([email protected]([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])))([email protected])([email protected])([email protected])([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])':
dependencies:
'@babel/core': 7.28.4
'@babel/generator': 7.28.3
'@babel/parser': 7.28.4
'@babel/plugin-syntax-jsx': 7.27.1(@babel/[email protected])
'@babel/preset-typescript': 7.27.1(@babel/[email protected])
'@babel/traverse': 7.28.4
'@babel/types': 7.28.4
'@npmcli/package-json': 4.0.1
'@react-router/node': 7.9.4([email protected]([email protected]([email protected]))([email protected]))([email protected])
'@remix-run/node-fetch-server': 0.9.0
arg: 5.0.2
babel-dead-code-elimination: 1.0.10
chokidar: 4.0.3
dedent: 1.7.0([email protected])
es-module-lexer: 1.7.0
exit-hook: 2.2.1
isbot: 5.1.31
jsesc: 3.0.2
lodash: 4.17.21
pathe: 1.1.2
picocolors: 1.1.1
prettier: 3.6.2
react-refresh: 0.14.2
react-router: 7.9.4([email protected]([email protected]))([email protected])
semver: 7.7.3
tinyglobby: 0.2.15
valibot: 1.1.0([email protected])
vite: 7.1.12(@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])
vite-node: 3.2.4(@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])
optionalDependencies:
'@react-router/serve': 7.9.4([email protected]([email protected]([email protected]))([email protected]))([email protected])
'@vitejs/plugin-rsc': 0.5.1([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected])([email protected](@swc/[email protected])([email protected])))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
typescript: 5.9.3
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
- bluebird
- jiti
- less
- lightningcss
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
- tsx
- yaml
'@react-router/[email protected]([email protected])([email protected]([email protected]([email protected]))([email protected]))([email protected])':
dependencies:
'@react-router/node': 7.9.4([email protected]([email protected]([email protected]))([email protected]))([email protected])