
Upstash Vector Js
- 4 installs
- 70 repo stars
- Updated March 9, 2026
- upstash/vector-js
Helps with ai & agent building tasks during AI-assisted development.
About
upstash-vector-js is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- upstash-vector-js
- AI & Agent Building
- AI-coding skill
Upstash Vector Js by the numbers
- 4 all-time installs (skills.sh)
- Ranked #13,349 of 16,556 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/upstash/vector-js --skill upstash-vector-jsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 70 |
| Last updated | March 9, 2026 |
| Repository | upstash/vector-js ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Vector Documentation Skill
Quick Start
Vector is a high‑performance vector database for storing, querying, and managing vector embeddings.
Basic workflow:
- Install the Vector TS SDK.
- Connect to a Vector instance.
- Upsert vectors, query them, and manage namespaces.
Example (TypeScript):
import { Index } from "@upstash/vector";
const index = new Index({
url: process.env.UPSTASH_VECTOR_REST_URL!,
token: process.env.UPSTASH_VECTOR_REST_TOKEN!,
});
await index.upsert([{ id: "1", vector: [0.1, 0.2], metadata: { tag: "example" } }]);
const results = await index.query({
vector: [0.1, 0.2],
topK: 5,
});For full usage, refer to the linked skill files below.
Other Skill Files
TS SDK Reference
sdk-methods: Explains SDK commands: delete, fetch, info, query, range, reset, resumable-query, upsert
Features
features/namespaces: Explains namespaces and dataset organization.features/index-structure: Covers hybrid and sparse index structures.features/filtering-and-metadata: Details metadata storage and server-side filtering.
Use these files for deeper guidance on SDK usage, advanced configurations, algorithms, and integrations.
Vector Feature: Filtering and Metadata
Upstash Vector supports attaching metadata and optional data to vectors. Metadata is structured JSON used for filtering; data is unstructured content returned in responses but not filterable.
Filtering uses a SQL‑like syntax and supports nested objects, array indexing, glob patterns, and boolean logic. The system applies both in‑filtering and post‑filtering according to a filtering budget, so highly selective filters may return fewer results than topK.
Setting Metadata and Data
You can upsert vectors with metadata and optional data. Metadata is any JSON structure; data is typically raw text.
import { Index } from "@upstash/vector";
const index = new Index({ url: "...", token: "..." });
await index.upsert([
{
id: "v0",
vector: [0.1, 0.2],
metadata: { city: "Istanbul", population: 15460000 },
data: "Istanbul info",
},
{
id: "v1",
data: "Upstash is a serverless data platform.",
},
]);Querying with Metadata Filters
Include metadata in results and apply filters using SQL‑like expressions.
await index.query({
vector: [0.9, 0.3],
topK: 5,
includeMetadata: true,
filter: "population >= 1000000 AND geography.continent = 'Asia'",
});Supported Operators
- Equality:
=,!= - Numeric comparators:
<,<=,>,>= - Set membership:
IN,NOT IN - Array tests:
CONTAINS,NOT CONTAINS - Field existence:
HAS FIELD,HAS NOT FIELD - Glob string matching:
GLOB,NOT GLOB
Glob wildcards: *, ?, [], [^].
Boolean Logic
Use AND and OR, with parentheses for grouping. AND has higher precedence than OR.
Nested Objects and Arrays
- Access nested fields:
economy.currency,geography.coordinates.latitude. - Index arrays:
industries[0]or from end:industries[#-1].
Example:
economy.major_industries CONTAINS 'Tourism' AND geography.coordinates.latitude >= 35Retrieving Metadata and Data
// query
await index.query({
vector: [0.9, 0.3],
topK: 5,
includeMetadata: true,
includeData: true,
});
// range
await index.range({ cursor: "0", limit: 3, includeMetadata: true });Vector Feature: Index Structure
Overview
Upstash Vector supports three major index structures:
- Dense indexes: semantic matching via dense embeddings.
- Sparse indexes: exact/near-exact token and feature matching.
- Hybrid indexes: combine dense + sparse results, optionally reranked.
---
Key Concepts
Sparse Vectors
- High‑dimensional, mostly‑zero representations.
- Represented as two equal‑length arrays:
indices: int32 positions of non‑zero elementsvalues: float32 values- Upstash limit: max 1,000 non‑zero entries per sparse vector.
- Useful for exact token/word matching (BM25, SPLADE, etc.).
Hybrid Vectors
- Combine dense semantic vectors with sparse exact‑match vectors.
- Hybrid queries run both dense + sparse search and fuse results.
- Require both components (
vectorandsparseVector).
Fusion Algorithms
- RRF (default): ranking‑based, simple, robust, ignores score magnitudes.
- DBSF: normalizes scores using distribution statistics; more sensitive to score ranges.
---
Common Pitfalls
- Hybrid upserts require both dense and sparse vectors; omitting either fails.
- Indexes with embedding models (dense, sparse or both) let you upsert/query using text; indexes without embedding models do not.
- In Hybrin indexes, dense‑only or sparse‑only querying is allowed, but fusion happens only when both are provided.
---
Usage with Embedding Models
await index.upsert([
{
id: "t1",
data: "Upstash Vector provides sparse models.",
},
]);
const results = await index.query({
data: "Upstash Vector",
topK: 5,
});
import { WeightingStrategy } from "@upstash/vector";
await index.query({
data: "Upstash Vector",
weightingStrategy: WeightingStrategy.IDF,
});Sparse Index Usage
Upserting Sparse Vectors
await index.upsert([
{
id: "x1",
sparseVector: {
indices: [1, 2, 3],
values: [0.1, 0.2, 0.3],
},
},
]);
const results = await index.query({
sparseVector: {
indices: [3, 5],
values: [0.3, 0.5],
},
topK: 5,
includeMetadata: true,
});- Scores use inner product, matching only overlapping indices.
- Results may be fewer than
top_kif no overlapping dims exist.
Hybrid Index Usage
Upserting Dense + Sparse
await index.upsert([
{
id: "h1",
vector: [0.1, 0.5],
sparseVector: {
indices: [1, 2],
values: [0.1, 0.2],
},
},
]);
const results = await index.query({
vector: [0.5, 0.4],
sparseVector: {
indices: [3, 5],
values: [0.3, 0.5],
},
topK: 5,
});
import { FusionAlgorithm } from "@upstash/vector";
await index.query({
vector: [0.5, 0.4],
sparseVector: {
indices: [2, 3],
values: [0.1, 0.2],
},
fusionAlgorithm: FusionAlgorithm.RRF, // or FusionAlgorithm.DBSF
});---
Custom Reranking
Sometimes RRF/DBSF is insufficient (e.g., using bge‑reranker-v2-m3). Query dense and sparse portions separately and rerank in your own model.
Custom Rerank (vector input)
// Dense-only
const dense = await index.query({
vector: [0.5, 0.4],
topK: 5,
});
// Sparse-only
const sparse = await index.query({
sparseVector: {
indices: [3, 5],
values: [0.3, 0.5],
},
topK: 5,
});
// Custom rerank dense + sparse...Custom Rerank (text input with hosted models)
import { QueryMode } from "@upstash/vector";
const dense = await index.query({
data: "Upstash Vector",
queryMode: QueryMode.DENSE,
});
const sparse = await index.query({
data: "Upstash Vector",
queryMode: QueryMode.SPARSE,
});
// Rerank...---
Agent Implementation Notes
- Always check whether the index supports hosted embeddings before using
data=fields. - Use
await index.info()to check: ifdenseIndex?.embeddingModelorsparseIndex?.embeddingModelexists, the index supports text-based embeddings via thedatafield. - Example:
const info = await index.info();
const hasDenseEmbedding = !!info.denseIndex?.embeddingModel;
const hasSparseEmbedding = !!info.sparseIndex?.embeddingModel;- For hybrid indexes:
- Always provide _both_
vectorandsparseVectorunless intentionally querying only one modality. - For reranking workflows:
- Use dense-only + sparse-only queries, never hybrid queries (as fusion is already applied).
- When building sparse vectors manually:
- Ensure indices are sorted, unique, and below the model dimension.
Vector Feature: Namespaces
Namespaces partition a single Upstash Vector index into fully isolated subsets. Each request executes only within its specified namespace.
Key Concepts
- Every index has a default namespace named "" (empty string).
- Additional namespaces are created automatically on first upsert.
- If no namespace is provided, all operations use the default.
Using Namespaces
Upsert and query operations scoped to a namespace automatically create it if missing.
import { Index } from "@upstash/vector";
const index = new Index({ url: "URL", token: "TOKEN" });
const ns = index.namespace("ns");
await ns.upsert({ id: "id-0", vector: [0.1, 0.2] });
await ns.query({ vector: [0.1, 0.2], topK: 5 });Operatoins
await index.deleteNamespace("ns");
await index.listNamespaces();Common Pitfalls
- Forgetting to specify
namespacecauses writes to go into the default namespace.
Vector TS SDK
Upsert
Add or update vectors. Also accepts raw text (data) to embed automatically.
Pitfalls
- Vector dimension must match index dimension.
- Passing both
vectoranddatais invalid. - Metadata is optional but recommended for filtering.
Example (single + batch, mix of vector/data)
// Single vector
await index.upsert({ id: "1", vector: [0.1, 0.2], metadata: { type: "doc" } });
// Multiple vectors
await index.upsert(
[
{ id: "2", vector: [0.2, 0.3] },
{ id: "3", vector: [0.3, 0.4], metadata: { tag: "a" } },
],
{ namespace: "ns" }
);
// Using data (auto‑embedding. Only works if the vector index has an embedding model)
await index.upsert({ id: "4", data: "A fantasy movie" });---
Fetch
Retrieve vectors by exact ID or prefix.
Example
// Exact
const out = await index.fetch(["1", "2"], { includeMetadata: true });
// → [{ id: "1", metadata: {...} }, null]
// Prefix
await index.fetch({ prefix: "user-" });---
Delete
Remove vectors by IDs, prefix, or metadata filter.
Pitfalls
- Only one of
ids,prefix, orfiltercan be used. - Using
filtertriggers an O(N) scan.
Example
await index.delete(["1", "2"]);
await index.delete({ prefix: "user-" });
await index.delete({ filter: "status = 'expired'" });---
Query
Find the top‑K most similar vectors. Supports dense, sparse, hybrid, and embedded-on-demand queries.
Pitfalls
- Query vector dimension must match index.
- Scores are normalized 0–1 no matter the similarity metric.
Example
// Dense vector
const results = await index.query({
vector: [0.1, 0.2],
topK: 3,
includeMetadata: true,
filter: "genre = 'fantasy'",
});
// Data (auto‑embedding)
await index.query({ data: "epic fantasy adventure", topK: 2 });---
Resumable Query
Long-running, chunked queries with server-side state.
Pitfalls
- Remember to call
stop()to free resources. fetchNext(k)retrieves N more results.
Example
const { result, fetchNext, stop } = await index.resumableQuery({
vector: [0.1, 0.2],
topK: 50,
maxIdle: 3600,
});
const next = await fetchNext(10);
await stop();---
Range
Paginated, stateless scanning of vectors; recommended for large prefix fetches.
Pitfalls
- Always pass
cursor; set to0initially.
Example
let cursor = 0;
while (cursor !== null) {
const page = await index.range({ cursor, limit: 100, includeMetadata: true });
console.log(page.vectors);
cursor = page.nextCursor;
}---
Info
Retrieve index statistics.
Example
const info = await index.info();
/* Returns:
{
vectorCount: number;
pendingVectorCount: number;
indexSize: number;
dimension: number;
similarityFunction: "COSINE" | "EUCLIDEAN" | "DOT_PRODUCT";
denseIndex?: {
dimension: number;
similarityFunction: "COSINE" | "EUCLIDEAN" | "DOT_PRODUCT";
embeddingModel?: string;
};
sparseIndex?: {
embeddingModel?: string;
};
namespaces: Record<string, {
vectorCount: number;
pendingVectorCount: number;
}>;
}
*/---
Reset
Clear a namespace or the entire index.
Pitfalls
{ all: true }must be explicit.
Example
await index.reset(); // default namespace
await index.reset({ namespace: "my-namespace" });
await index.reset({ all: true });---
Advanced
Request Timeout
const index = new Index({
url,
token,
signal: () => AbortSignal.timeout(1000),
});Telemetry
Disable with env variable:
UPSTASH_DISABLE_TELEMETRY=1