diff --git a/apps/www/config/docs.ts b/apps/www/config/docs.ts
index 5f46e07d83..7309e7f666 100644
--- a/apps/www/config/docs.ts
+++ b/apps/www/config/docs.ts
@@ -127,6 +127,17 @@ export const docsConfig: DocsConfig = {
href: "/docs/installation/vite",
items: [],
},
+ {
+ title: "Laravel",
+ href: "/docs/installation/laravel",
+ items: [],
+ },
+ {
+ title: "React Router",
+ href: "/docs/installation/react-router",
+ items: [],
+ label: "New",
+ },
{
title: "Remix",
href: "/docs/installation/remix",
@@ -137,22 +148,12 @@ export const docsConfig: DocsConfig = {
href: "/docs/installation/astro",
items: [],
},
- {
- title: "Laravel",
- href: "/docs/installation/laravel",
- items: [],
- },
{
title: "Tanstack Start",
href: "/docs/installation/tanstack",
items: [],
label: "New",
},
- {
- title: "Gatsby",
- href: "/docs/installation/gatsby",
- items: [],
- },
{
title: "Manual",
href: "/docs/installation/manual",
diff --git a/apps/www/content/docs/installation/astro.mdx b/apps/www/content/docs/installation/astro.mdx
index c8e11411be..bec6ee3dcd 100644
--- a/apps/www/content/docs/installation/astro.mdx
+++ b/apps/www/content/docs/installation/astro.mdx
@@ -1,14 +1,8 @@
---
title: Astro
-description: Install and configure Astro.
+description: Install and configure shadcn/ui for Astro
---
-
- **Update:** We have added full support for React 19 and Tailwind v4 in the
- `canary` release. See the docs for [Tailwind v4](/docs/tailwind-v4) for more
- information.
-
-
### Create project
@@ -16,72 +10,7 @@ description: Install and configure Astro.
Start by creating a new Astro project:
```bash
-npm create astro@latest
-```
-
-### Configure your Astro project
-
-You will be asked a few questions to configure your project:
-
-```txt showLineNumbers
-- Where should we create your new project? ./your-app-name
-- How would you like to start your new project? Choose a template
-- Do you plan to write TypeScript? Yes
-- How strict should TypeScript be? Strict
-- Install dependencies? Yes
-- Initialize a new git repository? (optional) Yes/No
-```
-
-### Add React to your project
-
-Install React using the Astro CLI:
-
-```bash
-npx astro add react
-```
-
-
-
-Answer `Yes` to all the question prompted by the CLI when installing React.
-
-
-
-### Add Tailwind CSS to your project
-
-```bash
-npx astro add tailwind
-```
-
-Create a `styles/globals.css` file in the `src` folder.
-
-```css title="styles/globals.css" showLineNumbers
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-```
-
-Import the `globals.css` file
-
-Import the `styles/globals.css` file in the `src/pages/index.astro` file:
-
-```ts title="src/pages/index.astro" showLineNumbers
----
-import '@/styles/globals.css'
----
-```
-
-Update `astro.config.mjs` and set `applyBaseStyles` to `false`
-
-To prevent serving the Tailwind base styles twice, we need to tell Astro not to apply the base styles, since we already include them in our own `globals.css` file. To do this, set the `applyBaseStyles` config option for the tailwind plugin in `astro.config.mjs` to `false`.
-
-```js title="astro.config.mjs" {3-5} showLineNumbers
-export default defineConfig({
- integrations: [
- tailwind({
- applyBaseStyles: false,
- }),
- ],
-})
+npx create-astro@latest astro-app --template with-tailwindcss --install --add react --git
```
### Edit tsconfig.json file
@@ -111,7 +40,7 @@ Run the `shadcn` init command to setup your project:
npx shadcn@latest init
```
-### That's it
+### Add Components
You can now start adding components to your project.
@@ -121,17 +50,24 @@ npx shadcn@latest add button
The command above will add the `Button` component to your project. You can then import it like this:
-```astro {2,10} showLineNumbers
+```astro title="src/pages/index.astro" {2,16} showLineNumbers
---
import { Button } from "@/components/ui/button"
---
- Astro
+
+
+
+
+ Astro + TailwindCSS
+
- Hello World
+
+ Button
+
```
diff --git a/apps/www/content/docs/installation/index.mdx b/apps/www/content/docs/installation/index.mdx
index 202dd41754..414f1a995c 100644
--- a/apps/www/content/docs/installation/index.mdx
+++ b/apps/www/content/docs/installation/index.mdx
@@ -32,18 +32,28 @@ description: How to install dependencies and structure your app.
Vite
-
+
+
+
+ Laravel
+
+
+
- Remix
-
+
- Remix
+ React Router
Astro
-
-
-
-
- Laravel
-
- **Update:** We have added full support for React 19 and Tailwind v4 in the
- `canary` release. See the docs for [Tailwind v4](/docs/tailwind-v4) for more
- information.
-
-
### Create project
@@ -16,47 +10,31 @@ description: Install and configure Laravel with Inertia
Start by creating a new Laravel project with Inertia and React using the laravel installer `laravel new my-app`:
```bash
-laravel new my-app --typescript --breeze --stack=react --git --no-interaction
+laravel new my-app --react
```
-### Run the CLI
-
-Run the `shadcn` init command to setup your project:
-
-```bash
-npx shadcn@latest init
-```
-
-### Configure components.json
-
-You will be asked a few questions to configure `components.json`:
-
-```txt showLineNumbers
-Which style would you like to use?
-Which color would you like to use as base color?
-Do you want to use CSS variables for colors? › yes
-```
-
-### That's it
+### Add Components
You can now start adding components to your project.
```bash
-npx shadcn@latest add button
+npx shadcn@latest add switch
```
-The command above will add the `Button` component to your project. You can then import it like this:
+The command above will add the `Switch` component to `resources/js/components/ui/switch.tsx`. You can then import it like this:
```tsx {1,6} showLineNumbers
-import { Button } from "@/Components/ui/button"
+import { Switch } from "@/components/ui/switch"
-export default function Home() {
+const MyPage = () => {
return (
- Click me
+
)
}
+
+export default MyPage
```
diff --git a/apps/www/content/docs/installation/manual.mdx b/apps/www/content/docs/installation/manual.mdx
index 058fa03f80..255ee9c363 100644
--- a/apps/www/content/docs/installation/manual.mdx
+++ b/apps/www/content/docs/installation/manual.mdx
@@ -36,132 +36,140 @@ Configure the path aliases in your `tsconfig.json` file.
The `@` alias is a preference. You can use other aliases if you want.
-### Configure tailwind.config.js
-
-Here's what my `tailwind.config.js` file looks like:
-
-```js title="tailwind.config.js"
-/** @type {import('tailwindcss').Config} */
-module.exports = {
- darkMode: ["class"],
- content: ["app/**/*.{ts,tsx}", "components/**/*.{ts,tsx}"],
- theme: {
- extend: {
- colors: {
- border: "hsl(var(--border))",
- input: "hsl(var(--input))",
- ring: "hsl(var(--ring))",
- background: "hsl(var(--background))",
- foreground: "hsl(var(--foreground))",
- primary: {
- DEFAULT: "hsl(var(--primary))",
- foreground: "hsl(var(--primary-foreground))",
- },
- secondary: {
- DEFAULT: "hsl(var(--secondary))",
- foreground: "hsl(var(--secondary-foreground))",
- },
- destructive: {
- DEFAULT: "hsl(var(--destructive))",
- foreground: "hsl(var(--destructive-foreground))",
- },
- muted: {
- DEFAULT: "hsl(var(--muted))",
- foreground: "hsl(var(--muted-foreground))",
- },
- accent: {
- DEFAULT: "hsl(var(--accent))",
- foreground: "hsl(var(--accent-foreground))",
- },
- popover: {
- DEFAULT: "hsl(var(--popover))",
- foreground: "hsl(var(--popover-foreground))",
- },
- card: {
- DEFAULT: "hsl(var(--card))",
- foreground: "hsl(var(--card-foreground))",
- },
- },
- borderRadius: {
- lg: `var(--radius)`,
- md: `calc(var(--radius) - 2px)`,
- sm: "calc(var(--radius) - 4px)",
- },
- },
- },
- plugins: [require("tailwindcss-animate")],
-}
-```
-
### Configure styles
Add the following to your styles/globals.css file. You can learn more about using CSS variables for theming in the [theming section](/docs/theming).
-```css title="globals.css"
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
+```css showLineNumbers title="src/styles/globals.css"
+@import "tailwindcss";
-@layer base {
- :root {
- --background: 0 0% 100%;
- --foreground: 222.2 47.4% 11.2%;
- --muted: 210 40% 96.1%;
- --muted-foreground: 215.4 16.3% 46.9%;
- --popover: 0 0% 100%;
- --popover-foreground: 222.2 47.4% 11.2%;
- --border: 214.3 31.8% 91.4%;
- --input: 214.3 31.8% 91.4%;
- --card: 0 0% 100%;
- --card-foreground: 222.2 47.4% 11.2%;
- --primary: 222.2 47.4% 11.2%;
- --primary-foreground: 210 40% 98%;
- --secondary: 210 40% 96.1%;
- --secondary-foreground: 222.2 47.4% 11.2%;
- --accent: 210 40% 96.1%;
- --accent-foreground: 222.2 47.4% 11.2%;
- --destructive: 0 100% 50%;
- --destructive-foreground: 210 40% 98%;
- --ring: 215 20.2% 65.1%;
- --radius: 0.5rem;
- }
+@plugin 'tailwindcss-animate';
- .dark {
- --background: 224 71% 4%;
- --foreground: 213 31% 91%;
- --muted: 223 47% 11%;
- --muted-foreground: 215.4 16.3% 56.9%;
- --accent: 216 34% 17%;
- --accent-foreground: 210 40% 98%;
- --popover: 224 71% 4%;
- --popover-foreground: 215 20.2% 65.1%;
- --border: 216 34% 17%;
- --input: 216 34% 17%;
- --card: 224 71% 4%;
- --card-foreground: 213 31% 91%;
- --primary: 210 40% 98%;
- --primary-foreground: 222.2 47.4% 1.2%;
- --secondary: 222.2 47.4% 11.2%;
- --secondary-foreground: 210 40% 98%;
- --destructive: 0 63% 31%;
- --destructive-foreground: 210 40% 98%;
- --ring: 216 34% 17%;
- }
+@custom-variant dark (&:is(.dark *));
+
+:root {
+ --background: oklch(1 0 0);
+ --foreground: oklch(0.145 0 0);
+ --card: oklch(1 0 0);
+ --card-foreground: oklch(0.145 0 0);
+ --popover: oklch(1 0 0);
+ --popover-foreground: oklch(0.145 0 0);
+ --primary: oklch(0.205 0 0);
+ --primary-foreground: oklch(0.985 0 0);
+ --secondary: oklch(0.97 0 0);
+ --secondary-foreground: oklch(0.205 0 0);
+ --muted: oklch(0.97 0 0);
+ --muted-foreground: oklch(0.556 0 0);
+ --accent: oklch(0.97 0 0);
+ --accent-foreground: oklch(0.205 0 0);
+ --destructive: oklch(0.577 0.245 27.325);
+ --destructive-foreground: oklch(0.577 0.245 27.325);
+ --border: oklch(0.922 0 0);
+ --input: oklch(0.922 0 0);
+ --ring: oklch(0.708 0 0);
+ --chart-1: oklch(0.646 0.222 41.116);
+ --chart-2: oklch(0.6 0.118 184.704);
+ --chart-3: oklch(0.398 0.07 227.392);
+ --chart-4: oklch(0.828 0.189 84.429);
+ --chart-5: oklch(0.769 0.188 70.08);
+ --radius: 0.625rem;
+ --sidebar: oklch(0.985 0 0);
+ --sidebar-foreground: oklch(0.145 0 0);
+ --sidebar-primary: oklch(0.205 0 0);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.97 0 0);
+ --sidebar-accent-foreground: oklch(0.205 0 0);
+ --sidebar-border: oklch(0.922 0 0);
+ --sidebar-ring: oklch(0.708 0 0);
+}
+
+.dark {
+ --background: oklch(0.145 0 0);
+ --foreground: oklch(0.985 0 0);
+ --card: oklch(0.145 0 0);
+ --card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.145 0 0);
+ --popover-foreground: oklch(0.985 0 0);
+ --primary: oklch(0.985 0 0);
+ --primary-foreground: oklch(0.205 0 0);
+ --secondary: oklch(0.269 0 0);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.269 0 0);
+ --muted-foreground: oklch(0.708 0 0);
+ --accent: oklch(0.269 0 0);
+ --accent-foreground: oklch(0.985 0 0);
+ --destructive: oklch(0.396 0.141 25.723);
+ --destructive-foreground: oklch(0.637 0.237 25.331);
+ --border: oklch(0.269 0 0);
+ --input: oklch(0.269 0 0);
+ --ring: oklch(0.439 0 0);
+ --chart-1: oklch(0.488 0.243 264.376);
+ --chart-2: oklch(0.696 0.17 162.48);
+ --chart-3: oklch(0.769 0.188 70.08);
+ --chart-4: oklch(0.627 0.265 303.9);
+ --chart-5: oklch(0.645 0.246 16.439);
+ --sidebar: oklch(0.205 0 0);
+ --sidebar-foreground: oklch(0.985 0 0);
+ --sidebar-primary: oklch(0.488 0.243 264.376);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.269 0 0);
+ --sidebar-accent-foreground: oklch(0.985 0 0);
+ --sidebar-border: oklch(0.269 0 0);
+ --sidebar-ring: oklch(0.439 0 0);
+}
+
+@theme inline {
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-destructive-foreground: var(--destructive-foreground);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --color-chart-1: var(--chart-1);
+ --color-chart-2: var(--chart-2);
+ --color-chart-3: var(--chart-3);
+ --color-chart-4: var(--chart-4);
+ --color-chart-5: var(--chart-5);
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+ --radius-xl: calc(var(--radius) + 4px);
+ --color-sidebar: var(--sidebar);
+ --color-sidebar-foreground: var(--sidebar-foreground);
+ --color-sidebar-primary: var(--sidebar-primary);
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
+ --color-sidebar-accent: var(--sidebar-accent);
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
+ --color-sidebar-border: var(--sidebar-border);
+ --color-sidebar-ring: var(--sidebar-ring);
}
@layer base {
* {
- @apply border-border;
+ @apply border-border outline-ring/50;
}
body {
- @apply font-sans antialiased bg-background text-foreground;
+ @apply bg-background text-foreground;
}
}
```
### Add a cn helper
-```ts title="lib/utils.ts" showLineNumbers
+```ts showLineNumbers title="lib/utils.ts"
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
@@ -181,9 +189,9 @@ Create a `components.json` file in the root of your project.
"rsc": false,
"tsx": true,
"tailwind": {
- "config": "tailwind.config.js",
- "css": "src/index.css",
- "baseColor": "zinc",
+ "config": "",
+ "css": "src/styles/globals.css",
+ "baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
diff --git a/apps/www/content/docs/installation/next.mdx b/apps/www/content/docs/installation/next.mdx
index 4a253e3b30..a2b8915ba6 100644
--- a/apps/www/content/docs/installation/next.mdx
+++ b/apps/www/content/docs/installation/next.mdx
@@ -1,14 +1,8 @@
---
title: Next.js
-description: Install and configure Next.js.
+description: Install and configure shadcn/ui for Next.js.
---
-
- **Update:** We have added full support for React 19 and Tailwind v4 in the
- `canary` release. See the docs for [Tailwind v4](/docs/tailwind-v4) for more
- information.
-
-
### Create project
@@ -19,27 +13,9 @@ Run the `init` command to create a new Next.js project or to setup an existing o
npx shadcn@latest init
```
-
+Choose between a Next.js project or a Monorepo.
-You can use the `-d` flag for defaults i.e `new-york`, `zinc` and `yes` for the css variables.
-
-```bash
-npx shadcn@latest init -d
-```
-
-
-
-### Configure components.json
-
-You will be asked a few questions to configure `components.json`:
-
-```txt showLineNumbers
-Which style would you like to use? › New York
-Which color would you like to use as base color? › Zinc
-Do you want to use CSS variables for colors? › no / yes
-```
-
-### That's it
+### Add Components
You can now start adding components to your project.
diff --git a/apps/www/content/docs/installation/react-router.mdx b/apps/www/content/docs/installation/react-router.mdx
new file mode 100644
index 0000000000..684a88432d
--- /dev/null
+++ b/apps/www/content/docs/installation/react-router.mdx
@@ -0,0 +1,53 @@
+---
+title: React Router
+description: Install and configure shadcn/ui for React Router.
+---
+
+
+
+### Create project
+
+```bash
+npx create-react-router@latest my-app
+```
+
+### Run the CLI
+
+Run the `shadcn-ui` init command to setup your project:
+
+```bash
+npx shadcn@latest init
+```
+
+### Add Components
+
+You can now start adding components to your project.
+
+```bash
+npx shadcn@latest add button
+```
+
+The command above will add the `Button` component to your project. You can then import it like this:
+
+```tsx showLineNumbers title="app/routes/home.tsx"
+import { Button } from "~/components/ui/button"
+
+import type { Route } from "./+types/home"
+
+export function meta({}: Route.MetaArgs) {
+ return [
+ { title: "New React Router App" },
+ { name: "description", content: "Welcome to React Router!" },
+ ]
+}
+
+export default function Home() {
+ return (
+
+ Click me
+
+ )
+}
+```
+
+
diff --git a/apps/www/content/docs/installation/remix.mdx b/apps/www/content/docs/installation/remix.mdx
index a579e8213c..e319cba2d8 100644
--- a/apps/www/content/docs/installation/remix.mdx
+++ b/apps/www/content/docs/installation/remix.mdx
@@ -1,8 +1,14 @@
---
title: Remix
-description: Install and configure Remix.
+description: Install and configure shadcn/ui for Remix.
---
+
+
+**Note:** This guide is for Remix. For React Router, see the [React Router](/docs/installation/react-router) guide.
+
+
+
### Create project
diff --git a/apps/www/content/docs/tailwind-v4.mdx b/apps/www/content/docs/tailwind-v4.mdx
index af7725bc48..a94b7ebcc5 100644
--- a/apps/www/content/docs/tailwind-v4.mdx
+++ b/apps/www/content/docs/tailwind-v4.mdx
@@ -1,21 +1,24 @@
---
-title: An update on Tailwind v4
-description: How to use shadcn/ui with Tailwind v4.
+title: Tailwind v4
+description: How to use shadcn/ui with Tailwind v4 and React 19.
---
-It’s here! Tailwind v4 and React 19. Ready for you to try out. It's available in the `canary` release of the CLI. You can start using it today.
+It’s here! Tailwind v4 and React 19. Ready for you to try out. You can start using it today.
-## TLDR
-
-If you're starting a new project with Tailwind v4 and React 19, use the `canary` version of the command-line:
-
-```bash
-npx shadcn@canary init
-```
+
## What's New
-- The CLI (`canary`) can now initialize projects with Tailwind v4.
+- The CLI can now initialize projects with Tailwind v4.
- Full support for the new `@theme` directive and `@theme inline` option.
- All components are updated for Tailwind v4 and React 19.
- We’ve removed the forwardRefs and adjusted the types.
@@ -24,133 +27,124 @@ npx shadcn@canary init
- We're deprecating the `toast` component in favor of `sonner`.
- Buttons now use the default cursor.
- We're deprecating the `default` style. New projects will use `new-york`.
+- HSL colors are now converted to OKLCH.
**Note: this is non-breaking. Your existing apps with Tailwind v3 and React 18 will still work. When you add new components, they'll still be in v3 and React 18 until you upgrade. Only new projects start with Tailwind v4 and React 19.**
-## What's Coming Next
-
-The following is still being worked on. I'll post updates soon.
-
-- Migrating colors to OKLCH.
-- Fix and improve animations.
-
## See it Live
I put together a demo with all the updated components here: https://v4.shadcn.com
-Take a look and test the components. If you find any bugs, leave a comment on the [GitHub issue](https://github.com/shadcn-ui/ui/issues/6585).
-
-- The code for the app is here: https://github.com/shadcn-ui/ui/tree/main/apps/v4
-- The v4 components can be found here: https://github.com/shadcn-ui/ui/tree/main/apps/v4/registry/new-york-v4/ui
+Take a look and test the components. If you find any bugs, please let me know on [GitHub](https://github.com/shadcn-ui/ui).
## Try It Out
-You can test Tailwind v4 + React 19 today using the `canary` release of the CLI.
+You can test Tailwind v4 + React 19 today using the `canary` release of the CLI. See the framework specific guides below for how to get started.
-```bash
-pnpm dlx shadcn@canary init
-```
-
-I'm still working on the docs, but here's a quick guide to testing new projects:
-
-### Next.js
-
-1. Start a new project with Tailwind v4 and React 19:
-
-```bash
-pnpm create next-app@canary --tailwind --eslint --typescript --app --no-src-dir
-```
-
-2. Init shadcn/ui. This will create your `components.json` and set up your CSS variables:
-
-```bash
-pnpm dlx shadcn@canary init
-```
-
-3. You should now be able to add components:
-
-```bash
-pnpm dlx shadcn@canary add button
-```
-
-### Vite
-
-1. Create a new project with React 19:
-
-```bash
-pnpm create vite --template=react-ts
-```
-
-2. Follow the official guide to add Tailwind CSS: https://tailwindcss.com/docs/installation/using-vite
-
-3. Add path aliases to `tsconfig.json`:
-
-```json title="tsconfig.json" showLineNumbers
-{
- "files": [],
- "references": [
- { "path": "./tsconfig.app.json" },
- { "path": "./tsconfig.node.json" }
- ],
- "compilerOptions": {
- "baseUrl": ".",
- "paths": {
- "@/*": ["./src/*"]
- }
- }
-}
-```
-
-4. Add path aliases to `tsconfig.app.json`:
-
-```json title="tsconfig.app.json" showLineNumbers
-{
- "compilerOptions": {
- "baseUrl": ".",
- "paths": {
- "@/*": ["./src/*"]
- }
- }
-}
-```
-
-5. Install `@types/node`:
-
-```bash
-pnpm add -D @types/node
-```
-
-6. Add resolve alias config to `vite.config.ts`:
-
-```ts title="vite.config.ts" showLineNumbers
-import path from "path"
-import tailwindcss from "@tailwindcss/vite"
-import react from "@vitejs/plugin-react"
-import { defineConfig } from "vite"
-
-export default defineConfig({
- plugins: [react(), tailwindcss()],
- resolve: {
- alias: {
- "@": path.resolve(__dirname, "./src"),
- },
- },
-})
-```
-
-7. Init `shadcn/ui`. This will create your `components.json` and set up your CSS variables:
-
-```bash
-pnpm dlx shadcn@canary init
-```
-
-8. You should now be able to add components:
-
-```bash
-pnpm dlx shadcn@canary add button
-```
-
-(Note: If you need help with other frameworks, drop a comment below. I'll update the guide)
+
+
+
+ Next.js
+
+
+ Next.js
+
+
+
+ Vite
+
+
+ Vite
+
+
+
+
+
+ Laravel
+
+
+
+
+
+ React Router
+
+
+
+ Astro
+
+
+ Astro
+
+
+
+
+
+ TanStack Start
+
+
+
+ Gatsby
+
+
+ Gatsby
+
+
+
+ React
+
+
+ Manual
+
+
## Upgrade Your Project