Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,578 changes: 775 additions & 803 deletions .agents/skills/vercel-react-best-practices/AGENTS.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ Popular icon and component libraries can have **up to 10,000 re-exports** in the
**Incorrect (imports entire library):**

```tsx
import { Check, X, Menu } from 'lucide-react'
import { Check, X, Menu } from "lucide-react";
// Loads 1,583 modules, takes ~2.8s extra in dev
// Runtime cost: 200-800ms on every cold start

import { Button, TextField } from '@mui/material'
import { Button, TextField } from "@mui/material";
// Loads 2,225 modules, takes ~4.2s extra in dev
```

Expand All @@ -30,14 +30,14 @@ import { Button, TextField } from '@mui/material'
// next.config.js - automatically optimizes barrel imports at build time
module.exports = {
experimental: {
optimizePackageImports: ['lucide-react', '@mui/material']
}
}
optimizePackageImports: ["lucide-react", "@mui/material"],
},
};
```

```tsx
// Keep the standard imports - Next.js transforms them to direct imports
import { Check, X, Menu } from 'lucide-react'
import { Check, X, Menu } from "lucide-react";
// Full TypeScript support, no manual path wrangling
```

Expand All @@ -46,15 +46,15 @@ This is the recommended approach because it preserves TypeScript type safety and
**Correct - Direct imports (non-Next.js projects):**

```tsx
import Button from '@mui/material/Button'
import TextField from '@mui/material/TextField'
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
// Loads only what you use
```

> **TypeScript warning:** Some libraries (notably `lucide-react`) don't ship `.d.ts` files for their deep import paths. Importing from `lucide-react/dist/esm/icons/check` resolves to an implicit `any` type, causing errors under `strict` or `noImplicitAny`. Prefer `optimizePackageImports` when available, or verify the library exports types for its subpaths before using direct imports.

These optimizations provide 15-70% faster dev boot, 28% faster builds, 40% faster cold starts, and significantly faster HMR.

Libraries commonly affected: `lucide-react`, `@mui/material`, `@mui/icons-material`, `@tabler/icons-react`, `react-icons`, `@headlessui/react`, `@radix-ui/react-*`, `lodash`, `ramda`, `date-fns`, `rxjs`, `react-use`.
Libraries commonly affected: `lucide-react`, `@mui/material`, `@mui/icons-material`, `@tabler/icons-react`, `react-icons`, `@headlessui/react`, `lodash`, `ramda`, `date-fns`, `rxjs`, `react-use`.

Reference: [How we optimized package imports in Next.js](https://vercel.com/blog/how-we-optimized-package-imports-in-next-js)
6 changes: 5 additions & 1 deletion apps/api/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
POSTGRES_URL=postgresql://root:root@localhost:5432/vitnode
REDIS_URL=redis://localhost:6379

NEXT_PUBLIC_WEB_URL=http://localhost:3000

Expand All @@ -8,4 +9,7 @@ CRON_SECRET=your-secure-cron-secret-key
# === Docker Database Postgres ===
POSTGRES_USER=root
POSTGRES_PASSWORD=root
POSTGRES_NAME=vitnode
POSTGRES_NAME=vitnode

# === Docker Redis ===
REDIS_PASSWORD=root
1 change: 1 addition & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@hono/zod-openapi": "^1.4.0",
"@hono/zod-validator": "^0.8.0",
"@vitnode/core": "workspace:*",
"@vitnode/node-cron": "workspace:*",
"drizzle-kit": "^0.31.10",
"drizzle-orm": "^0.45.2",
"hono": "^4.12.27",
Expand Down
38 changes: 38 additions & 0 deletions apps/api/src/locales/@vitnode/core/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,44 @@
"debug": {
"title": "Debug Panel",
"desc": "Check logs, errors, and other debug information.",
"integrations": {
"title": "Integrations",
"desc": "Status of the core services that power this instance.",
"read_more": "Read more",
"status": {
"active": "Active",
"inactive": "Inactive",
"warning": "Unreachable"
},
"websocket": {
"title": "WebSocket",
"desc": "Live updates and notifications pushed to connected clients in real time."
},
"redis": {
"title": "Redis",
"desc": "Shared cache and rate-limiter storage. Falls back to in-memory when off.",
"down": "Configured but unreachable — check your Redis connection."
},
"email": {
"title": "Email",
"desc": "Transactional emails such as sign-up confirmations and password resets."
},
"captcha": {
"title": "Captcha",
"desc": "Bot protection on public forms like sign-up and password reset.",
"type": {
"cloudflare_turnstile": "Cloudflare Turnstile",
"recaptcha_v3": "reCAPTCHA v3"
}
},
"cron": {
"title": "Cron Jobs",
"desc": "Scheduled background tasks such as clearing expired sessions and tokens.",
"insecure": "Using the default CRON_SECRET — set a secure one in production.",
"not_configured": "No cron adapter configured — jobs won't run automatically.",
"jobs": "{count, plural, =0 {No jobs scheduled} one {# job scheduled} other {# jobs scheduled}}"
}
},
"actions": {
"clear_cache": {
"label": "Clear Cache",
Expand Down
5 changes: 5 additions & 0 deletions apps/api/src/vitnode.api.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { blogApiPlugin } from "@vitnode/blog/config.api";
import { buildApiConfig } from "@vitnode/core/vitnode.config";
import { NodeCronAdapter } from "@vitnode/node-cron";
import { NodemailerEmailAdapter } from "@vitnode/nodemailer";
import { config } from "dotenv";
import { drizzle } from "drizzle-orm/postgres-js";
Expand All @@ -18,6 +19,10 @@ export const vitNodeApiConfig = buildApiConfig({
connection: POSTGRES_URL,
casing: "camelCase",
}),
cron: NodeCronAdapter(),
redis: process.env.REDIS_URL
? { url: process.env.REDIS_URL, password: process.env.REDIS_PASSWORD }
: undefined,
email: {
adapter: NodemailerEmailAdapter({
from: process.env.NODE_MAILER_FROM,
Expand Down
6 changes: 5 additions & 1 deletion apps/docs/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
POSTGRES_URL=postgresql://root:root@localhost:5432/vitnode
REDIS_URL=redis://localhost:6379

NEXT_PUBLIC_API_URL=http://localhost:3000
NEXT_PUBLIC_WEB_URL=http://localhost:3000
Expand All @@ -9,4 +10,7 @@ CRON_SECRET=your-secure-cron-secret-key
# === Docker Database Postgres ===
POSTGRES_USER=root
POSTGRES_PASSWORD=root
POSTGRES_NAME=vitnode
POSTGRES_NAME=vitnode

# === Docker Redis ===
REDIS_PASSWORD=root
Loading
Loading