@weaviate/add-collection
v0.1.0
Published
React component for visually building Weaviate collection schemas
Readme
Weaviate Add Collection (minimal)
A minimal React app (Vite) with a Collection component to compose a Weaviate collection JSON.
This project is used in Weaviate Studio
✨ New: Programmatic schema access via onChange and onSubmit callbacks — no more DOM scraping needed!
✨ New: Version-aware UI via the weaviateVersion prop — fields, options, and sections are automatically shown or hidden based on what your Weaviate instance supports. Unavailable options are disabled with a tooltip indicating the minimum required version.
Quick Start (macOS, zsh)
# install deps
npm install
# start dev server
npm run devUsing as a Package
npm install @weaviate/add-collectionreact and react-dom (18 or 19) are peer dependencies. The package ships prebuilt ESM and CommonJS bundles in lib/; styles are imported separately:
import '@weaviate/add-collection/styles.css';You can import the Collection component into your own React application:
// Default import
import Collection from '@weaviate/add-collection';
// Named import
import { Collection } from '@weaviate/add-collection';Example Usage
import React from 'react';
import Collection from '@weaviate/add-collection';
function App() {
return (
<div>
<h1>My Weaviate Collection Builder</h1>
<Collection
initialJson={{ name: 'MyCollection', description: 'A sample collection' }}
availableModules={serverModules}
nodesNumber={3}
weaviateVersion="1.36.0"
/>
</div>
);
}Props
The Collection component accepts the following props:
initialJson(optional): JSON object to prepopulate the form withnameanddescriptionavailableModules(optional): Object containing available vectorizer modules from the server. If not provided, all default modules are available.nodesNumber(optional): Number representing the number of nodes (used as max for replication factor)weaviateVersion(optional): Semver string (e.g."1.36.0") representing the target Weaviate instance version. Controls which fields, options, and sections are shown based on version availability. Defaults to the latest supported version when omitted. See Version-Gated UI below.onChange(optional): Callback function(schema: object) => voidcalled whenever the schema changes. Provides programmatic access to the current JSON schema without DOM scraping.onSubmit(optional): Callback function(schema: object) => voidcalled when the "Create Collection" button is clicked. If provided, a submit button will be displayed below the JSON preview.
Programmatic Schema Access
Instead of scraping the DOM to get the generated schema, you can use the callback props:
import React from 'react';
import Collection from '@weaviate/add-collection';
function App() {
const handleSchemaChange = (schema) => {
console.log('Schema updated:', schema);
// Do something with the schema as it changes
};
const handleSubmit = async (schema) => {
console.log('Creating collection with schema:', schema);
// Send the schema to your Weaviate instance
try {
const response = await fetch('http://localhost:8080/v1/schema', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(schema)
});
if (response.ok) {
alert('Collection created successfully!');
}
} catch (error) {
console.error('Failed to create collection:', error);
}
};
return (
<div>
<h1>My Weaviate Collection Builder</h1>
<Collection
initialJson={{ name: 'MyCollection', description: 'A sample collection' }}
availableModules={serverModules}
nodesNumber={3}
weaviateVersion="1.36.0"
onChange={handleSchemaChange}
onSubmit={handleSubmit}
/>
</div>
);
}Version-Gated UI
The weaviateVersion prop enables version-aware rendering: fields, dropdown options, and entire sections are shown, disabled, or hidden based on whether the target Weaviate instance supports them.
Pass the version of the Weaviate instance your user is connecting to:
<Collection weaviateVersion="1.36.0" ... />When weaviateVersion is omitted the component behaves as if the latest supported version is in use, showing all features.
How it works
| Element | Behaviour when unavailable |
|---------|---------------------------|
| Individual field / checkbox | Hidden entirely |
| Dropdown option | Kept in list but disabled, label appended with — Requires Weaviate ≥ X.Y.Z |
| Collapsible section | Toggle button shown but disabled, same tooltip |
Version feature registry
All version gates are centralised in src/constants/versionFeatures.js. Each entry maps a feature identifier to the minimum Weaviate version that introduced it:
// src/constants/versionFeatures.js
export const VERSION_FEATURES = {
dynamicIndexType: '1.25.0',
textAnalyzer: '1.37.2',
// ...
}To add a new gate, add an entry there and use one of the gating helpers from src/context/VersionContext.jsx:
<VersionGated featureId="…">— wraps any JSX; greys it out behind a click-capture overlay and shows adata-version-tooltipwhen unavailable. The content stays in the DOM.<VersionGatedSection featureId="…" title="…">— wraps a collapsible section; disables the toggle when unavailable and does not render the panel.useVersionFilteredOptions(opts)— keeps options but marks themdisabledand appends "— Requires Weaviate ≥ X.Y.Z" to the label.
Establish the minimum version from Weaviate core, not from a client release.
A feature usually appears in the TypeScript client some releases after the
server gained it, and occasionally before the server ships it at all. Both
directions cause real bugs: gating too late greys out a working control, and
gating too early offers a control the server will reject. Find the commit that
introduced the field in weaviate/weaviate, then check which tag first
contains it:
gh api "repos/weaviate/weaviate/compare/<sha>...v1.34.0" --jq '.status'
# "ahead" -> that tag contains the commit
# "behind" -> it does notSee CLAUDE.md for step-by-step instructions on adding new version-gated fields, options, and sections.
Testing
This project includes integration tests that work with a local Weaviate instance.
# Run tests (requires Weaviate running on localhost:8080)
npm test
# Run tests once
npm run test:run
# Run tests with UI
npm run test:uiSee TESTING.md for detailed testing documentation.
How it Works
- Open the app at http://localhost:5173 (default Vite port).
- Fill the name and description fields. The generated JSON will update live below the form.
- You can also import a JSON file with
nameanddescriptionkeys to prepopulate the form. - Use the "Copy" button to copy the generated JSON, or "Download" to save it as
{CollectionName}_weaviate_schema.json.
UI Rules
Property
Conditional Field Display
The following fields are shown conditionally based on the selected data type:
Tokenization
- Visible only for:
textdata type - Options: word, whitespace, lowercase, field, gse, gse_ch, trigram, kagome_ja, kagome_kr
- Default: word
- Purpose: Defines how text is tokenized for search indexing
- Note:
gse,gse_ch,kagome_jaandkagome_kreach need their ownENABLE_TOKENIZER_*environment variable set on the server, otherwise Weaviate rejects the property at creation time
Text Analyzer
- Visible only for:
textdata type - Requires: Weaviate 1.37.2+
- Purpose: Per-property accent folding and stopword selection
- Fields:
- ASCII Fold — folds accents to base characters, so "école" matches "ecole". Immutable after the property is created.
- ASCII Fold Ignore — characters to leave unfolded. Editable later, but only affects data indexed after the change.
- Stopword Preset — overrides the collection-level stopwords for this
property. Offers the built-in
enandnoneplus any preset defined under Inverted Index Configuration. Only applies towordtokenization, so the field is hidden for every other method.
- Example Output:
{ "name": "title", "dataType": ["text"], "tokenization": "word", "textAnalyzer": { "asciiFold": true, "asciiFoldIgnore": ["é"], "stopwordPreset": "fr" } }
Vectorization Settings (per-property)
- Visible only for:
textdata type - Type: Checkboxes
- Purpose: Control how individual text properties are vectorized
- Options:
- Vectorize Property Name - Include the property name itself when creating embeddings (default: false)
- Note: These settings are applied to all active vectorizers in the vectorConfig and generate a
moduleConfigobject for each property - Example Output:
{ "name": "description", "dataType": ["text"], "moduleConfig": { "text2vec-openai": { "vectorizePropertyName": true } } }
indexSearchable
- Visible only for:
textdata type - Type: Checkbox
- Default: true
- Purpose: Enables inverted index for text search capabilities
indexRangeFilters
- Visible only for:
int,number,datedata types - Type: Checkbox
- Default: false
- Purpose: Enables range filtering for numeric and date values
indexFilterable
- Visible for: All data types
- Type: Checkbox
- Default: true
- Purpose: Enables general filtering on this property
Data Types
Available data types:
text- Text strings (shows tokenization and indexSearchable options)int- Integer numbers (shows indexRangeFilters option)number- Floating-point numbers (shows indexRangeFilters option)date- Date values (shows indexRangeFilters option)boolean- True/false valuesgeoCoordinates- Geographic coordinatesphoneNumber- Phone number valuesuuid- UUID valuesblob- Binary data
Array Support
Any data type can be configured as an array by checking the "array" checkbox. This appends [] to the data type in the generated JSON (e.g., text[], int[]).
JSON Field Mapping
The following UI fields are mapped differently in the generated JSON:
- Collection UI field
name→ JSON fieldclass - Property UI field
name→ JSON fieldname(unchanged)
Vectorizer Configuration
Overview
The Vectorizer Configuration section allows you to add multiple vector configurations to your collection. Each configuration generates a vectorConfig entry in the JSON output.
Vector Config Fields
Each vector configuration has the following fields:
Name
- Type: Text input
- Required: Yes (auto-generated if empty)
- Default:
vector_config_1,vector_config_2, etc. - Purpose: Unique identifier for this vector configuration
- Examples:
default,semantic,contextual
Vectorize Class Name
- Type: Checkbox
- Default: false
- Purpose: Whether to include the collection/class name in vectorization
- Note: Common to all vectorizer modules
Properties to Vectorize
- Type: Multi-select checkboxes
- Constraint: Only text properties are available for selection
- Purpose: Select which text fields should be included when creating embeddings
- Features:
- Select All / Deselect All buttons for quick management
- Only properties with
dataType: textare shown - Shows count of selected properties
- If no text properties exist, displays a helpful message
- Note: Non-text properties (int, number, boolean, date, etc.) cannot be vectorized and won't appear in the list
Tabbed Interface
The vector configuration is organized into three tabs for better organization:
Tab 1: Vectorizer Module
Configure which embedding model to use and its specific settings.
- Vectorizer Module (Dropdown)
- Select from 40+ available modules
- Categories: text2vec-, multi2vec-, ref2vec-*, etc.
- Module Configuration (Dynamic)
- Automatically shows relevant fields based on selected module
- Examples: model, dimensions, projectId, baseURL, etc.
- Required fields marked with *
Note: Backup, generative, and reranker modules are filtered out.
Tab 2: Index Configuration
Configure the vector index type and optimization parameters.
Index Types:
- HNSW - Fast approximate search (recommended)
- Flat - Exact search for small datasets
- Dynamic - Auto-switches based on collection size
HNSW Parameters:
- Distance Metric (cosine, dot, l2-squared, manhattan, hamming)
- ef Construction (build quality)
- ef (search quality)
- Max Connections (graph density)
Flat Parameters:
- Distance Metric only
Dynamic Parameters:
- Distance Metric
- Threshold (when to switch from flat to HNSW)
Tab 3: Compression/Quantization
Reduce memory usage by compressing vectors.
Note: This tab is hidden when using Dynamic index type, as quantization is configured separately for each sub-index (HNSW and Flat).
Quantization Types:
- None - Full precision (default)
- PQ - Product Quantization (8x-32x compression)
- BQ - Binary Quantization (32x compression)
- SQ - Scalar Quantization (4x compression)
PQ Parameters:
- Segments, Centroids, Training Limit, Distribution
BQ/SQ Parameters:
- Rescore Limit, Training Limit
Important: For flat indexes, only binary quantization is available. This can speed up search performance significantly. See Weaviate Compression Considerations for more details.
Dynamic Index Quantization
When using the Dynamic index type, quantization is configured separately for each sub-index:
- HNSW Sub-index: Supports all quantization types (PQ, BQ, SQ, None)
- Flat Sub-index: Only supports Binary Quantization (BQ) or None
This allows for optimal compression strategies based on the index type being used at different collection sizes.
Important Note: For flat indexes, only binary quantization is available. This can speed up search performance significantly. See Weaviate Compression Considerations for more details.
See TABS_DOCUMENTATION.md for detailed information about each tab.
Dynamic Module Configuration
When you select a vectorizer module, the application renders a configuration form built from a table of field definitions transcribed from the weaviate-client TypeScript types.
How It Works
Field Definitions:
src/utils/moduleConfigExtractor.jsholds a table of the configuration fields for each module, transcribed by hand from theweaviate-clienttype definitions. Despite the file's name nothing is extracted at build or runtime — keeping it current is a manual step on each client bump.Dynamic Form Generation: Based on the selected module, a configuration form is automatically generated with the appropriate fields.
Field Types: The form intelligently renders different input types:
- String fields: Text inputs
- Number fields: Numeric inputs
- Boolean fields: Checkboxes
- Array fields: Comma-separated text inputs
- Object fields: JSON textarea editors
Required Fields: Fields marked as required in the type definitions are indicated with a red asterisk (*).
Example Module Configurations
text2vec-openai:
model(string) - The model to use (e.g., text-embedding-ada-002)modelVersion(string) - The model versiontype(string) - The type of embeddings (text, code)baseURL(string) - The base URL for OpenAI APIdimensions(number) - The dimensionality of the vectorvectorizeClassName(boolean) - Whether to vectorize the class name
text2vec-google:
projectId(string) * - The project ID of the model in GCPlocation(string) - The location where the model runsmodel(string) - The model to usedimensions(number) - The dimensionality of the vectorvectorizeClassName(boolean) - Whether to vectorize the class name
multi2vec-clip:
imageFields(string[]) - The image fields used when vectorizinginferenceUrl(string) - The URL where inference requests are senttextFields(string[]) - The text fields used when vectorizingvectorizeCollectionName(boolean) - Whether the collection name is vectorizedweights(object) - The weights of the fields used for vectorization
Usage
- Click "Add Vector Config" to create a new configuration
- Enter a unique name for the configuration
- Select a vectorizer module from the dropdown
- Configure module settings: Once a module is selected, a dynamic configuration form will appear with module-specific options
- Fill in the module configuration fields as needed (required fields are marked with *)
- Choose an index type (default is HNSW)
- Click the documentation link (if available) to learn more about the selected module
- Repeat to add multiple vector configurations
Generated JSON Structure
The vector configurations are output in the vectorConfig object with module-specific settings:
{
"class": "MyCollection",
"description": "This is a demo collection",
"properties": [
{
"name": "property1",
"dataType": [
"text"
],
"indexFilterable": true,
"indexSearchable": true,
"tokenization": "word",
"indexRangeFilters": false
},
{
"name": "original_id",
"dataType": [
"text"
],
"indexFilterable": true,
"indexSearchable": true,
"tokenization": "field",
"indexRangeFilters": false
}
],
"vectorConfig": {
"default": {
"vectorizer": {
"text2vec-openai": {
"properties": [
"property1"
],
"model": "text-embedding-3-small"
}
},
"vectorIndexType": "dynamic",
"vectorIndexConfig": {
"hnsw": {
"rq": {
"enabled": true
}
},
"flat": {
"rq": {
"enabled": true
}
}
}
}
},
"moduleConfig": {
"generative-cohere": {},
"reranker-cohere": {}
},
"invertedIndexConfig": {
"indexNullState": true,
"indexTimestamps": true,
"stopwords": {
"additions": [
"something"
]
}
},
"multiTenancyConfig": {
"enabled": true,
"autoTenantCreation": true,
"autoTenantActivation": true
},
"objectTtlConfig": {
"enabled": true,
"deleteOn": "creationTime",
"timeToLive": 400,
"filterExpiredObjects": true
},
"replicationConfig": {
"factor": 3,
"asyncEnabled": true,
"deletionStrategy": "DeleteOnConflict"
},
"shardingConfig": {
"desiredCount": 2,
"virtualPerPhysical": 128,
"desiredVirtualCount": 256
}
}Sharding Configuration
Exposes the three create-time shardingConfig fields: desiredCount,
virtualPerPhysical and desiredVirtualCount.
A schema read back from a running Weaviate also carries actualCount,
actualVirtualCount, key, strategy and function. Those are accepted on
import so a round-tripped schema is not silently altered, but they are never
emitted — they are outputs, not settings.
Weaviate treats sharding and replication as mutually exclusive. This component
emits each from its own effect and auto-sets the replication factor from
nodesNumber, so both can end up in one schema; the section shows a warning
rather than blocking, and the server has the final say.
Architecture
Module Configuration System
The module configuration tables mirror the type definitions in the
weaviate-client library so the UI stays in sync with the API.
These tables are maintained by hand. Nothing reads the
.d.tsfiles at build or runtime. When bumpingweaviate-client, diff theVectorizer,GenerativeSearchandRerankerunions insrc/collections/config/types/againstVECTORIZER_CONFIG_FIELDSandallAvailableModules.moduleConfigExtractor.test.jsasserts that those two repo files agree with each other, but it cannot know about a module neither of them has heard of.
Components
moduleConfigExtractor.js (
src/utils/)- Extracts configuration field definitions for each vectorizer module
- Based on TypeScript type definitions from
weaviate-client - Provides validation and helper functions
- Contains metadata about each field (name, type, description, required)
ModuleConfigForm.jsx (
src/components/)- Dynamically renders configuration forms based on module selection
- Handles different field types (string, number, boolean, array, object)
- Provides appropriate input controls for each type
- Displays field descriptions and marks required fields
VectorConfigItem.jsx (
src/components/)- Manages individual vector configuration items
- Integrates the ModuleConfigForm component
- Handles state updates for module configuration
Collection.jsx (
src/components/)- Orchestrates the entire collection configuration
- Merges module configurations into the final JSON output
- Maintains state for all vector configurations
Data Flow
User selects module
↓
VectorConfigItem detects change
↓
ModuleConfigForm queries moduleConfigExtractor
↓
Form fields are rendered based on module type
↓
User fills in configuration
↓
Config stored in vectorConfig state
↓
Collection.jsx merges into final JSONType Mapping
The system maps TypeScript types to form inputs:
| TypeScript Type | Form Input | Example |
|----------------|------------|---------|
| string | Text input | model: "text-embedding-ada-002" |
| number | Number input | dimensions: 1536 |
| boolean | Checkbox | vectorizeClassName: false |
| string[] | Comma-separated text | imageFields: ["image1", "image2"] |
| object | JSON textarea | weights: {"imageFields": [0.7]} |
Benefits
- Type Safety: Configurations match the actual API requirements
- Self-Documenting: Field descriptions are embedded in the UI
- Validation: Required fields are enforced
- Consistency: A parity test keeps the field tables and the module dropdown in agreement, so a module can never have configuration options it cannot be selected to use
Examples
See examples/moduleConfigExamples.js for complete working examples of different vectorizer configurations.
