๐ A complete search engine and RAG pipeline in your browser, server or edge network with support for full-text, vector, and hybrid search in less than 2kb.
<p align="center">
<img src="https://raw.githubusercontent.com/oramasearch/orama/refs/heads/main/misc/readme/orama-readme-hero-light.png#gh-light-mode-only" />
</p>
[](https://github.com/oramasearch/orama/actions/workflows/turbo.yml)
If you need more info, help, or want to provide general feedback on Orama, join the [Orama Slack channel](https://orama.to/slack)
# Highlighted features
- [Full-Text search](https://docs.orama.com/docs/orama-js/search)
- [Vector Search](https://docs.orama.com/docs/orama-js/search/vector-search)
- [Hybrid Search](https://docs.orama.com/docs/orama-js/search/hybrid-search)
- [GenAI Chat Sessions](https://docs.orama.com/docs/orama-js/answer-engine)
- [Search Filters](https://docs.orama.com/docs/orama-js/search/filters)
- [Geosearch](https://docs.orama.com/docs/orama-js/search/geosearch)
- [Pinning Rules (Merchandising)](https://docs.orama.com/docs/orama-js/results-pinning)
- [Facets](https://docs.orama.com/docs/orama-js/search/facets)
- [Fields Boosting](https://docs.orama.com/docs/orama-js/search/fields-boosting)
- [Typo Tolerance](https://docs.orama.com/docs/orama-js/search#typo-tolerance)
- [Exact Match](https://docs.orama.com/docs/orama-js/search#exact-match)
- [BM25](https://docs.orama.com/docs/orama-js/search/bm25)
- [Stemming and tokenization in 30 languages](https://docs.orama.com/docs/orama-js/text-analysis/stemming)
- [Plugin System](https://docs.orama.com/docs/orama-js/plugins)
# Installation
You can install Orama using `npm`, `yarn`, `pnpm`, `bun`:
```sh
npm i @orama/orama
```
Or import it directly in a browser module:
```html
<html>
<body>
<script type="module">
import { create, insert, search } from 'https://cdn.jsdelivr.net/npm/@orama/orama@latest/+esm'
</script>
</body>
</html>
```
With Deno, you can just use the same CDN URL or use npm specifiers:
```js
import { create, search, insert } from 'npm:@orama/orama'
```
Read the complete documentation at [https://docs.orama.com](https://docs.orama.com).
# Orama Features
<p align="center">
<img src="https://raw.githubusercontent.com/oramasearch/orama/refs/heads/main/misc/readme/features-light.png#gh-light-mode-only" />
</p>
# Usage
Orama is quite simple to use. The first thing to do is to create a new database
instance and set an indexing schema:
```js
import { create, insert, remove, search, searchVector } from '@orama/orama'
const db = create({
schema: {
name: 'string',
description: 'string',
price: 'number',
embedding: 'vector[1536]', // Vector size must be expressed during schema initialization
meta: {
rating: 'number',
},
},
})
insert(db, {
name: 'Noise cancelling headphones',
description: 'Best noise cancelling headphones on the market',
price: 99.99,
embedding: [0.2432, 0.9431, 0.5322, 0.4234, ...],
meta: {
rating: 4.5
}
})
const results = search(db, {
term: 'Best headphones'
})
// {
// elapsed: {
// raw: 21492,
// formatted: '21ฮผs',
// },
// hits: [
// {
// id: '41013877-56',
// score: 0.925085832971998432,
// document: {
// name: 'Noise cancelling headphones',
// description: 'Best noise cancelling headphones on the market',
// price: 99.99,
// embedding: [0.2432, 0.9431, 0.5322, 0.4234, ...],
// meta: {
// rating: 4.5
// }
// }
// }
// ],
// count: 1
// }
```
Orama currently supports 10 different data types:
| Type | Description | Example |
| ---------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `string` | A string of characters. | `'Hello world'` |
| `number` | A numeric value, either float or integer. | `42` |
| `boolean` | A boolean value. | `true` |
| `enum` | An enum value. | `'drama'` |
| `geopoint` | A geopoint value. | `{ lat: 40.7128, lon: 74.0060 }` |
| `string[]` | An array of strings. | `['red', 'green', 'blue']` |
| `number[]` | An array of numbers. | `[42, 91, 28.5]` |
| `boolean[]` | An array of booleans. | `[true, false, false]` |
| `enum[]` | An array of enums. | `['comedy', 'action', 'romance']` |
| `vector[<size>]` | A vector of numbers to perform vector search on. | `[0.403, 0.192, 0.830]` |
# Vector and Hybrid Search Support
Orama supports both vector and hybrid search by just setting `mode: 'vector'` when performing search.
To perform this kind of search, you'll need to provide [text embeddings](https://en.wikipedia.org/wiki/Word_embedding) at search time:
```js
import { create, insertMultiple, search } from '@orama/orama'
const db = create({
schema: {
title: 'string',
embedding: 'vector[5]'', // we are using a 5-dimensional vector.
},
});
insertMultiple(db, [
{ title: 'The Prestige', embedding: [0.938293, 0.284951, 0.348264, 0.948276, 0.56472] },
{ title: 'Barbie', embedding: [0.192839, 0.028471, 0.284738, 0.937463, 0.092827] },
{ title: 'Oppenheimer', embedding: [0.827391, 0.927381, 0.001982, 0.983821, 0.294841] },
])
const results = search(db, {
// Search mode. Can be 'vector', 'hybrid', or 'fulltext'
mode: 'vector',
vector: {
// The vector (text embedding) to use for search
value: [0.938292, 0.284961, 0.248264, 0.748276, 0.26472],
// The schema property where Orama should compare embeddings
property: 'embedding',
},
// Minimum similarity to determine a match. Defaults to `0.8`
similarity: 0.85,
// Defaults to `false`. Setting to 'true' will return the embeddings in the response (which can be very large).
includeVectors: true,
})
```
Have trouble generating embeddings for vector and hybrid search? Try our `@orama/plugin-embeddings` plugin!
```js
import { create } from '@orama/orama'
import { pluginEmbeddings } from '@orama/plugin-embeddings'
import '@tensorflow/tfjs-node' // Or any other appropriate TensorflowJS backend, like @tensorflow/tfjs-backend-webgl
const plugin = await pluginEmbeddings({
embeddings: {
// Schema property used to store generated embeddings
defaultProperty: 'embeddings',
onInsert: {
// Generate embeddings at insert-time
generate: true,
// properties to use for generating embeddings at insert time.
// Will be concatenated to generate a unique embedding.
properties: ['description'],
verbose: true,
}
}
})
const db = create({
schema: {
description: 'string',
// Orama generates 512-dimensions vectors.
// When using @orama/plugin-embeddings, set the property where you want to store embeddings as `vector[512]`.
embeddings: 'vector[512]'
},
plugins: [plugin]
})
// Orama will generate and store embeddings at insert-time!
await insert(db, { description: 'Classroom Headphones Bulk 5 Pack, Student On Ear Color Varieties' })
await insert(db, { description: 'Kids Wired Headphones for School Students K-12' })
await insert(db, { description: 'Kids Headphones Bulk 5-Pack for K-12 School' })
await insert(db, { description: 'Bose QuietComfort Bluetooth Headphones' })
// Orama will also generate and use embeddings at search time when search mode is set to "vector" or "hybrid"!
const searchResults = await search(db, {
term: 'Headphones for 12th grade students',
mode: 'vector'
})
```
Want to use OpenAI embedding models? Use our [Secure Proxy](https://docs.orama.com/docs/orama-js/plugins/plugin-secure-proxy) plugin to call OpenAI from the client-side securely.
# RAG and Chat Experiences with Orama
Since `v3.0.0`, Orama allows you to create your own ChatGPT/Perplexity/SearchGPT-like experience. You will need to call the OpenAI APIs, so we strongly recommend using the [Secure Proxy Plugin](https://docs.orama.com/docs/orama-js/plugins/plugin-secure-proxy) to do that securely from your client side. It's free!
```js
import { create, insert } from '@orama/orama'
import { pluginSecureProxy } from '@orama/plugin-secure-proxy'
const secureProxy = await pluginSecureProxy({
apiKey: 'my-api-key',
defaultProperty: 'embeddings',
models: {
// The chat model to use to generate the chat answer
chat: 'openai/gpt-4o-mini'
}
})
const db = create({
schema: {
name: 'string'
},
plugins: [secureProxy]
})
insert(db, { name: 'John Doe' })
insert(db, { name: 'Jane Doe' })
const session = new AnswerSession(db, {
// Customize the prompt for the system
systemPrompt: 'You will get a name as context, please provide a greeting message',
events: {
// Log all state changes. Useful to reactively update a UI on a new message chunk, sources, etc.
onStateChange: console.log,
}
})
const response = await session.ask({
term: 'john'
})
console.log(response) // Hello, John Doe! How are you doing?
```
Read the complete documentation [here](https://docs.orama.com/docs/orama-js/usage/answer-engine/introduction).
# Official Docs
Read the complete documentation at [https://docs.orama.com/open-source](https://docs.orama.com/open-source).
# Official Orama Plugins
- [Plugin Embeddings](https://docs.orama.com/docs/orama-js/plugins/plugin-embeddings)
- [Plugin Secure Proxy](https://docs.orama.com/docs/orama-js/plugins/plugin-secure-proxy)
- [Plugin Analytics](https://docs.orama.com/docs/orama-js/plugins/plugin-analytics)
- [Plugin Data Persistence](https://docs.orama.com/docs/orama-js/plugins/plugin-data-persistence)
- [Plugin QPS](https://docs.orama.com/docs/orama-js/plugins/plugin-qps)
- [Plugin PT15](https://docs.orama.com/docs/orama-js/plugins/plugin-pt15)
- [Plugin Vitepress](https://docs.orama.com/docs/orama-js/plugins/plugin-vitepress)
- [Plugin Docusaurus](https://docs.orama.com/docs/orama-js/plugins/plugin-docusaurus)
- [Plugin Astro](https://docs.orama.com/docs/orama-js/plugins/plugin-astro)
- [Plugin Nextra](https://docs.orama.com/docs/orama-js/plugins/plugin-nextra)
Write your own plugin: [https://docs.orama.com/docs/orama-js/plugins/writing-your-own-plugins](https://docs.orama.com/docs/orama-js/plugins/writing-your-own-plugins)
# License
Orama is licensed under the [Apache 2.0](/LICENSE.md) license.
<img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=fb0c2057-e709-49a9-b634-cf90bdfb2dbd" />
# Orama Analytics Plugin
[](https://github.com/oramasearch/orama/actions/workflows/turbo.yml)
Official plugin to provide analytics data on your searches.
# Usage
For the complete usage guide, please refer to the [official plugin documentation](https://docs.orama.com/docs/orama-js/plugins/plugin-analytics).
To use the Orama Analytics Plugin, you will need to sign up for a free account at [https://cloud.orama.com](https://cloud.orama.com)
```js
import { create, insert, search } from '@orama/orama'
import { pluginAnalytics} from '@orama/plugin-analytics'
const db = await create({
schema: {
title: 'string',
description: 'string'
},
plugins: [
pluginAnalytics({
apiKey: '<API-KEY>',
endpoint: '<ENDPOINT>'
})
]
})
```
For the full configuration guide of this plugin, please follow the [official plugin documentation](https://docs.orama.com/docs/orama-js/plugins/plugin-analytics).
# License
[Apache-2.0](/LICENSE.md)
# Orama's Astro Plugin
[](https://github.com/oramasearch/orama/actions/workflows/turbo.yml)
This package is a (still experimental) [Orama](https://oramasearch.com) integration for
[Astro](https://astro.build).
## Usage
### Configuring the Astro integration
```typescript
// In `astro.config.mjs`
import orama from '@orama/plugin-astro'
// https://astro.build/config
export default defineConfig({
integrations: [
orama({
// We can generate more than one DB, with different configurations
mydb: {
// Required. Only pages matching this path regex will be indexed
pathMatcher: /blog\/[0-9]{4}\/[0-9]{2}\/[0-9]{2}\/.+$/,
// Optional. 'english' by default
language: 'spanish',
// Optional. ['body'] by default. Use it to constraint what is used to
// index a page.
contentSelectors: ['h1', 'main']
}
})
]
})
```
When running the `astro build` command, a new DB file will be persisted in the
`dist/assets` directory. For the particular case of this example, it will be
saved in the file `dist/assets/oramaDB_mydb.json`.
### Using generated DBs in your pages
To use the generated DBs in your pages, you can include a script in your
`<head>` section, as the following one:
```html
<head>
<!-- Other stuff -->
<script>
// Astro will do the job of bundling everything for you
import { getOramaDB, search } from "@orama/plugin-astro/client"
// We load the DB that we generated at build time, this is an asynchronous
// operation, so we must either await, or rely on `.then` calls.
const db = await getOramaDB('mydb')
// Now we can search inside our DB. Of course, feel free to use it in more
// interesting ways.
console.log('Search Results')
console.log(search(db, { term: 'mySearchTerm' }))
</script>
</head>
```
**NOTE:** For now, this plugin only supports readonly DBs. This might change in
the future if there's demand for it.
# Data Persistence Plugin
[](https://github.com/oramasearch/orama/actions/workflows/turbo.yml)
This plugin aims to provide data persistence capabilities to Orama.
# Usage
For the complete usage guide, please refer to the [official plugin documentation](https://docs.orama.com/docs/orama-js/plugins/plugin-data-persistence).
# License
[Apache-2.0](/LICENSE.md)
# Orama Plugin for Docusaurus v3
[Plugin documentation](https://docs.orama.com/docs/orama-js/plugins/plugin-docusaurus)
## Local Development
To test the plugin locally, follow these steps:
### (Required only if using workspace dependencies):
Replace all the `workspace:*` packages with the latest version of the package.
#### Steps:
1. Add a link to the plugin in your Docusaurus project:
```bash
"dependencies": {
"@orama/plugin-docusaurus": "file:../path/to/plugin"
}
```
2. Install the plugin:
```bash
pnpm install
```
3. Start your Plugin project (plugin folder):
```bash
pnpm run watch
```
4. Copy the needed CSS files into dist folder:
```bash
pnpm run postbuild
```
5. Start your Docusaurus project:
```bash
pnpm start
```
The Docusaurus project will watch automatically for changes in the plugin, so you can edit the plugin and see the changes in real-time.
### Other information
- The Answer Session will not work while working on Staging due to the answer session url being hard-corded to production. To test it please, use prod environment.
For Docusaurus v2, please refer to the [v2 branch.](https://www.npmjs.com/package/@orama/plugin-docusaurus)
# Orama plugin for Docusaurus v2
[](https://github.com/oramasearch/orama/actions/workflows/turbo.yml)
## Pre-requisites
In order guarantee a correct functionality of the plugin, you need to have the `@docusaurus/core` at least in the version `2.4.3`.
| :warning: This plugin do not support Docusaurus v3. Use [`@orama/plugin-docusaurus-v3`](https://www.npmjs.com/package/@orama/plugin-docusaurus-v3) instead. |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
## Usage
Install the plugin:
```bash
npm install --save @orama/plugin-docusaurus
```
```bash
yarn add @orama/plugin-docusaurus
```
Add the plugin to your `docusaurus.config.js`:
```js
plugins: ['@orama/plugin-docusaurus']
```
# License
Licensed under the [Apache 2.0](/LICENSE.md) license.
# Orama Plugin Embeddings
**Orama Plugin Embeddings** allows you to generate fast text embeddings at insert and search time offline, directly on your machine - no OpenAI needed!
## Installation
To get started with **Orama Plugin Embeddings**, just install it with npm:
```sh
npm i @orama/plugin-embeddings
```
**Important note**: to use this plugin, you'll also need to install one of the following TensorflowJS backend:
- `@tensorflow/tfjs`
- `@tensorflow/tfjs-node`
- `@tensorflow/tfjs-backend-webgl`
- `@tensorflow/tfjs-backend-cpu`
- `@tensorflow/tfjs-node-gpu`
- `@tensorflow/tfjs-backend-wasm`
For example, if you're running Orama on the browser, we highly recommend using `@tensorflow/tfjs-backend-webgl`:
```sh
npm i @tensorflow/tfjs-backend-webgl
```
If you're using Orama in Node.js, we recommend using `@tensorflow/tfjs-node`:
```sh
npm i @tensorflow/tfjs-node
```
## Usage
```js
import { create } from '@orama/orama'
import { pluginEmbeddings } from '@orama/plugin-embeddings'
import '@tensorflow/tfjs-node' // Or any other appropriate TensorflowJS backend
const plugin = await pluginEmbeddings({
embeddings: {
defaultProperty: 'embeddings', // Property used to store generated embeddings
onInsert: {
generate: true, // Generate embeddings at insert-time
properties: ['description'], // properties to use for generating embeddings at insert time
verbose: true,
}
}
})
const db = await create({
schema: {
description: 'string',
embeddings: 'vector[512]' // Orama generates 512-dimensions vectors
},
plugins: [plugin]
})
```
Example usage at insert time:
```js
await insert(db, {
description: 'Classroom Headphones Bulk 5 Pack, Student On Ear Color Varieties'
})
await insert(db, {
description: 'Kids Wired Headphones for School Students K-12'
})
await insert(db, {
description: 'Kids Headphones Bulk 5-Pack for K-12 School'
})
await insert(db, {
description: 'Bose QuietComfort Bluetooth Headphones'
})
```
Orama will automatically generate text embeddings and store them into the `embeddings` property.
Then, you can use the `vector` or `hybrid` setting to perform hybrid or vector search at runtime:
```js
await search(db, {
term: 'Headphones for 12th grade students',
mode: 'vector'
})
```
Orama will generate embeddings at search time and perform vector or hybrid search for you.
# License
[Apache 2.0](/LICENSE.md)
# Match Highlight Plugin - DEPRECATED
This plugin is deprecated in favor of [Orama Highlight](https://www.npmjs.com/package/@orama/highlight). It's faster, easier to use, and with a minimal memory footprint. Give it a try!
# License
[Apache-2.0](/LICENSE.md)
# Nextra Plugin
[](https://github.com/oramasearch/orama/actions/workflows/turbo.yml)
Official plugin to provide search capabilities through Orama on any Nextra website!
# Usage
For the complete usage guide, please refer to the [official plugin documentation](https://docs.orama.com/docs/orama-js/plugins/plugin-nextra).
# License
[Apache-2.0](/LICENSE.md)
# Parsedoc Plugin
[](https://github.com/oramasearch/orama/actions/workflows/turbo.yml)
This plugin aims to generate an index for Orama from HTML files
# Usage
For the complete usage guide, please refer to the [official plugin documentation](https://docs.orama.com/docs/orama-js/plugins/plugin-parsedoc).
# License
[Apache-2.0](/LICENSE.md)
# Orama Plugin PT15
Fast ranking algorithm based on token position.
## Installation
To get started with **Orama Plugin PT15**, just install it with npm:
```sh
npm i @orama/plugin-pt15
```
## Usage
```js
import { create } from '@orama/orama'
import { pluginPT15 } from '@orama/plugin-pt15'
const db = await create({
schema: {
description: 'string',
},
plugins: [ pluginPT15() ],
})
```
# License
[Apache 2.0](/LICENSE.md)
# Orama Plugin Quantum Proximity Scoring
**Orama Plugin Quantum Proximity Scoring** ranks search results based on the proximity of query tokens in the document.
## Installation
To get started with **Orama Plugin QPS**, just install it with npm:
```sh
npm i @orama/plugin-qps
```
## Usage
```js
import { create } from '@orama/orama'
import { pluginQPS } from '@orama/plugin-qps'
const db = await create({
schema: {
description: 'string',
},
plugins: [ pluginQPS() ],
})
```
# License
[Apache 2.0](/LICENSE.md)
# Snowball Stemmer
This directory contains **generated** stemmers using the
[Snowball](http://snowballstem.org/) compiler.
Do not edit these files directly.
# Orama Stemmers
Orama can analyze the input and perform a `stemming` operation, which allows the engine to perform more optimized queries, as well as save indexing space.
<!-- LANGUAGES:START -->
Right now, Orama supports 31 languages and stemmers out of the box:
- Arabic
- Armenian
- Bulgarian
- Czech
- Danish
- Dutch
- English
- Finnish
- French
- German
- Greek
- Hindi
- Hungarian
- Indonesian
- Irish
- Italian
- Lithuanian
- Nepali
- Norwegian
- Portuguese
- Romanian
- Russian
- Sanskrit
- Serbian
- Slovenian
- Spanish
- Swedish
- Tamil
- Turkish
- Ukrainian
- Vietnamese
<!-- LANGUAGES:END -->
Chinese (Mandarin) and Japanese are supported through dedicated tokenizers (`@orama/tokenizers`) and stop-word removal (`@orama/stopwords`), not through stemming.
```js
import { create } from '@orama/orama'
import { stemmer, language } from '@orama/stemmers/italian'
const db = create({
schema: {
components: {
tokenizer: {
stemming: true,
stemmer,
language
}
}
})
```
Read more in the official docs: [https://docs.orama.com/docs/orama-js/text-analysis/stemming](https://docs.orama.com/docs/orama-js/text-analysis/stemming).
# License
[Apache 2.0](/LICENSE.md)
# Orama Stop-words
<!-- LANGUAGES:START -->
This package provides support for stop-words removal in 33 languages:
- Arabic
- Armenian
- Bulgarian
- Chinese (Mandarin)
- Czech
- Danish
- Dutch
- English
- Finnish
- French
- German
- Greek
- Hindi
- Hungarian
- Indonesian
- Irish
- Italian
- Japanese
- Lithuanian
- Nepali
- Norwegian
- Portuguese
- Romanian
- Russian
- Sanskrit
- Serbian
- Slovenian
- Spanish
- Swedish
- Tamil
- Turkish
- Ukrainian
- Vietnamese
<!-- LANGUAGES:END -->
```js
import { create } from '@orama/orama'
import { stopwords as italianStopwords } from '@orama/stopwords/italian'
const db = create({
schema: {
components: {
tokenizer: {
stopwords: italianStopwords
}
}
})
```
Read more in the official docs: [https://docs.orama.com/docs/orama-js/text-analysis/stop-words](https://docs.orama.com/docs/orama-js/text-analysis/stop-words).
# License
[Apache 2.0](/LICENSE.md)
# Orama Switch
Orama Switch allows you to run queries on Orama Cloud and OSS with a single interface.
## Installation
```sh
npm i @orama/switch
```
## Usage
You can use the same APIs to access either Orama Cloud or Orama OSS.
For instance, this is how you would interact with Orama Cloud:
```js
import { Switch } from '@orama/switch'
import { OramaClient } from '@oramacloud/client'
const client = new OramaClient({
endpoint: '<Your Orama Cloud Endpoint>',
api_key: '<Your Orama Cloud API Key>',
})
const orama = new Switch(client)
const results = await orama.search({
term: 'noise cancelling headphones',
where: {
price: {
lte: 99.99
}
}
})
```
And this is Orama OSS:
```js
import { Switch } from '@orama/switch'
import { create } from '@orama/orama'
const db = await create({
schema: {
productName: 'string',
price: 'number'
}
})
const orama = new Switch(client)
const results = await orama.search({
term: 'noise cancelling headphones',
where: {
price: {
lte: 99.99
}
}
})
```
## License
[Apache 2.0](/LICENSE.md)