BTST

Standalone Components

Use BTST's UI components independently of any plugin — auto-form, markdown editor, kanban, form builder, UI builder, and more.

BTST ships a set of UI components that can be used without setting up any plugin. Each is available as its own import path from @btst/stack, so you only bundle what you use.

Import pathCSS exportWhat you get
@btst/stack/components/auto-formAutoForm, AutoFormSubmit
@btst/stack/components/stepped-auto-formSteppedAutoForm
@btst/stack/components/form-builderFormBuilder and schema helpers
@btst/stack/components/markdown@btst/stack/components/markdown/cssMarkdownContent, MarkdownEditor
@btst/stack/components/multi-selectMultipleSelector
@btst/stack/components/search-selectSearchSelect
@btst/stack/components/emptyEmpty, EmptyHeader, EmptyTitle, …

AutoForm

Generate forms automatically from Zod schemas. Learn more →

import { AutoForm, AutoFormSubmit } from "@btst/stack/components/auto-form"
import type { FieldConfig, Dependency } from "@btst/stack/components/auto-form"
<AutoForm
  formSchema={z.object({
    name: z.string().min(1),
    email: z.string().email(),
  })}
  onSubmit={(values) => console.log(values)}
>
  <AutoFormSubmit>Submit</AutoFormSubmit>
</AutoForm>

Stepped AutoForm

Multi-step wizard variant. Learn more →

import { SteppedAutoForm } from "@btst/stack/components/stepped-auto-form"
import type { SteppedAutoFormProps, StepperComponentProps } from "@btst/stack/components/stepped-auto-form"

FormBuilder

A JSON-schema-driven form editor — lets users visually create form definitions that can be stored and later rendered. Learn more →

import {
  FormBuilder,
  defaultComponents,
  objectFieldDefinition,
  arrayFieldDefinition,
  defineComponent,
  baseMetaSchema,
  baseMetaSchemaWithPlaceholder,
} from "@btst/stack/components/form-builder"
import type {
  FormBuilderComponentDefinition,
  FormBuilderField,
  JSONSchema,
  JSONSchemaProperty,
} from "@btst/stack/components/form-builder"
<FormBuilder
  schema={currentSchema}
  onChange={(schema) => setSchema(schema)}
  components={defaultComponents}
/>

The full Form Builder plugin (@btst/stack/plugins/form-builder) layers data persistence, API routes, and submissions on top of this component. Use the standalone import when you want to manage your own storage.


Markdown

MarkdownContent

Renders Markdown/MDX to HTML with syntax highlighting:

import { MarkdownContent } from "@btst/stack/components/markdown"
import type { MarkdownContentProps } from "@btst/stack/components/markdown"
<MarkdownContent content="# Hello\n\nSome **bold** text." />

Import the stylesheet in your root CSS (or layout):

@import "@btst/stack/components/markdown/css";

MarkdownEditor

A rich Markdown editor powered by Milkdown/Crepe with optional image upload:

import { MarkdownEditor } from "@btst/stack/components/markdown"
import type { MarkdownEditorProps } from "@btst/stack/components/markdown"
<MarkdownEditor
  value={content}
  onChange={(markdown) => setContent(markdown)}
  placeholder="Write something..."
  uploadImage={async (file) => {
    const url = await uploadToStorage(file)
    return url
  }}
/>

MarkdownEditor Props

PropTypeDefaultDescription
valuestring""Current Markdown content
onChange(markdown: string) => voidCalled on every change
classNamestringAdditional CSS classes
placeholderstring"Write something..."Placeholder when empty
uploadImage(file: File) => Promise<string>Enables image upload; must return the public URL

The stylesheet also covers the Markdown editor. Import once from @btst/stack/components/markdown/css.


MultipleSelector

A multi-select combobox with search, async options, and tag-style values:

import { MultipleSelector } from "@btst/stack/components/multi-select"
import type { Option, MultipleSelectorRef } from "@btst/stack/components/multi-select"
const options: Option[] = [
  { value: "react", label: "React" },
  { value: "vue", label: "Vue" },
  { value: "svelte", label: "Svelte" },
]

<MultipleSelector
  options={options}
  value={selected}
  onChange={setSelected}
  placeholder="Select frameworks..."
/>

SearchSelect

A searchable single-value select powered by Radix + cmdk:

import { SearchSelect } from "@btst/stack/components/search-select"
<SearchSelect
  options={[
    { value: "us", label: "United States" },
    { value: "gb", label: "United Kingdom" },
  ]}
  value={country}
  onValueChange={setCountry}
  placeholder="Select a country..."
/>

Empty

Composable empty-state UI components:

import {
  Empty,
  EmptyHeader,
  EmptyTitle,
  EmptyDescription,
  EmptyContent,
  EmptyMedia,
} from "@btst/stack/components/empty"
<Empty>
  <EmptyMedia>
    <InboxIcon className="size-12 text-muted-foreground" />
  </EmptyMedia>
  <EmptyHeader>
    <EmptyTitle>No results</EmptyTitle>
    <EmptyDescription>Try adjusting your search or filters.</EmptyDescription>
  </EmptyHeader>
  <EmptyContent>
    <Button>Clear filters</Button>
  </EmptyContent>
</Empty>