diff --git a/.github/workflows/build-lint-test.yml b/.github/workflows/build-lint-test.yml
index 9665a27ac..d4cb217cf 100644
--- a/.github/workflows/build-lint-test.yml
+++ b/.github/workflows/build-lint-test.yml
@@ -36,6 +36,9 @@ jobs:
- name: Build Scripts
run: pnpm build:scripts
+ - name: Build Plugins
+ run: pnpm build:plugins
+
- name: Run build
run: pnpm build
diff --git a/apps/api/package.json b/apps/api/package.json
index c19096f94..ef54d038c 100644
--- a/apps/api/package.json
+++ b/apps/api/package.json
@@ -14,31 +14,31 @@
"lint:fix": "eslint . --fix"
},
"dependencies": {
- "@hono/zod-openapi": "^1.1.4",
- "@hono/zod-validator": "^0.7.4",
+ "@hono/zod-openapi": "^1.3.0",
+ "@hono/zod-validator": "^0.7.6",
"@vitnode/core": "workspace:*",
- "drizzle-kit": "^0.31.7",
- "drizzle-orm": "^0.44.7",
- "hono": "^4.10.6",
- "next-intl": "^4.5.3",
- "react": "^19.2.0",
- "react-dom": "^19.2.0",
- "use-intl": "^4.5.3",
- "zod": "^4.1.12"
+ "drizzle-kit": "^0.31.10",
+ "drizzle-orm": "^0.45.2",
+ "hono": "^4.12.16",
+ "next-intl": "^4.11.0",
+ "react": "^19.2.5",
+ "react-dom": "^19.2.5",
+ "use-intl": "^4.11.0",
+ "zod": "^4.4.1"
},
"devDependencies": {
- "@hono/node-server": "^1.19.6",
- "@react-email/components": "^1.0.1",
- "@types/node": "^24.10.1",
- "@types/react": "^19.2.5",
+ "@hono/node-server": "^2.0.1",
+ "@react-email/components": "^1.0.12",
+ "@types/node": "^25.6.0",
+ "@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitnode/config": "workspace:*",
"@vitnode/nodemailer": "workspace:*",
- "dotenv": "^17.2.3",
- "eslint": "^9.39.1",
- "react-email": "^5.0.4",
+ "dotenv": "^17.4.2",
+ "eslint": "^10.2.1",
+ "react-email": "^6.0.5",
"tsc-alias": "^1.8.16",
- "tsx": "^4.20.6",
- "typescript": "^5.9.3"
+ "tsx": "^4.21.0",
+ "typescript": "^6.0.3"
}
}
diff --git a/apps/api/tsconfig.json b/apps/api/tsconfig.json
index 4bc15ed4a..7145b4d55 100644
--- a/apps/api/tsconfig.json
+++ b/apps/api/tsconfig.json
@@ -4,8 +4,9 @@
"compilerOptions": {
"target": "ESNext",
"module": "NodeNext",
- "baseUrl": ".",
+ "rootDir": "./src",
"outDir": "./dist",
+ "incremental": false,
"types": ["node"],
"paths": {
"@/*": ["./src/*"]
diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore
index cae412f45..78b8c7949 100644
--- a/apps/docs/.gitignore
+++ b/apps/docs/.gitignore
@@ -34,4 +34,5 @@ yarn-error.log*
# Others
.vercel
-next-env.d.ts
\ No newline at end of file
+next-env.d.ts
+.env*.local
diff --git a/apps/docs/components.json b/apps/docs/components.json
index c6a338228..9a3fe27e5 100644
--- a/apps/docs/components.json
+++ b/apps/docs/components.json
@@ -1,15 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
- "style": "new-york",
+ "style": "base-nova",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/global.css",
- "baseColor": "neutral",
+ "baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
+ "iconLibrary": "lucide",
+ "rtl": true,
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
@@ -17,5 +19,7 @@
"lib": "@/lib",
"hooks": "@/hooks"
},
- "iconLibrary": "lucide"
+ "menuColor": "default",
+ "menuAccent": "subtle",
+ "registries": {}
}
diff --git a/apps/docs/package.json b/apps/docs/package.json
index cae0ed199..81311561c 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -22,35 +22,35 @@
"lint:fix": "eslint . --fix"
},
"dependencies": {
- "@hono/zod-openapi": "^1.1.4",
- "@hono/zod-validator": "^0.7.4",
+ "@hono/zod-openapi": "^1.3.0",
+ "@hono/zod-validator": "^0.7.6",
"@vitnode/blog": "workspace:*",
"@vitnode/core": "workspace:*",
- "drizzle-kit": "^0.31.7",
- "drizzle-orm": "^0.44.7",
- "fumadocs-core": "^16.0.11",
- "fumadocs-mdx": "^13.0.8",
- "fumadocs-ui": "^16.0.11",
- "hono": "^4.10.6",
- "lucide-react": "^0.553.0",
- "motion": "^12.23.24",
- "next": "^16.0.3",
- "next-intl": "^4.5.3",
+ "drizzle-kit": "^0.31.10",
+ "drizzle-orm": "^0.45.2",
+ "fumadocs-core": "^16.8.5",
+ "fumadocs-mdx": "^14.3.2",
+ "fumadocs-ui": "^16.8.5",
+ "hono": "^4.12.16",
+ "lucide-react": "^1.14.0",
+ "motion": "^12.38.0",
+ "next": "^16.2.4",
+ "next-intl": "^4.11.0",
"node-cron": "^4.2.1",
- "react": "^19.2.0",
- "react-dom": "^19.2.0",
- "react-hook-form": "^7.66.0",
+ "react": "^19.2.5",
+ "react-dom": "^19.2.5",
+ "react-hook-form": "^7.74.0",
"react-use": "^17.6.0",
"sonner": "^2.0.7"
},
"devDependencies": {
- "@next/bundle-analyzer": "^16.0.3",
- "@playwright/test": "^1.56.1",
- "@react-email/components": "^1.0.1",
- "@tailwindcss/postcss": "^4.1.17",
+ "@next/bundle-analyzer": "^16.2.4",
+ "@playwright/test": "^1.59.1",
+ "@react-email/components": "^1.0.12",
+ "@tailwindcss/postcss": "^4.2.4",
"@types/mdx": "^2.0.13",
- "@types/node": "^24.10.1",
- "@types/react": "^19.2.5",
+ "@types/node": "^25.6.0",
+ "@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitnode/config": "workspace:*",
"@vitnode/node-cron": "workspace:*",
@@ -58,14 +58,14 @@
"@vitnode/resend": "workspace:*",
"babel-plugin-react-compiler": "^1.0.0",
"class-variance-authority": "^0.7.1",
- "eslint": "^9.39.1",
- "postcss": "^8.5.6",
- "react-email": "^5.0.4",
- "shiki": "^3.15.0",
- "tailwindcss": "^4.1.17",
+ "eslint": "^10.2.1",
+ "postcss": "^8.5.12",
+ "react-email": "^6.0.5",
+ "shiki": "^4.0.2",
+ "tailwindcss": "^4.2.4",
"tw-animate-css": "^1.4.0",
- "typescript": "^5.9.3",
- "use-intl": "^4.5.3",
- "zod": "^4.1.12"
+ "typescript": "^6.0.3",
+ "use-intl": "^4.11.0",
+ "zod": "^4.4.1"
}
}
diff --git a/apps/docs/source.config.ts b/apps/docs/source.config.ts
index cf6fc0532..29217e692 100644
--- a/apps/docs/source.config.ts
+++ b/apps/docs/source.config.ts
@@ -1,22 +1,13 @@
-import {
- defineConfig,
- defineDocs,
- frontmatterSchema,
- metaSchema,
-} from "fumadocs-mdx/config";
+import { defineConfig, defineDocs } from "fumadocs-mdx/config";
import jsonSchema from "fumadocs-mdx/plugins/json-schema";
export const docs = defineDocs({
dir: "content/docs",
docs: {
- schema: frontmatterSchema,
postprocess: {
includeProcessedMarkdown: true,
},
},
- meta: {
- schema: metaSchema,
- },
});
export default defineConfig({
diff --git a/apps/docs/src/app/[locale]/(docs)/docs/[[...slug]]/page.client.tsx b/apps/docs/src/app/[locale]/(docs)/docs/[[...slug]]/page.client.tsx
index c33614755..8cf159ee8 100644
--- a/apps/docs/src/app/[locale]/(docs)/docs/[[...slug]]/page.client.tsx
+++ b/apps/docs/src/app/[locale]/(docs)/docs/[[...slug]]/page.client.tsx
@@ -1,7 +1,7 @@
"use client";
+import { cn } from "@vitnode/core/lib/utils";
// Source: https://github.com/fuma-nama/fumadocs/blob/dev/apps/docs/app/docs/%5B...slug%5D/page.client.tsx
-
import { cva } from "class-variance-authority";
import { buttonVariants } from "fumadocs-ui/components/ui/button";
import {
@@ -9,9 +9,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "fumadocs-ui/components/ui/popover";
-import { ChevronDown } from "fumadocs-ui/internal/icons";
-import { cn } from "fumadocs-ui/utils/cn";
-import { ExternalLinkIcon, MessageCircleIcon } from "lucide-react";
+import { ChevronDown, ExternalLinkIcon, MessageCircleIcon } from "lucide-react";
const optionVariants = cva(
"text-sm p-2 rounded-lg inline-flex items-center gap-2 hover:text-fd-accent-foreground hover:bg-fd-accent [&_svg]:size-4",
diff --git a/apps/docs/src/app/[locale]/(main)/(home)/page.tsx b/apps/docs/src/app/[locale]/(main)/(home)/page.tsx
index 80632989b..3a7190d2b 100644
--- a/apps/docs/src/app/[locale]/(main)/(home)/page.tsx
+++ b/apps/docs/src/app/[locale]/(main)/(home)/page.tsx
@@ -18,7 +18,7 @@ export const metadata: Metadata = {
export default function HomePage() {
return (
-
+
diff --git a/apps/docs/src/app/[locale]/(main)/layout.client.tsx b/apps/docs/src/app/[locale]/(main)/layout.client.tsx
index 7ff71dd9f..4dbd83965 100644
--- a/apps/docs/src/app/[locale]/(main)/layout.client.tsx
+++ b/apps/docs/src/app/[locale]/(main)/layout.client.tsx
@@ -1,6 +1,6 @@
"use client";
-import { cn } from "fumadocs-ui/utils/cn";
+import { cn } from "@vitnode/core/lib/utils";
import { useParams } from "next/navigation";
export function useMode(): string | undefined {
diff --git a/apps/docs/src/app/global.css b/apps/docs/src/app/global.css
index 7ce95b66c..a3723c255 100644
--- a/apps/docs/src/app/global.css
+++ b/apps/docs/src/app/global.css
@@ -5,43 +5,43 @@
@import "tw-animate-css";
-@source '../../node_modules/fumadocs-ui/dist/**/*.js';
+@source "../../node_modules/fumadocs-ui/dist/**/*.js";
@source "../../node_modules/@vitnode/core/dist/src/components";
@source "../../node_modules/@vitnode/core/dist/src/views";
:root:not(.dark) {
- --background: oklch(0.96 0.01 250);
- --foreground: oklch(0.18 0.01 250);
+ --background: oklch(1 0 0);
+ --foreground: oklch(0.141 0.005 285.823);
--card: oklch(1 0 0);
- --card-foreground: oklch(0.22 0.01 250);
+ --card-foreground: oklch(0.141 0.005 285.823);
--popover: oklch(1 0 0);
- --popover-foreground: oklch(0.22 0.01 250);
- --primary: oklch(0.51 0.16 262.61);
- --primary-foreground: oklch(0.985 0 0);
- --secondary: oklch(0.98 0.01 250);
- --secondary-foreground: oklch(0.25 0.01 250);
- --muted: oklch(0.95 0.01 250);
- --muted-foreground: oklch(0.53 0.01 250);
- --accent: oklch(0.92 0.01 250);
- --accent-foreground: oklch(0.25 0.01 250);
- --destructive: oklch(0.6 0.2 24.45);
- --warn: oklch(0.54 0.12 82.58);
- --border: oklch(0.9 0.01 250);
- --input: oklch(0.9 0.01 250);
- --ring: oklch(0.7 0.13 250);
- --chart-1: oklch(0.65 0.13 250);
- --chart-2: oklch(0.6 0.11 260);
- --chart-3: oklch(0.45 0.09 250);
- --chart-4: oklch(0.8 0.13 250);
- --chart-5: oklch(0.75 0.13 250);
- --sidebar: var(--card);
- --sidebar-foreground: oklch(0.22 0.01 250);
- --sidebar-primary: var(--primary);
- --sidebar-primary-foreground: var(--primary-foreground);
- --sidebar-accent: oklch(0.97 0.01 250);
- --sidebar-accent-foreground: oklch(0.25 0.01 250);
- --sidebar-border: oklch(0.91 0.01 250);
- --sidebar-ring: oklch(0.7 0.13 250);
+ --popover-foreground: oklch(0.141 0.005 285.823);
+ --primary: oklch(0.488 0.243 264.376);
+ --primary-foreground: oklch(0.97 0.014 254.604);
+ --secondary: oklch(0.967 0.001 286.375);
+ --secondary-foreground: oklch(0.21 0.006 285.885);
+ --muted: oklch(0.967 0.001 286.375);
+ --muted-foreground: oklch(0.552 0.016 285.938);
+ --accent: oklch(0.967 0.001 286.375);
+ --accent-foreground: oklch(0.21 0.006 285.885);
+ --destructive: oklch(0.577 0.245 27.325);
+ --border: oklch(0.92 0.004 286.32);
+ --input: oklch(0.92 0.004 286.32);
+ --ring: oklch(0.705 0.015 286.067);
+ --chart-1: oklch(0.871 0.006 286.286);
+ --chart-2: oklch(0.552 0.016 285.938);
+ --chart-3: oklch(0.442 0.017 285.786);
+ --chart-4: oklch(0.37 0.013 285.805);
+ --chart-5: oklch(0.274 0.006 286.033);
+ --radius: 0.625rem;
+ --sidebar: oklch(0.985 0 0);
+ --sidebar-foreground: oklch(0.141 0.005 285.823);
+ --sidebar-primary: oklch(0.546 0.245 262.881);
+ --sidebar-primary-foreground: oklch(0.97 0.014 254.604);
+ --sidebar-accent: oklch(0.967 0.001 286.375);
+ --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
+ --sidebar-border: oklch(0.92 0.004 286.32);
+ --sidebar-ring: oklch(0.705 0.015 286.067);
--dev-color: oklch(0.6 0.18 50);
--ui-color: oklch(0.65 0.18 170);
@@ -49,37 +49,37 @@
}
.dark {
- --background: oklch(0.16 0.01 250);
- --foreground: oklch(0.96 0.01 250);
- --card: oklch(0.2 0.01 250);
- --card-foreground: oklch(0.96 0.01 250);
- --popover: oklch(0.22 0.01 250);
- --popover-foreground: oklch(0.96 0.01 250);
- --primary: oklch(0.6 0.18 262.65);
- --primary-foreground: oklch(0.98 0 0);
- --secondary: oklch(0.2 0.01 250);
- --secondary-foreground: oklch(0.96 0.01 250);
- --muted: oklch(0.24 0.01 250);
- --muted-foreground: oklch(0.7 0.01 250);
- --accent: oklch(0.28 0.01 250);
- --destructive: oklch(0.62 0.2 25.35);
- --warn: oklch(0.76 0.18 81.84);
- --border: oklch(0.3 0.01 250);
- --input: oklch(0.3 0.01 250);
- --ring: oklch(0.54 0.13 250);
- --chart-1: oklch(0.45 0.09 250);
- --chart-2: oklch(0.6 0.11 260);
- --chart-3: oklch(0.75 0.13 250);
- --chart-4: oklch(0.8 0.13 250);
- --chart-5: oklch(0.65 0.13 250);
- --sidebar: var(--card);
- --sidebar-foreground: oklch(0.96 0.01 250);
- --sidebar-primary: var(--primary);
- --sidebar-primary-foreground: var(--primary-foreground);
- --sidebar-accent: oklch(0.23 0.01 250);
- --sidebar-accent-foreground: oklch(0.96 0.01 250);
- --sidebar-border: oklch(0.26 0.01 250);
- --sidebar-ring: oklch(0.54 0.13 250);
+ --background: oklch(0.141 0.005 285.823);
+ --foreground: oklch(0.985 0 0);
+ --card: oklch(0.21 0.006 285.885);
+ --card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.21 0.006 285.885);
+ --popover-foreground: oklch(0.985 0 0);
+ --primary: oklch(0.424 0.199 265.638);
+ --primary-foreground: oklch(0.97 0.014 254.604);
+ --secondary: oklch(0.274 0.006 286.033);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.274 0.006 286.033);
+ --muted-foreground: oklch(0.705 0.015 286.067);
+ --accent: oklch(0.274 0.006 286.033);
+ --accent-foreground: oklch(0.985 0 0);
+ --destructive: oklch(0.704 0.191 22.216);
+ --border: oklch(1 0 0 / 10%);
+ --input: oklch(1 0 0 / 15%);
+ --ring: oklch(0.552 0.016 285.938);
+ --chart-1: oklch(0.871 0.006 286.286);
+ --chart-2: oklch(0.552 0.016 285.938);
+ --chart-3: oklch(0.442 0.017 285.786);
+ --chart-4: oklch(0.37 0.013 285.805);
+ --chart-5: oklch(0.274 0.006 286.033);
+ --sidebar: oklch(0.21 0.006 285.885);
+ --sidebar-foreground: oklch(0.985 0 0);
+ --sidebar-primary: oklch(0.623 0.214 259.815);
+ --sidebar-primary-foreground: oklch(0.97 0.014 254.604);
+ --sidebar-accent: oklch(0.274 0.006 286.033);
+ --sidebar-accent-foreground: oklch(0.985 0 0);
+ --sidebar-border: oklch(1 0 0 / 10%);
+ --sidebar-ring: oklch(0.552 0.016 285.938);
--dev-color: oklch(0.75 0.18 50);
--ui-color: oklch(0.7 0.18 170);
diff --git a/apps/docs/src/components/animated-beam/animated-beam.tsx b/apps/docs/src/components/animated-beam/animated-beam.tsx
index 44ec99aa5..50b079498 100644
--- a/apps/docs/src/components/animated-beam/animated-beam.tsx
+++ b/apps/docs/src/components/animated-beam/animated-beam.tsx
@@ -1,4 +1,4 @@
-/* eslint-disable @eslint-react/hooks-extra/no-direct-set-state-in-use-effect */
+/* eslint-disable @eslint-react/set-state-in-effect */
"use client";
import { cn } from "@vitnode/core/lib/utils";
@@ -12,6 +12,7 @@ export const AnimatedBeam = ({
toRef,
curvature = 0,
reverse = false, // Include the reverse prop
+ // eslint-disable-next-line react-hooks/purity, @eslint-react/purity
duration = Math.random() * 3 + 4,
delay = 0,
pathColor = "gray",
@@ -104,7 +105,7 @@ export const AnimatedBeam = ({
}
// Call the updatePath initially to set the initial path
- // eslint-disable-next-line react-you-might-not-need-an-effect/no-adjust-state-on-prop-change
+
updatePath();
// Clean up the observer on component unmount
diff --git a/apps/docs/src/components/fumadocs/img.tsx b/apps/docs/src/components/fumadocs/img.tsx
index 7d3972cc5..fed8f9410 100644
--- a/apps/docs/src/components/fumadocs/img.tsx
+++ b/apps/docs/src/components/fumadocs/img.tsx
@@ -1,7 +1,7 @@
import type React from "react";
+import { cn } from "@vitnode/core/lib/utils";
import { ImageZoom } from "fumadocs-ui/components/image-zoom";
-import { cn } from "fumadocs-ui/utils/cn";
export const ImgDocs = ({
className,
diff --git a/apps/docs/src/components/fumadocs/preview.tsx b/apps/docs/src/components/fumadocs/preview.tsx
index bc2b3a462..97ff6d4dd 100644
--- a/apps/docs/src/components/fumadocs/preview.tsx
+++ b/apps/docs/src/components/fumadocs/preview.tsx
@@ -12,12 +12,14 @@ export const Preview = ({
name: string;
withoutBackground?: boolean;
}) => {
+ // eslint-disable-next-line @eslint-react/static-components
const Component = dynamic(async () => import(`../../examples/${name}.tsx`));
if (withoutBackground) {
return (
} key={name}>
+ {/* eslint-disable-next-line react-hooks/static-components, @eslint-react/static-components */}
@@ -27,11 +29,12 @@ export const Preview = ({
return (
} key={name}>
+ {/* eslint-disable-next-line react-hooks/static-components, @eslint-react/static-components */}
diff --git a/apps/docs/src/components/infinite-slider.tsx b/apps/docs/src/components/infinite-slider.tsx
index 8e98957b0..502b7b423 100644
--- a/apps/docs/src/components/infinite-slider.tsx
+++ b/apps/docs/src/components/infinite-slider.tsx
@@ -29,10 +29,13 @@ export function InfiniteSlider({
reverse = false,
className,
}: InfiniteSliderProps) {
+ // eslint-disable-next-line @eslint-react/no-unused-state
const [currentSpeed, setCurrentSpeed] = React.useState(speed);
const [ref, { width, height }] = useMeasure();
const translation = useMotionValue(0);
+ // eslint-disable-next-line @eslint-react/no-unused-state
const [isTransitioning, setIsTransitioning] = React.useState(false);
+ // eslint-disable-next-line @eslint-react/no-unused-state
const [key, setKey] = React.useState(0);
React.useEffect(() => {
diff --git a/apps/docs/src/components/text-animate.tsx b/apps/docs/src/components/text-animate.tsx
index b1a785a08..0f7f3a87c 100644
--- a/apps/docs/src/components/text-animate.tsx
+++ b/apps/docs/src/components/text-animate.tsx
@@ -314,8 +314,10 @@ const TextAnimateBase = ({
animation = "fadeIn",
...props
}: TextAnimateProps) => {
+ // eslint-disable-next-line @eslint-react/static-components
const MotionComponent = motion.create(Component);
+ // eslint-disable-next-line no-useless-assignment
let segments: string[] = [];
switch (by) {
case "character":
@@ -388,6 +390,7 @@ const TextAnimateBase = ({
return (
+ {/* eslint-disable-next-line react-hooks/static-components, @eslint-react/static-components */}
=22"
diff --git a/packages/config/eslint.react.config.mjs b/packages/config/eslint.react.config.mjs
index 330937bad..76cc62641 100644
--- a/packages/config/eslint.react.config.mjs
+++ b/packages/config/eslint.react.config.mjs
@@ -1,14 +1,12 @@
// @ts-check
import eslintReact from "@eslint-react/eslint-plugin";
-import reactPlugin from "eslint-plugin-react";
import hooksPlugin from "eslint-plugin-react-hooks";
import reactYouMightNotNeedAnEffect from "eslint-plugin-react-you-might-not-need-an-effect";
export default [
reactYouMightNotNeedAnEffect.configs.recommended,
eslintReact.configs.recommended,
- reactPlugin.configs.flat.recommended,
{
files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"],
settings: {
diff --git a/packages/config/package.json b/packages/config/package.json
index 94986cf52..370f82979 100644
--- a/packages/config/package.json
+++ b/packages/config/package.json
@@ -37,24 +37,24 @@
}
},
"peerDependencies": {
- "eslint": "^9.0.0",
- "prettier": "^3.0.0",
- "typescript": "5.9.x"
+ "eslint": "^10.0.0",
+ "prettier": "^3.x.x",
+ "typescript": "6.0.x"
},
"devDependencies": {
- "typescript": "^5.9.3"
+ "eslint": "^10.2.1",
+ "typescript": "^6.0.3"
},
"dependencies": {
- "@eslint-react/eslint-plugin": "^2.3.5",
- "@eslint/js": "^9.39.1",
+ "@eslint-react/eslint-plugin": "^5.7.0",
+ "@eslint/js": "^10.0.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-jsx-a11y": "^6.10.2",
- "eslint-plugin-perfectionist": "^4.15.1",
- "eslint-plugin-prettier": "^5.5.4",
- "eslint-plugin-react": "^7.37.5",
- "eslint-plugin-react-hooks": "^5.2.0",
- "eslint-plugin-react-you-might-not-need-an-effect": "^0.7.0",
- "prettier-plugin-tailwindcss": "^0.7.1",
- "typescript-eslint": "^8.46.4"
+ "eslint-plugin-perfectionist": "^5.9.0",
+ "eslint-plugin-prettier": "^5.5.5",
+ "eslint-plugin-react-hooks": "^7.1.1",
+ "eslint-plugin-react-you-might-not-need-an-effect": "^0.9.3",
+ "prettier-plugin-tailwindcss": "^0.8.0",
+ "typescript-eslint": "^8.59.1"
}
}
diff --git a/packages/create-vitnode-app/package.json b/packages/create-vitnode-app/package.json
index 416b279ab..51d80f4c1 100644
--- a/packages/create-vitnode-app/package.json
+++ b/packages/create-vitnode-app/package.json
@@ -35,18 +35,18 @@
"typescript"
],
"dependencies": {
- "@inquirer/prompts": "^7.10.1",
- "commander": "^14.0.2",
- "ora": "^9.0.0",
+ "@inquirer/prompts": "^8.4.2",
+ "commander": "^14.0.3",
+ "ora": "^9.4.0",
"picocolors": "^1.1.1",
- "validate-npm-package-name": "^7.0.0"
+ "validate-npm-package-name": "^7.0.2"
},
"devDependencies": {
- "@types/node": "^24.10.1",
+ "@types/node": "^25.6.0",
"@types/prompts": "^2.4.9",
"@types/validate-npm-package-name": "^4.0.2",
"@vitnode/config": "workspace:*",
- "eslint": "^9.39.1",
- "typescript": "^5.9.3"
+ "eslint": "^10.2.1",
+ "typescript": "^6.0.3"
}
}
diff --git a/packages/create-vitnode-app/src/create/create-package-json.ts b/packages/create-vitnode-app/src/create/create-package-json.ts
index a3c614ce9..159da5622 100644
--- a/packages/create-vitnode-app/src/create/create-package-json.ts
+++ b/packages/create-vitnode-app/src/create/create-package-json.ts
@@ -135,7 +135,7 @@ const apiDeps = {
};
const apiDevDeps = (pm: string, eslint: boolean) => ({
- "@hono/node-server": "^1.19",
+ "@hono/node-server": "^2.0",
...(pm === "bun" ? { "@types/bun": versionsPackageJson.typesBun } : {}),
"@types/node": versionsPackageJson.typesNode,
"@types/react": versionsPackageJson.typesReact,
diff --git a/packages/create-vitnode-app/src/create/package-versions.ts b/packages/create-vitnode-app/src/create/package-versions.ts
index b68a06ba2..b80e164ff 100644
--- a/packages/create-vitnode-app/src/create/package-versions.ts
+++ b/packages/create-vitnode-app/src/create/package-versions.ts
@@ -1,46 +1,46 @@
export const versionsPackageJson = {
- typesNode: "^24",
+ typesNode: "^25",
typesReact: "^19.2",
typesReactDom: "^19.2",
typesBun: "latest",
- turbo: "^2.6",
- typescript: "^5.9",
- tsx: "^4.20.6",
+ turbo: "^2.9",
+ typescript: "^6.0",
+ tsx: "^4.21",
tscAlias: "^1.8.16",
- eslint: "^9.39.1",
- prettier: "^3.6.2",
- prettierTailwind: "^0.6.14",
- tailwind: "^4.1.17",
- tailwindPostcss: "^4.1.17",
- postcss: "^8.5.6",
+ eslint: "^10",
+ prettier: "^3.8.3",
+ prettierTailwind: "^0.8",
+ tailwind: "^4.2",
+ tailwindPostcss: "^4.2",
+ postcss: "^8.5",
twAnimateCss: "^1.4.0",
react: "^19.2",
reactDom: "^19.2",
- nextSingle: "^16.0",
- nextIntl: "^4.5",
- useIntl: "^4.5",
- rhf: "^7.66.0",
+ nextSingle: "^16.2",
+ nextIntl: "^4.11",
+ useIntl: "^4.11",
+ rhf: "^7.74",
rhfResolvers: "^5.1.1",
- lucide: "^0.553.0",
+ lucide: "^1.14",
sonner: "^2.0.7",
- dotenv: "^17.2.2",
+ dotenv: "^17.4",
- drizzleKit: "^0.31.7",
- drizzleOrm: "^0.44.7",
+ drizzleKit: "^0.31.10",
+ drizzleOrm: "^0.45.2",
- hono: "^4.10",
- honoZodOpenapi: "^1.1.4",
- honoZodValidator: "^0.7.4",
- reactEmail: "^5.0",
+ hono: "^4.12",
+ honoZodOpenapi: "^1.3",
+ honoZodValidator: "^0.7.6",
+ reactEmail: "^6.0",
reactEmailComponents: "^1.0",
- zod: "^4.1.12",
+ zod: "^4.4",
cva: "^0.7.1",
babelPluginReactCompiler: "^1.0",
- swcCli: "^0.7.9",
- swcCore: "^1.15.1",
+ swcCli: "^0.8.1",
+ swcCore: "^1.15",
concurrently: "^9.2.1",
};
diff --git a/packages/create-vitnode-app/tsconfig.json b/packages/create-vitnode-app/tsconfig.json
index 5c28c650c..e0cb51e39 100644
--- a/packages/create-vitnode-app/tsconfig.json
+++ b/packages/create-vitnode-app/tsconfig.json
@@ -5,6 +5,7 @@
"target": "ESNext",
"module": "NodeNext",
"moduleResolution": "nodenext",
+ "types": ["node"],
"rootDir": "./",
"outDir": "./dist",
"strict": true,
diff --git a/packages/node-cron/package.json b/packages/node-cron/package.json
index 1cc4edbb6..8468fa8c8 100644
--- a/packages/node-cron/package.json
+++ b/packages/node-cron/package.json
@@ -34,13 +34,13 @@
"node-cron": "^4.2.1"
},
"devDependencies": {
- "@swc/cli": "^0.7.9",
- "@swc/core": "^1.15.2",
+ "@swc/cli": "^0.8.1",
+ "@swc/core": "^1.15.32",
"@vitnode/config": "workspace:*",
"@vitnode/core": "workspace:*",
"concurrently": "^9.2.1",
- "eslint": "^9.39.1",
+ "eslint": "^10.2.1",
"tsc-alias": "^1.8.16",
- "typescript": "^5.9.3"
+ "typescript": "^6.0.3"
}
}
diff --git a/packages/node-cron/tsconfig.json b/packages/node-cron/tsconfig.json
index 7593a944f..a7d082399 100644
--- a/packages/node-cron/tsconfig.json
+++ b/packages/node-cron/tsconfig.json
@@ -5,8 +5,9 @@
"target": "ESNext",
"module": "esnext",
"moduleResolution": "bundler",
- "rootDir": "./",
+ "rootDir": "./src",
"outDir": "./dist",
+ "incremental": false,
"emitDeclarationOnly": true,
"declaration": true,
"declarationMap": true,
diff --git a/packages/nodemailer/package.json b/packages/nodemailer/package.json
index bb5b93120..1b4ce8065 100644
--- a/packages/nodemailer/package.json
+++ b/packages/nodemailer/package.json
@@ -30,17 +30,17 @@
"lint:fix": "eslint . --fix"
},
"dependencies": {
- "nodemailer": "^7.0.10"
+ "nodemailer": "^8.0.7"
},
"devDependencies": {
- "@swc/cli": "^0.7.9",
- "@swc/core": "^1.15.2",
- "@types/nodemailer": "^7.0.3",
+ "@swc/cli": "^0.8.1",
+ "@swc/core": "^1.15.32",
+ "@types/nodemailer": "^7.0.11",
"@vitnode/config": "workspace:*",
"@vitnode/core": "workspace:*",
"concurrently": "^9.2.1",
- "eslint": "^9.39.1",
+ "eslint": "^10.2.1",
"tsc-alias": "^1.8.16",
- "typescript": "^5.9.3"
+ "typescript": "^6.0.3"
}
}
diff --git a/packages/nodemailer/tsconfig.json b/packages/nodemailer/tsconfig.json
index 7593a944f..a7d082399 100644
--- a/packages/nodemailer/tsconfig.json
+++ b/packages/nodemailer/tsconfig.json
@@ -5,8 +5,9 @@
"target": "ESNext",
"module": "esnext",
"moduleResolution": "bundler",
- "rootDir": "./",
+ "rootDir": "./src",
"outDir": "./dist",
+ "incremental": false,
"emitDeclarationOnly": true,
"declaration": true,
"declarationMap": true,
diff --git a/packages/resend/package.json b/packages/resend/package.json
index 4566d2fa2..6eded8a3d 100644
--- a/packages/resend/package.json
+++ b/packages/resend/package.json
@@ -29,16 +29,16 @@
"lint:fix": "eslint . --fix"
},
"dependencies": {
- "resend": "^6.4.2"
+ "resend": "^6.12.2"
},
"devDependencies": {
- "@swc/cli": "^0.7.9",
- "@swc/core": "^1.15.2",
+ "@swc/cli": "^0.8.1",
+ "@swc/core": "^1.15.32",
"@vitnode/config": "workspace:*",
"@vitnode/core": "workspace:*",
"concurrently": "^9.2.1",
- "eslint": "^9.39.1",
+ "eslint": "^10.2.1",
"tsc-alias": "^1.8.16",
- "typescript": "^5.9.3"
+ "typescript": "^6.0.3"
}
}
diff --git a/packages/resend/tsconfig.json b/packages/resend/tsconfig.json
index 7593a944f..a7d082399 100644
--- a/packages/resend/tsconfig.json
+++ b/packages/resend/tsconfig.json
@@ -5,8 +5,9 @@
"target": "ESNext",
"module": "esnext",
"moduleResolution": "bundler",
- "rootDir": "./",
+ "rootDir": "./src",
"outDir": "./dist",
+ "incremental": false,
"emitDeclarationOnly": true,
"declaration": true,
"declarationMap": true,
diff --git a/packages/vitnode/components.json b/packages/vitnode/components.json
index d20ce6a8f..797c749cb 100644
--- a/packages/vitnode/components.json
+++ b/packages/vitnode/components.json
@@ -1,15 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
- "style": "new-york",
+ "style": "base-nova",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/views/global.css",
- "baseColor": "neutral",
+ "baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
+ "iconLibrary": "lucide",
+ "rtl": true,
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
@@ -17,5 +19,7 @@
"lib": "@/lib",
"hooks": "@/hooks"
},
- "iconLibrary": "lucide"
+ "menuColor": "default",
+ "menuAccent": "subtle",
+ "registries": {}
}
diff --git a/packages/vitnode/package.json b/packages/vitnode/package.json
index e9f3ff958..4762347a5 100644
--- a/packages/vitnode/package.json
+++ b/packages/vitnode/package.json
@@ -37,45 +37,45 @@
"zod": "^4.x.x"
},
"devDependencies": {
- "@hono/zod-openapi": "^1.1.4",
- "@hono/zod-validator": "^0.7.4",
+ "@hono/zod-openapi": "^1.3.0",
+ "@hono/zod-validator": "^0.7.6",
"@hookform/resolvers": "^5.2.2",
- "@react-email/components": "^1.0.1",
- "@swc/cli": "^0.7.9",
- "@swc/core": "^1.15.2",
+ "@react-email/components": "^1.0.12",
+ "@swc/cli": "^0.8.1",
+ "@swc/core": "^1.15.32",
"@testing-library/dom": "^10.4.1",
- "@testing-library/react": "^16.3.0",
- "@types/node": "^24.10.1",
- "@types/react": "^19.2.5",
+ "@testing-library/react": "^16.3.2",
+ "@types/node": "^25.6.0",
+ "@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
- "@vitejs/plugin-react": "^5.1.1",
- "@vitest/coverage-v8": "^4.0.9",
+ "@vitejs/plugin-react": "^6.0.1",
+ "@vitest/coverage-v8": "^4.1.5",
"@vitnode/config": "workspace:*",
- "chokidar": "^4.0.3",
+ "chokidar": "^5.0.0",
"concurrently": "^9.2.1",
- "drizzle-kit": "^0.31.7",
- "drizzle-orm": "^0.44.7",
- "eslint": "^9.39.1",
- "hono": "^4.10.6",
+ "drizzle-kit": "^0.31.10",
+ "drizzle-orm": "^0.45.2",
+ "eslint": "^10.2.1",
+ "hono": "^4.12.16",
"jiti": "^2.6.1",
- "jsdom": "^27.2.0",
- "lucide-react": "^0.553.0",
- "next": "^16.0.3",
- "next-intl": "^4.5.3",
- "react": "^19.2.0",
- "react-dom": "^19.2.0",
- "react-email": "^5.0.4",
- "react-hook-form": "^7.66.0",
+ "jsdom": "^29.1.1",
+ "lucide-react": "^1.14.0",
+ "next": "^16.2.4",
+ "next-intl": "^4.11.0",
+ "react": "^19.2.5",
+ "react-dom": "^19.2.5",
+ "react-email": "^6.0.5",
+ "react-hook-form": "^7.74.0",
"sonner": "^2.0.7",
- "tailwindcss": "^4.1.17",
+ "tailwindcss": "^4.2.4",
"tsc-alias": "^1.8.16",
"tsup": "^8.5.1",
- "tsx": "^4.20.6",
+ "tsx": "^4.21.0",
"tw-animate-css": "^1.4.0",
- "typescript": "^5.9.3",
- "vite-tsconfig-paths": "^5.1.4",
- "vitest": "^4.0.9",
- "zod": "^4.1.12"
+ "typescript": "^6.0.3",
+ "vite": "^8.0.10",
+ "vitest": "^4.1.5",
+ "zod": "^4.4.1"
},
"bin": {
"vitnode": "./dist/scripts/scripts.js"
@@ -111,28 +111,29 @@
"dependencies": {
"@bprogress/next": "^3.2.12",
"@dnd-kit/core": "^6.3.1",
- "@hono/swagger-ui": "^0.5.2",
- "@react-email/preview-server": "^5.0.4",
- "@tanstack/react-query": "^5.90.9",
- "@tiptap/extension-text-align": "^3.10.7",
- "@tiptap/pm": "^3.10.7",
- "@tiptap/react": "^3.10.7",
- "@tiptap/starter-kit": "^3.10.7",
+ "@hono/swagger-ui": "^0.6.1",
+ "@react-email/preview-server": "^5.2.10",
+ "@tanstack/react-query": "^5.100.6",
+ "@tiptap/extension-text-align": "^3.22.5",
+ "@tiptap/pm": "^3.22.5",
+ "@tiptap/react": "^3.22.5",
+ "@tiptap/starter-kit": "^3.22.5",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
- "cron-parser": "^5.4.0",
- "dotenv": "^17.2.3",
+ "cron-parser": "^5.5.0",
+ "dotenv": "^17.4.2",
"input-otp": "^1.4.2",
- "motion": "^12.23.24",
+ "motion": "^12.38.0",
"next-themes": "^0.4.6",
- "postgres": "^3.4.7",
+ "postgres": "^3.4.9",
"radix-ui": "^1.4.3",
- "rate-limiter-flexible": "^8.2.1",
- "react-scan": "^0.4.3",
- "tailwind-merge": "^3.4.0",
- "use-debounce": "^10.0.6",
- "use-intl": "^4.5.3",
+ "rate-limiter-flexible": "^11.0.1",
+ "react-scan": "^0.5.3",
+ "server-only": "^0.0.1",
+ "tailwind-merge": "^3.5.0",
+ "use-debounce": "^10.1.1",
+ "use-intl": "^4.11.0",
"vaul": "^1.1.2"
}
}
diff --git a/packages/vitnode/src/api/lib/route.ts b/packages/vitnode/src/api/lib/route.ts
index e2f217ef4..a080d7522 100644
--- a/packages/vitnode/src/api/lib/route.ts
+++ b/packages/vitnode/src/api/lib/route.ts
@@ -44,7 +44,7 @@ export const buildRoute = <
: []),
],
...route,
- }) as R & { path: P },
+ }),
handler: handler as Route["handler"],
pluginId,
};
diff --git a/packages/vitnode/src/api/lib/with-pagination.ts b/packages/vitnode/src/api/lib/with-pagination.ts
index 35497680e..a40fc100f 100644
--- a/packages/vitnode/src/api/lib/with-pagination.ts
+++ b/packages/vitnode/src/api/lib/with-pagination.ts
@@ -142,11 +142,7 @@ export async function withPagination<
primaryCursor,
);
- const totalCount = await fetchTotalCount(
- c,
- table as PgTable,
- whereFromParams,
- );
+ const totalCount = await fetchTotalCount(c, table, whereFromParams);
const limit = (first ?? last ?? 50) + 1;
const edges = await query({ limit, where, orderBy });
diff --git a/packages/vitnode/src/api/middlewares/rate-limiter.middleware.ts b/packages/vitnode/src/api/middlewares/rate-limiter.middleware.ts
index 1c4e54055..b5581584d 100644
--- a/packages/vitnode/src/api/middlewares/rate-limiter.middleware.ts
+++ b/packages/vitnode/src/api/middlewares/rate-limiter.middleware.ts
@@ -18,8 +18,6 @@ const createRateLimiter = ({
return new RateLimiterMemory({
keyPrefix,
- points: options?.points ?? 80, // 80 in prod
- duration: options?.duration ?? 60, // per 60 seconds
...options,
});
};
@@ -37,6 +35,8 @@ export const rateLimiterMiddleware = (
const rateLimiter = createRateLimiter({
...options,
keyPrefix: "vitnode-api-rate-limiter",
+ duration: options?.duration ?? 60,
+ points: options?.points ?? 80,
});
return async (c: Context, next: Next) => {
diff --git a/packages/vitnode/src/components/date-format.tsx b/packages/vitnode/src/components/date-format.tsx
index 0e8431d1b..5825d591c 100644
--- a/packages/vitnode/src/components/date-format.tsx
+++ b/packages/vitnode/src/components/date-format.tsx
@@ -24,6 +24,7 @@ export const DateFormat = ({
updateInterval:
updateInterval ??
// Update it every 1 minute if the date is from today, otherwise don't update
+ // eslint-disable-next-line react-hooks/purity, @eslint-react/purity
(Date.now() - dateToFormat.getTime() < 86400000 ? 60000 : 0),
});
diff --git a/packages/vitnode/src/components/form/fields/combobox-async.tsx b/packages/vitnode/src/components/form/fields/combobox-async.tsx
index ea716fe50..0a94bfdc4 100644
--- a/packages/vitnode/src/components/form/fields/combobox-async.tsx
+++ b/packages/vitnode/src/components/form/fields/combobox-async.tsx
@@ -69,6 +69,46 @@ export const AutoFormComboboxAsync = ({
setSearch(value);
}, 500);
+ const renderCommandList = () => {
+ if (isLoading) {
+ return (
+
+
+
+
+ );
+ }
+
+ if ((data ?? []).length === 0) {
+ return {t("results_not_found")};
+ }
+
+ return (
+
+ {(data ?? []).map(({ label, value }) => (
+ {
+ field.onChange({
+ label,
+ value,
+ });
+ }}
+ value={label}
+ >
+ {label}
+
+
+ ))}
+
+ );
+ };
+
return (
{label && (
@@ -83,7 +123,7 @@ export const AutoFormComboboxAsync = ({