diff --git a/README.md b/README.md
index 694ca4c..3108bf7 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@ This is a monorepo containing multiple standalone projects. Each project lives i
code-samples/
├── typesense-astro-search/ # Astro + Typesense search implementation
├── typesense-next-search-bar/ # Next.js + Typesense search implementation
+├── typesense-solid-js-search/ # SolidJS + Typesense search implementation
├── typesense-vanilla-js-search/ # Vanilla JS + Typesense search implementation
├── ... # More projects coming soon
└── README.md # You are here
@@ -21,6 +22,7 @@ code-samples/
| -------------------------------------------------------------- | ---------- | ---------------------------------------------------- |
| [typesense-astro-search](./typesense-astro-search) | Astro | A modern search bar with instant search capabilities |
| [typesense-next-search-bar](./typesense-next-search-bar) | Next.js | A modern search bar with instant search capabilities |
+| [typesense-solid-js-search](./typesense-solid-js-search) | SolidJS | A modern search bar with instant search capabilities |
| [typesense-vanilla-js-search](./typesense-vanilla-js-search) | Vanilla JS | A modern search bar with instant search capabilities |
## Getting Started
diff --git a/typesense-solid-js-search/.env.sample b/typesense-solid-js-search/.env.sample
new file mode 100644
index 0000000..7e42c7c
--- /dev/null
+++ b/typesense-solid-js-search/.env.sample
@@ -0,0 +1,4 @@
+VITE_TYPESENSE_API_KEY=xyz
+VITE_TYPESENSE_HOST=localhost
+VITE_TYPESENSE_PORT=8108
+VITE_TYPESENSE_PROTOCOL=http
\ No newline at end of file
diff --git a/typesense-solid-js-search/README.md b/typesense-solid-js-search/README.md
new file mode 100644
index 0000000..90a6fd9
--- /dev/null
+++ b/typesense-solid-js-search/README.md
@@ -0,0 +1,81 @@
+# SolidJS Search Bar with Typesense
+
+A modern search bar application built with SolidJS and Typesense, featuring instant search capabilities.
+
+## Tech Stack
+
+- SolidJS
+- Typesense
+- typesense-instantsearch-adapter & instantsearch.js
+
+## Prerequisites
+
+- Node.js 18+ and npm 9+.
+- Docker (for running Typesense locally). Alternatively, you can use a Typesense Cloud cluster.
+- Basic knowledge of SolidJS.
+
+## Quick Start
+
+### 1. Clone the repository
+
+```bash
+git clone https://github.com/typesense/code-samples.git
+cd typesense-solid-js-search
+```
+
+### 2. Install dependencies
+
+```bash
+npm install
+```
+
+### 3. Set up environment variables
+
+Create a `.env` file in the project root with the following content:
+
+```env
+VITE_TYPESENSE_API_KEY=xyz
+VITE_TYPESENSE_HOST=localhost
+VITE_TYPESENSE_PORT=8108
+VITE_TYPESENSE_PROTOCOL=http
+```
+
+### 4. Project Structure
+
+```text
+├── src
+│ ├── components
+│ │ ├── BookCard.tsx
+│ │ ├── BookList.tsx
+│ │ ├── BookSearch.tsx
+│ │ ├── Heading.tsx
+│ │ └── icons.tsx
+│ ├── types
+│ │ └── Book.ts
+│ ├── utils
+│ │ └── typesense.ts
+│ ├── App.tsx
+│ ├── index.css
+│ └── index.tsx
+├── index.html
+└── package.json
+```
+
+### 5. Start the development server
+
+```bash
+npm run dev
+```
+
+Open [http://localhost:5173](http://localhost:5173) in your browser.
+
+### 6. Deployment
+
+Set env variables to point the app to the Typesense Cluster:
+
+```env
+VITE_TYPESENSE_API_KEY=xxx
+VITE_TYPESENSE_HOST=xxx.typesense.net
+VITE_TYPESENSE_PORT=443
+VITE_TYPESENSE_PROTOCOL=https
+```
diff --git a/typesense-solid-js-search/index.html b/typesense-solid-js-search/index.html
new file mode 100644
index 0000000..bb839bf
--- /dev/null
+++ b/typesense-solid-js-search/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Typesense Solid.js Search
+
+
+
+
+
+
diff --git a/typesense-solid-js-search/package.json b/typesense-solid-js-search/package.json
new file mode 100644
index 0000000..267c428
--- /dev/null
+++ b/typesense-solid-js-search/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "typesense-solid-js-search",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc -b && vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "instantsearch.js": "^4.86.1",
+ "solid-js": "^1.9.10",
+ "typesense": "^2.1.0",
+ "typesense-instantsearch-adapter": "^2.9.0"
+ },
+ "devDependencies": {
+ "@types/node": "^24.10.1",
+ "typescript": "~5.9.3",
+ "vite": "^7.2.4",
+ "vite-plugin-solid": "^2.11.10"
+ }
+}
diff --git a/typesense-solid-js-search/public/favicon.png b/typesense-solid-js-search/public/favicon.png
new file mode 100644
index 0000000..f42ec19
Binary files /dev/null and b/typesense-solid-js-search/public/favicon.png differ
diff --git a/typesense-solid-js-search/src/App.css b/typesense-solid-js-search/src/App.css
new file mode 100644
index 0000000..409f8cc
--- /dev/null
+++ b/typesense-solid-js-search/src/App.css
@@ -0,0 +1,4 @@
+:root {
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ font-weight: 400;
+}
diff --git a/typesense-solid-js-search/src/App.tsx b/typesense-solid-js-search/src/App.tsx
new file mode 100644
index 0000000..dcbe50a
--- /dev/null
+++ b/typesense-solid-js-search/src/App.tsx
@@ -0,0 +1,14 @@
+import "./App.css";
+import Heading from "./components/Heading";
+import { BookSearch } from "./components/BookSearch";
+
+function App() {
+ return (
+ <>
+
+
+ >
+ );
+}
+
+export default App;
diff --git a/typesense-solid-js-search/src/components/BookCard.module.css b/typesense-solid-js-search/src/components/BookCard.module.css
new file mode 100644
index 0000000..3b92412
--- /dev/null
+++ b/typesense-solid-js-search/src/components/BookCard.module.css
@@ -0,0 +1,73 @@
+.bookCard {
+ background: white;
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ transition:
+ transform 0.2s ease,
+ box-shadow 0.2s ease;
+}
+
+.bookCard:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
+}
+
+.bookImageContainer {
+ width: 100%;
+ height: 250px;
+ overflow: hidden;
+ background: #f5f5f5;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.bookImage {
+ max-width: 100%;
+ max-height: 100%;
+ width: auto;
+ height: auto;
+ object-fit: contain;
+}
+
+.bookInfo {
+ padding: 1rem;
+}
+
+.bookTitle {
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: #2c3e50;
+ margin: 0 0 0.5rem;
+ line-height: 1.3;
+}
+
+.bookAuthor {
+ color: #7f8c8d;
+ font-size: 0.9rem;
+ margin: 0 0 0.5rem;
+}
+
+.ratingContainer {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ margin-bottom: 0.5rem;
+}
+
+.starRating {
+ color: #f39c12;
+ font-size: 0.9rem;
+}
+
+.ratingText {
+ color: #95a5a6;
+ font-size: 0.8rem;
+}
+
+.bookYear {
+ color: #95a5a6;
+ font-size: 0.85rem;
+ margin: 0;
+}
diff --git a/typesense-solid-js-search/src/components/BookCard.tsx b/typesense-solid-js-search/src/components/BookCard.tsx
new file mode 100644
index 0000000..3c52301
--- /dev/null
+++ b/typesense-solid-js-search/src/components/BookCard.tsx
@@ -0,0 +1,42 @@
+import styles from "./BookCard.module.css";
+import type { Book } from "../types/Book";
+
+interface BookCardProps {
+ book: Book;
+}
+
+export function BookCard(props: BookCardProps) {
+ const stars = "★".repeat(Math.round(props.book.average_rating || 0));
+
+ return (
+
+ {props.book.image_url && (
+
+

+
+ )}
+
+
{props.book.title}
+
+ {props.book.authors?.join(", ") || "Unknown Author"}
+
+
+ {stars}
+
+ {props.book.average_rating?.toFixed(1) || "0"} (
+ {props.book.ratings_count?.toLocaleString() || 0} ratings)
+
+
+ {props.book.publication_year && (
+
+ Published: {props.book.publication_year}
+
+ )}
+
+
+ );
+}
diff --git a/typesense-solid-js-search/src/components/BookList.module.css b/typesense-solid-js-search/src/components/BookList.module.css
new file mode 100644
index 0000000..34b2b67
--- /dev/null
+++ b/typesense-solid-js-search/src/components/BookList.module.css
@@ -0,0 +1,79 @@
+.bookList {
+ padding-bottom: 2rem;
+}
+
+.loadingContainer {
+ text-align: center;
+ padding: 3rem 1rem;
+}
+
+.spinner {
+ display: inline-block;
+ width: 2rem;
+ height: 2rem;
+ border: 3px solid #f3f3f3;
+ border-top: 3px solid #667eea;
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+ margin-bottom: 1rem;
+}
+
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+.noResults {
+ text-align: center;
+ padding: 3rem 1rem;
+ background: #f9f9f9;
+ border-radius: 8px;
+ margin: 2rem 0;
+}
+
+.noResults h3 {
+ color: #333;
+ margin-bottom: 0.5rem;
+}
+
+.noResults p {
+ color: #666;
+ margin: 0;
+}
+
+.resultsCount {
+ color: #666;
+ margin-bottom: 1.5rem;
+ font-size: 0.95rem;
+}
+
+.bookGrid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 1.5rem;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+@media (min-width: 768px) {
+ .bookGrid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
+
+@media (min-width: 1024px) {
+ .bookGrid {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
+
+@media (min-width: 1280px) {
+ .bookGrid {
+ grid-template-columns: repeat(4, 1fr);
+ }
+}
diff --git a/typesense-solid-js-search/src/components/BookList.tsx b/typesense-solid-js-search/src/components/BookList.tsx
new file mode 100644
index 0000000..85a94f0
--- /dev/null
+++ b/typesense-solid-js-search/src/components/BookList.tsx
@@ -0,0 +1,35 @@
+import { For, Show } from "solid-js";
+import { BookCard } from "./BookCard";
+import styles from "./BookList.module.css";
+import type { Book } from "../types/Book";
+
+interface BookListProps {
+ books: Book[];
+ loading: boolean;
+}
+
+export function BookList(props: BookListProps) {
+ return (
+
+
+
+
+
+
+
+
No books found
+
Try adjusting your search or try different keywords.
+
+
+
+
0}>
+
+ {(book) => }
+
+
+
+ );
+}
diff --git a/typesense-solid-js-search/src/components/BookSearch.module.css b/typesense-solid-js-search/src/components/BookSearch.module.css
new file mode 100644
index 0000000..f17a37d
--- /dev/null
+++ b/typesense-solid-js-search/src/components/BookSearch.module.css
@@ -0,0 +1,128 @@
+.searchContainer {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2rem 1.5rem;
+}
+
+.searchBoxContainer {
+ max-width: 600px;
+ margin: 0 auto 2rem;
+}
+
+/* Override InstantSearch searchbox styles */
+.ais-SearchBox {
+ width: 100%;
+}
+
+.searchForm {
+ position: relative;
+ width: 100%;
+ background: transparent;
+}
+
+.searchInput {
+ width: 100%;
+ padding: 0.85rem 3rem 0.85rem 3rem;
+ font-size: 1rem;
+ border: 2px solid #e0e0e0;
+ border-radius: 30px;
+ outline: none;
+ transition: all 0.3s ease;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ box-sizing: border-box;
+ background: white;
+}
+
+.searchInput:focus {
+ border-color: #667eea;
+ box-shadow: 0 2px 12px rgba(102, 126, 234, 0.2);
+}
+
+/* Add magnifying glass icon using pseudo-element */
+.searchForm::before {
+ content: "";
+ position: absolute;
+ left: 1rem;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 16px;
+ height: 16px;
+ background-image: url("data:image/svg+xml,%3Csvg fill='none' stroke='currentColor' viewBox='0 0 24 24' width='16' height='16'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z'%3E%3C/path%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: center;
+ color: #7f8c8d;
+ pointer-events: none;
+ z-index: 1;
+}
+
+/* Hide InstantSearch default reset button more aggressively */
+.ais-SearchBox-reset {
+ display: none !important;
+ visibility: hidden !important;
+ opacity: 0 !important;
+ width: 0 !important;
+ height: 0 !important;
+ overflow: hidden !important;
+ position: absolute !important;
+ left: -9999px !important;
+}
+
+/* Also hide any reset button inside the form */
+.ais-SearchBox-form .ais-SearchBox-reset {
+ display: none !important;
+ visibility: hidden !important;
+ opacity: 0 !important;
+ width: 0 !important;
+ height: 0 !important;
+ overflow: hidden !important;
+ position: absolute !important;
+ left: -9999px !important;
+}
+
+.searchSubmit,
+.searchReset {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 0.5rem;
+ color: #7f8c8d;
+ transition: color 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.searchSubmit {
+ display: none;
+}
+
+.searchReset {
+ right: 0.75rem;
+}
+
+.searchSubmit:hover,
+.searchReset:hover {
+ color: #667eea;
+}
+
+.searchSubmitIcon,
+.searchResetIcon {
+ width: 16px;
+ height: 16px;
+}
+
+.resultsCount {
+ color: #666;
+ margin-bottom: 1.5rem;
+ font-size: 0.95rem;
+ text-align: center;
+}
+
+@media (max-width: 768px) {
+ .searchContainer {
+ padding: 1.5rem 1rem;
+ }
+}
diff --git a/typesense-solid-js-search/src/components/BookSearch.tsx b/typesense-solid-js-search/src/components/BookSearch.tsx
new file mode 100644
index 0000000..9b994b3
--- /dev/null
+++ b/typesense-solid-js-search/src/components/BookSearch.tsx
@@ -0,0 +1,99 @@
+import { onMount, onCleanup, createSignal } from "solid-js";
+import { typesenseInstantsearchAdapter } from "../utils/typesense";
+import instantsearch from "instantsearch.js";
+import { searchBox, hits, stats, configure } from "instantsearch.js/es/widgets";
+import { BookList } from "./BookList";
+import styles from "./BookSearch.module.css";
+import type { Book } from "../types/Book";
+
+export function BookSearch() {
+ const [books, setBooks] = createSignal([]);
+ const [loading, setLoading] = createSignal(false);
+
+ let search: any;
+
+ onMount(() => {
+ search = instantsearch({
+ indexName: "books",
+ searchClient: typesenseInstantsearchAdapter.searchClient,
+ future: {
+ preserveSharedStateOnUnmount: true,
+ },
+ });
+
+ search.addWidgets([
+ configure({
+ hitsPerPage: 12,
+ }),
+ searchBox({
+ container: "#searchbox",
+ placeholder: "Search by title or author...",
+ showReset: false,
+ showSubmit: false,
+ cssClasses: {
+ form: styles.searchForm,
+ input: styles.searchInput,
+ submit: styles.searchSubmit,
+ },
+ }),
+ stats({
+ container: "#stats",
+ templates: {
+ text(data, { html }) {
+ if (data.hasManyResults) {
+ return html`${data.nbHits.toLocaleString()} results found`;
+ } else if (data.hasOneResult) {
+ return html`1 result found`;
+ } else {
+ return html`No results found`;
+ }
+ },
+ },
+ }),
+ hits({
+ container: "#hits",
+ templates: {
+ item: () => {
+ return "";
+ },
+ empty: () => {
+ return "";
+ },
+ },
+ transformItems: (items: any[]) => {
+ const booksData = items.map((item) => item as Book);
+ setBooks(booksData);
+ return items;
+ },
+ }),
+ ]);
+
+ // Listen for search state changes
+ search.on("render", () => {
+ const helper = search.helper;
+ setLoading(helper.state.loading);
+ });
+
+ search.start();
+ });
+
+ onCleanup(() => {
+ if (search) {
+ search.dispose();
+ }
+ });
+
+ return (
+
+ );
+}
diff --git a/typesense-solid-js-search/src/components/Heading.module.css b/typesense-solid-js-search/src/components/Heading.module.css
new file mode 100644
index 0000000..7b0f233
--- /dev/null
+++ b/typesense-solid-js-search/src/components/Heading.module.css
@@ -0,0 +1,93 @@
+:root {
+ --primary-glow: linear-gradient(
+ 135deg,
+ rgba(213, 43, 127, 0.4),
+ rgba(102, 126, 234, 0.4)
+ );
+ --accent: #d52b7f;
+ --step-3: clamp(1.5rem, 4vw, 2.5rem);
+ --step-0: clamp(0.875rem, 2vw, 1rem);
+}
+
+.Heading {
+ width: 100%;
+ text-align: center;
+ position: relative;
+ margin-top: 6rem;
+ margin-bottom: 2rem;
+}
+
+.Heading::after {
+ content: "";
+ background: var(--primary-glow);
+ width: 320px;
+ height: 180px;
+ z-index: -1;
+ left: 50%;
+ transform: translateX(-50%);
+ position: absolute;
+ filter: blur(45px);
+ top: -50%;
+ animation: move 40s ease-out infinite;
+}
+
+.Heading h1 {
+ font-size: var(--step-3);
+ font-weight: 700;
+ color: #1a1a1a;
+ margin: 0 0 0.5rem 0;
+}
+
+.typesense {
+ color: var(--accent);
+ font-size: var(--step-0);
+ text-decoration: none;
+ font-family: monospace;
+}
+
+.typesense:hover {
+ text-decoration: underline;
+}
+
+.githubLink {
+ position: fixed;
+ top: 2rem;
+ right: 2rem;
+ color: #333;
+ transition: color 0.2s ease;
+}
+
+.githubLink:hover {
+ color: #000;
+}
+
+.githubLink svg {
+ width: 28px;
+ height: 28px;
+}
+
+.solidJSLogo {
+ width: calc(3.75vmax + 3.25rem);
+ position: relative;
+ top: calc(0.1vmax + 0.1rem);
+ vertical-align: middle;
+ margin-left: 0.25rem;
+}
+
+@keyframes move {
+ 0% {
+ transform: translate(0%) scale(1);
+ }
+ 45% {
+ transform: translate(-40%, 20%) scale(1.2);
+ }
+ 75% {
+ transform: translate(5%, 40%) scale(1.3);
+ }
+ 90% {
+ transform: translate(-5%, 5%) scale(0.9);
+ }
+ 100% {
+ transform: translate(0%) scale(1);
+ }
+}
diff --git a/typesense-solid-js-search/src/components/Heading.tsx b/typesense-solid-js-search/src/components/Heading.tsx
new file mode 100644
index 0000000..5c3ddf8
--- /dev/null
+++ b/typesense-solid-js-search/src/components/Heading.tsx
@@ -0,0 +1,33 @@
+import { GithubIcon, SolidJSIcon } from "./icons";
+import s from "./Heading.module.css";
+
+export default function Heading() {
+ return (
+ <>
+
+
Solid JS Search Bar
+
+
+
+
+
+ >
+ );
+}
diff --git a/typesense-solid-js-search/src/components/icons.tsx b/typesense-solid-js-search/src/components/icons.tsx
new file mode 100644
index 0000000..35618b5
--- /dev/null
+++ b/typesense-solid-js-search/src/components/icons.tsx
@@ -0,0 +1,158 @@
+import type { JSX } from "solid-js";
+type _svgProp = JSX.HTMLAttributes;
+
+export function GithubIcon({ ...svgProps }: _svgProp) {
+ return (
+
+ );
+}
+export function SolidJSIcon({ ...svgProps }: _svgProp) {
+ const style = ` .a {
+ fill: #76b3e1;
+ }
+
+ .b, .d {
+ isolation: isolate;
+ opacity: 0.3;
+ }
+
+ .b {
+ fill: url(#a);
+ }
+
+ .c {
+ fill: #518ac8;
+ }
+
+ .d {
+ fill: url(#b);
+ }
+
+ .e {
+ fill: url(#c);
+ }
+
+ .f {
+ fill: url(#d);
+ }
+
+ .g {
+ fill: #58595b;
+ }`;
+ return (
+
+ );
+}
diff --git a/typesense-solid-js-search/src/index.css b/typesense-solid-js-search/src/index.css
new file mode 100644
index 0000000..e69de29
diff --git a/typesense-solid-js-search/src/index.tsx b/typesense-solid-js-search/src/index.tsx
new file mode 100644
index 0000000..f67cd20
--- /dev/null
+++ b/typesense-solid-js-search/src/index.tsx
@@ -0,0 +1,8 @@
+/* @refresh reload */
+import { render } from 'solid-js/web'
+import './index.css'
+import App from './App.tsx'
+
+const root = document.getElementById('root')
+
+render(() => , root!)
diff --git a/typesense-solid-js-search/src/types/Book.ts b/typesense-solid-js-search/src/types/Book.ts
new file mode 100644
index 0000000..a60803f
--- /dev/null
+++ b/typesense-solid-js-search/src/types/Book.ts
@@ -0,0 +1,9 @@
+export type Book = {
+ id: string;
+ title: string;
+ authors: string[];
+ publication_year: number;
+ average_rating: number;
+ image_url: string;
+ ratings_count: number;
+};
diff --git a/typesense-solid-js-search/src/utils/typesense.ts b/typesense-solid-js-search/src/utils/typesense.ts
new file mode 100644
index 0000000..fe4a79d
--- /dev/null
+++ b/typesense-solid-js-search/src/utils/typesense.ts
@@ -0,0 +1,17 @@
+import TypesenseInstantSearchAdapter from "typesense-instantsearch-adapter";
+
+export const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
+ server: {
+ apiKey: import.meta.env.VITE_TYPESENSE_API_KEY || "xyz",
+ nodes: [
+ {
+ host: import.meta.env.VITE_TYPESENSE_HOST || "localhost",
+ port: Number(import.meta.env.VITE_TYPESENSE_PORT) || 8108,
+ protocol: import.meta.env.VITE_TYPESENSE_PROTOCOL || "http",
+ },
+ ],
+ },
+ additionalSearchParameters: {
+ query_by: "title,authors",
+ },
+});
diff --git a/typesense-solid-js-search/tsconfig.app.json b/typesense-solid-js-search/tsconfig.app.json
new file mode 100644
index 0000000..c0b480e
--- /dev/null
+++ b/typesense-solid-js-search/tsconfig.app.json
@@ -0,0 +1,29 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "types": ["vite/client"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "preserve",
+ "jsxImportSource": "solid-js",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["src"]
+}
diff --git a/typesense-solid-js-search/tsconfig.json b/typesense-solid-js-search/tsconfig.json
new file mode 100644
index 0000000..1ffef60
--- /dev/null
+++ b/typesense-solid-js-search/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "files": [],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
+ ]
+}
diff --git a/typesense-solid-js-search/tsconfig.node.json b/typesense-solid-js-search/tsconfig.node.json
new file mode 100644
index 0000000..8a67f62
--- /dev/null
+++ b/typesense-solid-js-search/tsconfig.node.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2023",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "types": ["node"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/typesense-solid-js-search/vite.config.ts b/typesense-solid-js-search/vite.config.ts
new file mode 100644
index 0000000..4095d9b
--- /dev/null
+++ b/typesense-solid-js-search/vite.config.ts
@@ -0,0 +1,6 @@
+import { defineConfig } from 'vite'
+import solid from 'vite-plugin-solid'
+
+export default defineConfig({
+ plugins: [solid()],
+})