Integrating weaviate/elysia for Next-Gen Vector Search Applications


Integrating weaviate/elysia for Next-Gen Vector Search Applications

weaviate/elysia

2025-09-08

Weaviate is an open-source, vector-native database. What does that mean for you as a software engineer? It means Weaviate is designed from the ground up to store and search data based on its semantic meaning rather than just keywords. It uses vector embeddings, which are numerical representations of data (text, images, etc.), to understand relationships and find similar items. This is incredibly powerful for applications involving search, recommendations, anomaly detection, and more.

Elysia is a web framework for Bun, a fast all-in-one JavaScript runtime. Elysia focuses on performance, type safety, and developer experience. It allows you to build fast and robust web applications with ease, leveraging Bun's speed and its own expressive API.

The combination of Weaviate and Elysia allows you to build highly performant, AI-powered applications. You can use Elysia to create your backend API, handle requests, and then interact with Weaviate to perform intelligent data retrieval and management.

Use Case
Imagine you're building an e-commerce platform. Instead of just searching for exact product names, you want users to be able to search for "cozy sweaters for winter" and get relevant results, even if the product descriptions don't contain those exact words.

How it helps

Weaviate
Stores product data (descriptions, images) as vector embeddings. When a user searches, their query is also embedded, and Weaviate finds the most semantically similar products.

Elysia
Serves as the API endpoint. It receives the user's search query, sends it to Weaviate, and returns the search results to the frontend.

Use Case
Recommending articles, products, or content to users based on their past interactions or the similarity of items they've viewed.

How it helps

Weaviate
Can store user interaction data and item data. By finding vectors that are close to a user's "profile" or a viewed item, you can generate personalized recommendations.

Elysia
Manages user sessions, tracks interactions, and fetches recommendations from Weaviate to present to the user.

Use Case
Identifying unusual patterns in logs, detecting fraudulent transactions, or grouping similar customer feedback.

How it helps

Weaviate
Can store large datasets and use vector similarity to find outliers or clusters of similar data points.

Elysia
Acts as the data ingestion point, sending data to Weaviate for processing and analysis, and then serving the detected anomalies or cluster insights.

Use Case
Creating a fast and responsive API that handles complex data operations without slowing down.

How it helps

Elysia
Built on Bun, it offers incredible speed for request handling, routing, and middleware. Its type-safe approach reduces runtime errors.

Weaviate
Its specialized architecture for vector search ensures fast retrieval of semantically related data, which is often much quicker than traditional keyword-based searches on large datasets.

Let's outline a basic integration. We'll use Elysia to create a simple API that adds data to Weaviate and then searches it.

Install Bun

curl -fsSL https://bun.sh/install | bash

Install Weaviate
The easiest way is using Docker.

Create a docker-compose.yml file

version: '3.4"
services:
  weaviate:
    image: semitechnologies/weaviate:latest
    ports:
      - "8080:8080"
    volumes:
      - weaviate_data:/var/lib/weaviate
    environment:
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      DEFAULT_VECTORIZER_MODULE: 'text2vec-openai' # Or another module
      ENABLE_MODULES: 'text2vec-openai'
      OPENAI_APIKEY: 'YOUR_OPENAI_API_KEY' # If using OpenAI vectorizer
volumes:
  weaviate_data:

Run it

docker-compose up -d

Note
For this example, we're using the text2vec-openai module. You'll need an OpenAI API key. You can explore other vectorizer modules supported by Weaviate.

Install Weaviate Client for JavaScript/TypeScript

bun add weaviate-ts-client

Create a new Elysia project

bun create elysia my-weaviate-app
cd my-weaviate-app
bun install

Now, let's create an index.ts file (or your main Elysia file) and add the following code

import { Elysia, t } from "elysia";
import weaviate, { type WeaviateClient } from "weaviate-ts-client";

// --- Weaviate Client Initialization ---
const client: WeaviateClient = weaviate.defaultClient({
  scheme: "http",
  host: "localhost:8080", // Your Weaviate instance host
  // apiKey: "YOUR_WEAVIATE_API_KEY", // Uncomment if you have authentication enabled
  // headers: [
  //   "X-OpenAI-Api-Key: YOUR_OPENAI_API_KEY" // If using OpenAI module and need API key here
  // ]
});

