Elasticsearch needs a JVM, 2GB+ RAM, and a PhD to configure. Typesense runs as a single binary, uses 100MB RAM, and returns results in under 50ms.
Why Typesense
| Elasticsearch | Meilisearch | Typesense | |
|---|---|---|---|
| Written in | Java | Rust | C++ |
| Min RAM | 2GB | 100MB | 100MB |
| Setup | Complex | Easy | Easy |
| Typo tolerance | Plugin | Built-in | Built-in |
| Geo search | Yes | Yes | Yes |
| Faceting | Yes | Yes | Yes |
| Latency (p99) | 50-200ms | 20-50ms | 5-50ms |
Setup
# Docker
docker run -p 8108:8108 \
-v typesense-data:/data \
typesense/typesense:27.0 \
--data-dir=/data \
--api-key=YOUR_API_KEY
# Or binary
curl -O https://dl.typesense.org/releases/27.0/typesense-server-27.0-linux-amd64.tar.gz
tar xzf typesense-server-*.tar.gz
./typesense-server --data-dir=./data --api-key=YOUR_API_KEY
Create Collection & Index Data
import Typesense from "typesense";
const client = new Typesense.Client({
nodes: [{ host: "localhost", port: 8108, protocol: "http" }],
apiKey: "YOUR_API_KEY",
});
// Create collection (schema)
await client.collections().create({
name: "products",
fields: [
{ name: "name", type: "string" },
{ name: "description", type: "string" },
{ name: "price", type: "float" },
{ name: "category", type: "string", facet: true },
{ name: "rating", type: "float" },
{ name: "in_stock", type: "bool" },
],
default_sorting_field: "rating",
});
// Index documents
await client.collections("products").documents().import([
{ name: "MacBook Pro", description: "Powerful laptop for developers", price: 1999, category: "Laptops", rating: 4.8, in_stock: true },
{ name: "iPhone 15", description: "Latest smartphone from Apple", price: 999, category: "Phones", rating: 4.6, in_stock: true },
]);
Search
const results = await client.collections("products").documents().search({
q: "macbok", // Typo-tolerant!
query_by: "name,description",
filter_by: "price:<2000 && in_stock:true",
sort_by: "rating:desc",
facet_by: "category",
per_page: 10,
});
// results.hits[0].document → { name: "MacBook Pro", ... }
// results.facet_counts → [{ field_name: "category", counts: [{value: "Laptops", count: 1}] }]
Typo in "macbok"? Typesense still finds "MacBook Pro".
InstantSearch UI
npm install typesense-instantsearch-adapter react-instantsearch
import TypesenseInstantsearchAdapter from "typesense-instantsearch-adapter";
import { InstantSearch, SearchBox, Hits, RefinementList } from "react-instantsearch";
const adapter = new TypesenseInstantsearchAdapter({
server: { nodes: [{ host: "localhost", port: 8108, protocol: "http" }], apiKey: "search-key" },
additionalSearchParameters: { query_by: "name,description" },
});
function SearchPage() {
return (
<InstantSearch indexName="products" searchClient={adapter.searchClient}>
<SearchBox />
<RefinementList attribute="category" />
<Hits hitComponent={({ hit }) => <div>{hit.name} — ${hit.price}</div>} />
</InstantSearch>
);
}
Full search UI with faceted filtering in 20 lines.
Cloud Option
Typesense Cloud starts at free (28K documents, 28K searches/month). No server to manage.
Need search or data extraction solutions? I build web scraping and API tools. Email spinov001@gmail.com or explore my Apify tools.
Top comments (0)