# Docs - Development: Build VitNode plugins: pages, APIs, database tables and AdminCP screens in one installable package - **Start here** - [Introduction](/docs/dev): Build a TanStack Start and Hono application with VitNode plugins, then deploy and operate it confidently. - [Getting Started](/docs/dev/setup): Create a VitNode app, prepare Postgres, start TanStack Start, and sign in to AdminCP in five small steps. - Deployments: Deploy a VitNode application to production with cloud or self-hosted infrastructure - [Self-Hosted Deployment](/docs/dev/deployments/self-hosted): Build, migrate, and run VitNode on your own server or Docker container with a reverse proxy. - Cloud: Managed platforms, and what they cannot run - [Vercel](/docs/dev/deployments/cloud/vercel): Deploy a VitNode app to Vercel: the settings that work, the features that need a server which stays up, and where migrations have to run instead. - [Architecture](/docs/dev/architecture): How VitNode combines TanStack Start for UI and isomorphic routing with Hono for API authorization and database access. - [Configuration](/docs/dev/configuration): The two config files a VitNode app owns - the browser-safe shared one, and the server-only companion - plus the request pipeline Core installs for you. - **Framework** - Plugins: Build installable VitNode plugins for pages, APIs, data, AdminCP screens, and translations - [Create a Plugin](/docs/dev/plugins/create): Scaffold a VitNode plugin, register its package in your host app, and serve its first TanStack Start page. - [Plugin Routes](/docs/dev/plugins/routes): Declare plugin-owned URLs as a nested route tree with lazy pages, loaders, metadata, messages, and breadcrumbs. - REST API: Build typed Hono modules and routes inside your VitNode plugin - [API Modules](/docs/dev/plugins/api/modules): Add a typed Hono API module to a VitNode plugin, register it once, and keep endpoint ownership with the feature. - [API Routes](/docs/dev/plugins/api/routes): Validate plugin-owned Hono route inputs and responses with Zod, then protect staff actions with a clear permission. - Admin Control Panel: Add plugin-owned AdminCP pages, navigation, permissions and dashboard widgets - [AdminCP Pages](/docs/dev/plugins/admin): Add plugin-owned AdminCP pages, navigation, permissions, and dashboard extensions to the VitNode admin panel. - [Dashboard Widgets](/docs/dev/plugins/admin/dashboard-widgets): Add a configurable AdminCP dashboard widget from a VitNode plugin with sizing, permissions, and optional settings. - [Breadcrumbs](/docs/dev/plugins/breadcrumbs): Contribute one localized crumb per plugin route and let VitNode assemble the trail for public pages and AdminCP screens. - Routing: Claim a URL, name the page, and let the router handle locales - [Routing](/docs/dev/routing): Add public and AdminCP URLs through a plugin's route tree, with TanStack Start loaders, metadata, and code splitting. - [Navigation](/docs/dev/routing/navigation): Link between pages with the router's own Link, let VitNode write the locale prefix, and navigate from code after a form submits. - [Metadata & SEO](/docs/dev/routing/metadata): Give plugin pages concise titles, descriptions, and robots directives through TanStack Start route metadata. - [Loading States](/docs/dev/routing/loading-states): Render instant skeleton shapes while TanStack Start routes load data or download chunks. - [404 Not Found](/docs/dev/routing/not-found): Configure root and per-route 404 error boundaries and throw notFound() from TanStack Start loaders. - [Fetcher](/docs/dev/fetcher): Call your Hono API with end-to-end type safety. - [Data Loading](/docs/dev/data-loading): Load data in TanStack Start routes with server-side query warming and client-side suspense. - [Cache](/docs/dev/cache): VitNode's two caching layers - TanStack Query entries on the front end, and a Redis-backed cache inside Hono route handlers on the API. - [Server Functions & Isomorphic Fetching](/docs/dev/server-functions): When to reach for the universal fetcher, the server fetcher, or a TanStack Start server function in VitNode. - Database: Learn how to work with databases in VitNode plugins using Drizzle ORM and PostgreSQL. - [Database & Migrations](/docs/dev/database): Define PostgreSQL schemas with Drizzle ORM in VitNode plugins, generate migrations, and execute queries. - [Pagination](/docs/dev/database/pagination): Add stable cursor pagination to a plugin API route and navigate its results from a typed plugin page. - [Search](/docs/dev/database/search): Add case-insensitive search to one paginated plugin table with withPagination and the shared table UI. - Internationalization (I18n): Learn how to make your VitNode plugins multilingual with our I18n guide. - [Languages & Localization](/docs/dev/i18n): How VitNode merges translations from installed packages, and how to add, translate, and override languages. - [Messages & ICU Syntax](/docs/dev/i18n/messages): Format strings with ICU message syntax in VitNode, including variables, pluralization, rich text tags, and select rules. - [Translating Pages](/docs/dev/i18n/pages): Render localized strings with use-intl, declare route namespaces, and load translation bundles. - [Namespaces](/docs/dev/i18n/namespaces): How VitNode partitions its message tree per plugin, how a page asks for only the branches it renders, and the limits a namespace has to satisfy. - [API i18n](/docs/dev/i18n/server): Translate emails and API responses with VitNode's request-scoped API translator. - [Performance](/docs/dev/performance): Optimize bundle sizes, code splitting, and loading performance in VitNode and TanStack Start. - **Extend VitNode** - Content Engine: Declare a content type once, get the table, API, AdminCP, permissions and events - [Content Engine Overview](/docs/dev/content-engine): Declare a content type once in TypeScript and get a Postgres table, Zod schemas, CRUD routes, staff permissions, and AdminCP screens. - [Defining a Content Type](/docs/dev/content-engine/defining-a-content-type): Declare a Content Engine content type once to get a Postgres table, typed CRUD routes, and interactive AdminCP screens. - [Field Reference](/docs/dev/content-engine/fields): Complete guide to adding and configuring field types in Content Engine, including Postgres mappings, Zod validation, and AdminCP controls. - [Database & Migrations](/docs/dev/content-engine/database-and-migrations): How the Content Engine maps content models to PostgreSQL tables using createContentModel, handles system columns, and executes Drizzle Kit migrations. - [Content Services & API](/docs/dev/content-engine/services-and-api): Call generated Content Engine services from custom Hono routes, use typed Zod schemas, and listen to content events. - [Publication & Editorial](/docs/dev/content-engine/publication-and-editorial): Add draft/published lifecycles, revision histories, signed preview links, and scheduled publishing to content types. - [Public API and Caching](/docs/dev/content-engine/public-api-and-caching): Expose safe Content Engine fields from a plugin API and configure cache invalidation without framework-specific glue. - [Localization & Translations](/docs/dev/content-engine/localization): Step-by-step guide to building multi-language content models with localized fields, translation tables, independent workflows, and localized public APIs. - [Relations & Advanced Modeling](/docs/dev/content-engine/relations-and-advanced-modeling): Connect content types with foreign keys, junction tables, field groups, and repeatable child records. - [Content Delivery and SEO](/docs/dev/content-engine/content-delivery-and-seo): Deliver Content Engine records from a plugin with canonical metadata, slug redirects, hreflang, and XML sitemap support. - [Plugin Frontend Modules](/docs/dev/content-engine/plugin-registration): How plugins export AdminCP navigation, Content Engine screens, and runtime configs with optimized code splitting. - [AdminCP Integration](/docs/dev/content-engine/admincp): Configure zero-code AdminCP management screens, custom form layouts, list columns, and screen overrides. - [Production & Security](/docs/dev/content-engine/production-and-security): Step-by-step guide to concurrency control, security enforcement, failure retries, performance scaling, and system limitations. - Working with Users: The user model, roles, and the staff permission system - how VitNode decides who somebody is and what they are allowed to do. - [Users & Sessions](/docs/dev/working-with-users/users): Access signed-in user context in Hono API handlers, route loaders, and React components. - [Roles](/docs/dev/working-with-users/roles): Manage user roles, primary and secondary group memberships, role colors, and default seeded groups. - [Staff Permissions](/docs/dev/working-with-users/staff-permissions): Declare granular staff permissions in VitNode plugins, enforce them on Hono routes, and gate AdminCP UI controls. - Events: Emit typed domain events and react to them from any plugin - [Events](/docs/dev/events): Emit typed domain events from VitNode plugins and subscribe with isolated, typed event listeners. - [Built-in Events](/docs/dev/events/built-in-events): Reference for every domain event VitNode core, the Content Engine and the blog plugin emit, with its trigger, its payload shape and a listener use case. - [Custom Event Adapter](/docs/dev/events/custom-adapter): Build a custom event transport adapter to distribute VitNode domain events across multiple instances via message brokers like Redis Streams or RabbitMQ. - **Services** - AI: Register Vercel AI SDK models once, then resolve them in any route with c.get("ai") - [AI Setup](/docs/dev/ai): Configure Vercel AI SDK providers and models in VitNode API config to use with c.get("ai"). - [AI Usage](/docs/dev/ai/usage): Text generation, streaming responses, structured output, and embeddings using the Vercel AI SDK and VitNode model registry. - [Search & Discovery](/docs/dev/search): Enable site-wide full-text search across plugin content with Postgres or Elasticsearch ranking engines. - [Elasticsearch](/docs/dev/search-elasticsearch): Replace VitNode's default Postgres search provider with Elasticsearch or OpenSearch and rebuild your index safely. - Storage: Pluggable file uploads - local disk, AWS S3, Cloudflare R2 or Supabase Storage - [Storage](/docs/dev/storage): Upload, serve, and delete files in VitNode with pluggable storage adapters - local disk, AWS S3, Cloudflare R2, or Supabase Storage. - [Local (disk)](/docs/dev/storage/local): The zero-config VitNode storage adapter - writes uploads to public/uploads on the API server and serves them back as static files. - **Adapters** - [AWS S3 / Cloudflare R2](/docs/dev/storage/s3-r2): Store VitNode uploads in an S3-compatible bucket with @vitnode/s3 - one adapter for AWS S3, Cloudflare R2 and anything that speaks the S3 API. - [Supabase Storage](/docs/dev/storage/supabase): Store VitNode uploads in a Supabase Storage bucket with @vitnode/supabase-storage - a secret key, a bucket name and one adapter call. - [Custom adapter](/docs/dev/storage/custom-adapter): Write your own VitNode storage adapter - implement StorageApiPlugin's upload, delete and getUrl and store uploaded files anywhere. - Email: Transactional email with React Email templates and pluggable adapters - [Email](/docs/dev/email): Send transactional emails with React Email templates, recipient-locale rendering, and pluggable delivery adapters. - [Email Templates](/docs/dev/email/templates): Build responsive, localized email templates with React Email and VitNode default layouts. - Components: Buttons and cards for VitNode email templates - [Button](/docs/dev/email/components/button): EmailButton renders a call-to-action link for VitNode emails, with the same variants and sizes as the app button. - [Card](/docs/dev/email/components/card): EmailCard gives a VitNode email a bordered container with header, title, description, content and footer sections. - [More Components](https://react.email/components) - **Adapters** - [Resend](/docs/dev/email/resend): Deliver VitNode email through Resend's HTTPS API - install the adapter, add a key, verify the domain, watch the first mail land. - [Nodemailer (SMTP)](/docs/dev/email/nodemailer): Deliver VitNode email over SMTP with the Nodemailer adapter - local mail catcher for development, any relay in production. - **Advanced** - [Custom Email Adapter](/docs/dev/email/custom-adapter): Build a custom VitNode email adapter for any third-party provider like Postmark, AWS SES, or Mailgun. - Captcha: Bot protection with Cloudflare Turnstile or reCAPTCHA v3 - [Captcha](/docs/dev/captcha): Protect registration, password reset, and custom API routes against bots with Cloudflare Turnstile or Google reCAPTCHA v3. - **Providers** - [Cloudflare Turnstile](/docs/dev/captcha/cloudflare): Protect VitNode sign-up and password reset with Cloudflare Turnstile - create a widget, copy both keys, and test locally with the dummy keys. - [Google reCAPTCHA v3](/docs/dev/captcha/recaptcha): Protect VitNode sign-up and password reset with Google reCAPTCHA v3 - register a score-based site, add your domains, and wire both keys. - **Advanced** - [Custom forms](/docs/dev/captcha/custom-adapter): Solve a captcha challenge in a form you built yourself - the useCaptcha hook's isReady, getToken and onReset, and where to mount the widget. - Single Sign-On (SSO): OAuth2 sign-in with Google, Discord, Facebook or your own adapter - [Single Sign-On (SSO)](/docs/dev/sso): Enable social authentication with Google, Discord, Facebook, or custom OAuth2 providers in VitNode. - **Providers** - [Google](/docs/dev/sso/google): Add Google sign-in to VitNode - create an OAuth client, set the exact redirect URI and register the Google SSO adapter in your API config. - [Discord](/docs/dev/sso/discord): Add Discord sign-in to VitNode - create an application, register the redirect URL and wire up the Discord SSO adapter in your API config. - [Facebook](/docs/dev/sso/facebook): Add Facebook sign-in to VitNode - create a Meta app with the Facebook Login use case, set the OAuth redirect URI and register the Facebook SSO adapter. - [Custom SSO Adapter](/docs/dev/sso/custom-adapter): Build a custom OAuth2 Single Sign-On adapter for any provider with the SSOApiPlugin interface. - Cron Jobs: Recurring background jobs, the adapters that tick them, and the AdminCP screen that runs them - [Cron Jobs](/docs/dev/cron): Declare recurring background jobs in VitNode plugins and execute them via internal or external cron triggers. - **Adapters** - [Node CRON](/docs/dev/cron/node-cron): Tick VitNode's cron jobs from an in-process scheduler with the @vitnode/node-cron adapter - one package, one line of config. - [Cron over REST](/docs/dev/cron/rest-api): Trigger VitNode's cron endpoint from an external scheduler - the URL, the CRON_SECRET bearer token, a curl call, and what the response means. - [Custom Adapter](/docs/dev/cron/custom-adapter): Wrap any scheduler in VitNode's one-method CronAdapter interface - a plain setInterval, a cron library, or a platform trigger. - [WebSocket](/docs/dev/websocket): Push real-time updates and notifications from Hono routes to the browser over a multiplexed, cookie-authenticated WebSocket connection. - Advanced: Sessions and cookies, request rate limiting, the background task queue, and the optional Redis cache - [Authorization & Sessions](/docs/dev/advanced/auth): How VitNode manages public and admin sessions, HttpOnly cookies, device fingerprinting, and session expiration. - [Rate Limiter](/docs/dev/advanced/rate-limiter): Restrict API request rates per client IP, return 429 responses with Retry-After headers, and share counters across clusters with Redis. - [Queue Tasks](/docs/dev/advanced/queue): Run asynchronous background tasks through VitNode's database-backed queue with retries and AdminCP monitoring. - [Redis](/docs/dev/advanced/redis): Add a shared Redis cache to VitNode for faster session lookups, distributed rate limiting, and multi-instance WebSocket broadcasts. - **Operate** - Debugging: Read what your app is actually doing - [Debugging](/docs/dev/debugging): Find out what a VitNode app is actually doing - the AdminCP Debug Panel, the system log, the Router and Query devtools, and React Scan. - [Logging](/docs/dev/debugging/logging): Write log lines from a Hono route with c.get('log') - three levels, stored in the database and printed to the server console at the same time. - [Swagger](/docs/dev/swagger): Browse every endpoint your VitNode API serves at /api/swagger - an OpenAPI document generated from the Zod schemas your routes already declare. - [Contributing](/docs/dev/contribution): Set up the VitNode monorepo locally, run tests and typechecks, and submit pull requests. - Guides: End-to-end walkthroughs that build a real feature on VitNode, one ordered step at a time. - [Guides](/docs/guides): Follow concise VitNode tutorials that build real plugin-owned features from the first command to a working result. - [Build Your First Plugin](/docs/guides/first-plugin): Create a VitNode plugin step by step, add a TanStack Start route, register it, and open a working page. - **Plugins by VitNode** - [Install the Blog Plugin](/docs/guides/blog): Install @vitnode/blog, enable its API and TanStack Start integration, then publish your first article in AdminCP. - User Interface (UI): Base UI components, the AutoForm field set, a URL-driven data table and the design tokens behind them - every page with a live demo - [UI Components Overview](/docs/ui): Accessible, composable UI primitives, form inputs, and data tables built with Base UI and Tailwind CSS. - Hooks: Small React hooks for common VitNode interface behavior - [useBeforeUnload](/docs/ui/hooks/use-before-unload): A custom hook to handle the beforeunload event in React applications - [useMobile](/docs/ui/hooks/use-mobile): A custom hook to determine if the user is on a mobile device - [Typography](/docs/ui/typography): A collection of text styles and components for consistent typography across your application. - [Colors](/docs/ui/colors): A collection of color utilities and components for consistent theming across your application. - **Components** - [Data Table](/docs/ui/data-table): A sortable, searchable, filterable data table for TanStack Router with cursor pagination and URL state persistence. - [Confirm Action Alert Dialog](/docs/ui/confirm-action-alert-dialog): A dialog component for confirming destructive actions like delete operations, built on top of the Alert Dialog. - **Forms** - [Auto Form](/docs/ui/auto-form): Generates forms based on Zod schemas and react-hook-form with validation and input controls. - [Checkbox](/docs/ui/checkbox): Let people select one or more options with accessible checked states. - [Color](/docs/ui/color): Color picker field built on react-colorful that outputs an HSL string. - [Combobox](/docs/ui/combobox): Searchable dropdown select input for picking single or multiple options with static lists or async API queries. - [Editor](/docs/ui/editor): Rich text editor built on TipTap for editing and rendering HTML content. - [Input](/docs/ui/input): Collect a short text value with labels, validation and accessible feedback. - [Input Group](/docs/ui/input-group): Component used for grouping related input fields together - [Nullable Number](/docs/ui/nullable-number): Numeric field paired with a checkbox that toggles the value to null - for "unlimited", "never", "no limit", and similar. - [Radio Group](/docs/ui/radio-group): Pick exactly one option from a short list of Zod enum values, as plain radio buttons or as clickable blocks, with a description under each label. - [Roles](/docs/ui/roles): Search and pick roles for an Auto Form field - one, or as many as you like. - [Select](/docs/ui/select): Let people choose one accessible option from a defined list. - [Switch](/docs/ui/switch): Toggle a single preference or setting on and off accessibly. - [Textarea](/docs/ui/textarea): A multi-line text input for descriptions and longer answers, as an Auto Form field or on its own. - [User](/docs/ui/user): Pick a person by name, with their avatar, for an Auto Form field. - **UI** - [Accordion](/docs/ui/accordion): A component that allows users to expand and collapse sections of content. - [Alert Dialog](/docs/ui/alert-dialog): Display important messages to users in a modal dialog. - [Alert](/docs/ui/alert): Display an important status message with a clear action or next step. - [Badge](/docs/ui/badge): A small label for a status, a count or a tag, in the same variants as the button - and it takes a Lucide icon as a child. - [Button](/docs/ui/button): The button every VitNode action goes through - six variants, a built-in loading spinner, and a render prop that turns it into a router link. - [Card](/docs/ui/card): The raised surface everything else sits on, with header, title, description, content, footer and action slots. - [Dialog](/docs/ui/dialog): A modal dialog built on Base UI - trigger, title, description, footer and a close that needs no state of your own. - [Drawer](/docs/ui/drawer): A component for displaying content in a sliding panel. - [Dropdown Menu](/docs/ui/dropdown-menu): A dropdown menu component for building interactive menus in your application. - [Hover Card](/docs/ui/hover-card): A component for displaying additional information on hover. - [Popover](/docs/ui/popover): A popover component for displaying additional content on user interaction. - [Progress](/docs/ui/progress): A progress component for indicating the completion of a task. - [Scroll Area](/docs/ui/scroll-area): Container for scrollable content with custom scrollbars. - [Separator](/docs/ui/separator): Separate related interface sections without adding visual noise. - [Sheet](/docs/ui/sheet): A sheet component for displaying additional content in a modal-like overlay. - [Skeleton](/docs/ui/skeleton): Reserve layout space while data or an interface section is loading. - [Sonner](/docs/ui/sonner): A toast notification component for displaying messages to users. - [Toggle Group](/docs/ui/toggle-group): A toggle group component for selecting multiple options. - [Toggle](/docs/ui/toggle): A toggle component for switching between two states. - [Tooltip](/docs/ui/tooltip): A tooltip component for displaying additional information on hover or focus.