// Define your Weaviate schema (if not already created)
// It's often better to manage schema separately or with migrations.
// For simplicity, we'll define a basic class here.
async function ensureSchema() {
  const schemaConfig = {
    classes: [
      {
        class: "Document",
        description: "A document or piece of text",
        vectorizer: "text2vec-openai", // Matches the docker-compose.yml
        properties: [
          {
            name: "content",
            dataType: ["text"],
            description: "The main content of the document",
          },
          {
            name: "title",
            dataType: ["text"],
            description: "The title of the document",
          },
        ],
      },
    ],
  };

  try {
    const res = await client.schema.getter().do();
    if (!res.classes.some(c => c.class === "Document")) {
      await client.schema.creator().withClass(schemaConfig.classes[0]).do();
      console.log("Schema created successfully!");
    } else {
      console.log("Schema already exists.");
    }
  } catch (error) {
    console.error("Error ensuring schema:", error);
  }
}

ensureSchema(); // Call this once on startup

// --- Elysia App ---
const app = new Elysia()
  .decorate("weaviateClient", client) // Make Weaviate client available in handlers
  .on("error", ({ error }) => {
    console.error(error);
  })
  .group("/documents", (app) =>
    app
      .post(
        "/",
        async ({ weaviateClient, body }) => {
          const { content, title } = body as { content: string; title: string };

          if (!content || !title) {
            return new Response("Content and title are required", { status: 400 });
          }

          try {
            await weaviateClient.data
              .creator()
              .withClassName("Document")
              .withProperties({
                content: content,
                title: title,
              })
              .do();

            return { message: "Document added successfully!" };
          } catch (error) {
            console.error("Error adding document:", error);
            return new Response("Failed to add document", { status: 500 });
          }
        },
        {
          body: t.Object({
            content: t.String(),
            title: t.String(),
          }),
        }
      )
      .get(
        "/search",
        async ({ weaviateClient, query }) => {
          const searchTerm = query.q as string | undefined;

          if (!searchTerm) {
            return new Response("Search term 'q' is required", { status: 400 });
          }

          try {
            const result = await weaviateClient.query
              .get("Document", ["title", "content"])
              .withFields("title content")
              .withNearText({ concepts: [searchTerm] }) // Use semantic search
              .do();

            return result.data.Get.Document;
          } catch (error) {
            console.error("Error searching documents:", error);
            return new Response("Failed to search documents", { status: 500 });
          }
        },
        {
          query: t.Object({
            q: t.String(),
          }),
        }
      )
  )
  .listen(3000, () => {
    console.log("Elysia app is running on port 3000!");
  });

export type App = typeof app; // Export for potential testing

Start your Elysia app

bun run index.ts

(Make sure your Weaviate Docker container is also running!)

Add a document (using curl or a tool like Postman)

curl -X POST http://localhost:3000/documents/ \
  -H "Content-Type: application/json" \
  -d '{
    "title": "The Importance of AI in Software Development",
    "content": "Artificial intelligence is transforming how we build software, enabling faster development cycles and more intelligent applications. Machine learning models are becoming integral to many systems."
  }'

Add another document

curl -X POST http://localhost:3000/documents/ \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Advanced Machine Learning Techniques",
    "content": "Exploring deep learning and neural networks for complex pattern recognition and predictive modeling. Understanding algorithms like CNNs and RNNs is crucial."
  }'

Search for documents

curl "http://localhost:3000/documents/search?q=machine learning"

You should get results that include the documents related to "machine learning" and "artificial intelligence" because Weaviate understands the semantic similarity.

Semantic Understanding
Weaviate moves beyond keyword matching, allowing for more intelligent and context-aware data retrieval.

Performance
Elysia, powered by Bun, provides a lightning-fast backend framework, and Weaviate's specialized architecture ensures quick vector searches.

Developer Experience
Elysia's focus on type safety and clear APIs simplifies building complex backends, while Weaviate's client libraries make integration straightforward.

Scalability
Both Weaviate and Elysia are designed with scalability in mind, allowing your applications to grow.


weaviate/elysia