Getting Started

Introduction

What is Vextro?

Vextro is a CMS admin framework that generates a full-featured content management panel from your Convex schema definitions. Instead of building admin interfaces by hand, you define your collections and fields using type-safe builders, and Vextro produces a complete editing experience -- document lists, form editors, file uploads, version history, and more.

If you have used PayloadCMS, the mental model is similar: you define collections with typed fields, and the framework generates the admin UI. The key difference is that Vextro is built for the Convex backend instead of MongoDB, and it renders with Astro SSR and Svelte islands instead of React.

New to Convex?

If you have not used Convex before, start with the Key Concepts page. It covers the essential Convex concepts (queries, mutations, real-time, indexes) you need to understand before using Vextro. Already familiar with PayloadCMS? See Coming from PayloadCMS for a concept mapping guide.

Key Features

Metadata-driven UI generation

Every admin page -- sidebar navigation, collection lists, document editors -- is generated from collection and field metadata stored in Convex. When you add a new collection or change a field definition, the admin UI updates automatically. There are no hardcoded menu items or manually wired form inputs.

Type-safe field builders

Vextro provides the f namespace, a set of field builder functions that define both the Convex validator and the admin UI configuration in a single declaration:

import { f, defineVextroCollection } from "vextro";

export const posts = defineVextroCollection({
  slug: "posts",
  label: "Posts",
  collectionType: "content",
  tableName: "posts",
  fields: {
    title: f.text({ required: true, searchable: true }),
    slug: f.slug({ sourceField: "title", required: true }),
    body: f.richText(),
    category: f.select({ options: ["news", "blog", "tutorial"] }),
    author: f.id("users", { required: true }),
    publishedAt: f.datetime(),
  },
});

Each call to f.text(), f.slug(), or f.select() returns a definition that includes the Convex validator (for schema enforcement) and the admin field configuration (for rendering the correct input component). There is no separate schema file and admin config to keep in sync.

Rich text editing (TipTap)

The f.richText() field renders a full TipTap WYSIWYG editor with formatting toolbar, link insertion, image embedding, and optional block embedding. Content can be stored as TipTap JSON for structured access or as an HTML string.

Code editing (CodeMirror)

The f.code() field provides a CodeMirror editor with syntax highlighting for over 20 languages, line numbers, configurable tab size, and word wrap. Useful for storing configuration snippets, custom CSS, or template code.

Uploads and storage

Collections can be configured as upload-enabled, supporting file uploads with MIME type filtering, file size limits, image dimension tracking, and focal point selection. Vextro ships with built-in storage adapters for Convex file storage and S3-compatible services.

Import and export

Collections support CSV and JSON import/export with field mapping, validation, and error reporting. Templates can be downloaded to guide bulk data entry.

Version history

When versioning is enabled on a collection, Vextro snapshots the full document state before each update. Editors can view previous versions, compare changes with a visual diff, and restore any prior version.

Blocks system

The f.blocks() field allows editors to compose pages from reusable content blocks. Block types are defined with their own field schemas and stored in dedicated Convex tables. Blocks can be reordered via drag-and-drop and embedded inline within rich text fields.

Conditional fields

Any field can be conditionally shown or hidden based on the values of sibling fields. Conditions support equality checks, set membership, boolean logic (AND, OR, NOT), and custom functions:

linkType: f.select({ options: ["internal", "external"], required: true }),
externalUrl: f.url({
  required: true,
  condition: { field: "linkType", equals: "external" },
}),

Layout control

Fields can be organized using layout helpers that do not affect data storage: f.tabs() for tabbed sections, f.row() for side-by-side fields, f.collapsible() for collapsible groups, and f.section() for visual section headers.

Architecture

Vextro is structured as a layered system:

Astro SSR + Svelte islands

The admin panel is an Astro application using server-side rendering for fast page loads. Interactive components -- the rich text editor, code editor, drag-and-drop lists, relationship pickers -- are Svelte islands that hydrate only when needed. This keeps the admin responsive even on complex documents with many fields.

Convex backend

All data lives in Convex. Vextro provides a Convex component that manages admin metadata (collections, fields, relationships), document CRUD operations, version snapshots, and block references. The component installs into your existing Convex project and adds the necessary tables and indexes.

Better Auth integration

Authentication is handled by Better Auth, built into the core vextro package. The vextro/auth subpath provides middleware for protecting admin routes, session-to-JWT exchange, permission guards, and login page rendering. Auth providers are configurable -- you can use email/password, OAuth, or any provider supported by Better Auth.

Storage adapters

File uploads are processed through a pluggable storage adapter system. The default Convex adapter uses Convex file storage. The S3 adapter supports any S3-compatible service (AWS S3, Cloudflare R2, MinIO) with presigned URLs for direct browser uploads.

How it compares to PayloadCMS

AspectPayloadCMSVextro
BackendMongoDB / PostgresConvex
FrontendReact (Next.js)Astro + Svelte
Field definitionsConfig objectsType-safe f builders
Real-timePolling / webhooksConvex subscriptions
AuthBuilt-inBetter Auth integration
HostingSelf-hosted / Payload CloudConvex Cloud + any Astro host
Schema validationJoi / ZodConvex validators (auto-generated)

Vextro inherits Convex's real-time subscription model, so document lists and editors update live without polling. The f field builders generate both the Convex schema validator and the admin UI config from a single source, eliminating the drift between schema and admin that can occur in other CMS frameworks.

Next steps

Previous
Why Vextro →