Skip to content

Latest commit

 

History

History

needle

README.md

🪡 Needle - A New Way to Find

A new way to find. Find what you mean, not just what matches. Describe what you are looking for in your own words, without knowing the words the page uses. Needle finds relevant passages and highlights the sentence that matters, right in the original text. Use it on webpages with the Chrome extension or explore your own text in the React app. Powered by TypeSafe Jev.

Screenshot 2026-09-20 at 12 28 10 AM

Features

  • Search by meaning. Ask a question, describe an idea, or type a half-remembered detail.
  • Find the sentence that matters. Bright green highlights the strongest sentence; pale green keeps the surrounding context visible.
  • Stay on the page. Open the Chrome extension on a webpage and jump between matching passages.
  • Explore your own text. Paste an article, policy, or document into the React app, or start with one of the included examples.
  • Read the original source. Results point to existing text, with a relevance ranking and a copy button in the React app.

How It Works

  1. The extension extracts readable passages from the current webpage. The React app uses the selected document or pasted text.
  2. Your query and those passages go to the local Needle backend.
  3. TypeSafe Jev scores each passage for relevance and selects its strongest sentence in one evaluation request.
  4. Needle maps the result back to the original text so you can read it in context.

The backend accesses typesafe-ai/jev through Vercel AI Gateway's evaluation API. Jev selects source sentences rather than generating an answer. Results with relevance scores of at least 0.58 are included; this is a ranking threshold, not a guarantee that every relevant passage was found.

How to Get Started

Requires Node.js 22.12+, npm, and a Vercel AI Gateway account with access to typesafe-ai/jev and sufficient credits. Obtain an AI Gateway API key from the Vercel AI Gateway dashboard. An OpenAI key or a direct TypeSafe key is not a substitute for this endpoint.

git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/advanced_llm_apps/needle
npm ci
cp .env.example .env

On Windows PowerShell, use Copy-Item .env.example .env instead of cp.

Open .env in your editor and fill in:

AI_GATEWAY_API_KEY=your_vercel_ai_gateway_key

Run the App

Start the React app and its backend:

npm run dev

Open http://127.0.0.1:4199 in your browser. This starts the UI and backend together and creates a downloadable extension ZIP. Keep the terminal running while using the extension. .env is loaded at server startup; restart after changing it. The local server binds only to your computer’s loopback interface.

Never put the Gateway key in the extension, a VITE_ environment variable, a screenshot, or a committed file. .env is ignored by Git. The optional AI_GATEWAY_KEY_FILE setting can read an existing local key file instead; ordinary users only need .env.

Install the Chrome Extension

The extension is included in this repository. Install it directly in Chrome using Developer mode.

No separate extension build is needed to load the source:

  1. Open chrome://extensions in Chrome and enable Developer mode.
  2. Choose Load unpacked and select awesome-llm-apps/advanced_llm_apps/needle/extension/ folder. This is the folder containing manifest.json. Do not select the repository root or a ZIP file.
  3. Pin Needle from Chrome’s puzzle-piece menu. The settings page opens on first installation; you can also right-click the icon and choose Options.
  4. Set Needle server URL to http://127.0.0.1:4199. Leave Server access token blank for the default local setup. Click Save connection.
  5. Open a normal webpage and click the Needle icon, or press Cmd+F on macOS / Ctrl+F elsewhere. Type what you want to find.

If the shortcut is already in use, assign one at chrome://extensions/shortcuts.

ZIP installation: use Get the extension in the running playground, or run npm run package:extension. Unzip the package into a permanent folder and choose that folder in Load unpacked. Downloading or double-clicking a ZIP does not install it automatically. This follows Chrome’s unpacked extension installation flow.

Updates: pull the new source (or replace the extracted ZIP files), click Reload on Needle’s card in chrome://extensions, then refresh the webpage before reopening Needle. Keep the same extension folder to retain settings.

How to Use Needle

On a webpage

Keep npm run dev running, open the webpage you want to search, and click the pinned Needle icon. Type what you mean, such as “costs beyond the advertised price” or “what happens if I cancel?” Needle searches after a short pause and highlights relevant source sentences.

In the React app

Open http://127.0.0.1:4199, choose a document from the library, and type your query. To search your own content, open the library with the top-left toggle if it is hidden, choose Bring your own text, enter a title and the text, then select Start exploring. Click a result to jump to its source.

PDFs

Needle currently searches webpage text. Chrome's built-in PDF viewer renders PDFs inside a separate browser viewer, so Needle's page script cannot read and highlight the PDF text as ordinary webpage elements. Enabling file access does not add PDF support.

For a PDF with selectable text, copy the relevant text and use Bring your own text in the React app. Scanned PDFs need text extraction with OCR first. Direct PDF upload and highlights inside the PDF viewer are not implemented.

Troubleshooting

What you see What to do
Cannot reach Needle Start npm run dev and use http://127.0.0.1:4199 as the extension's server URL. Keep that terminal running.
API key or credits error Check AI_GATEWAY_API_KEY in .env, your Gateway account's model access and credits, then restart the server.
Chrome cannot find the manifest Choose the extension/ folder containing manifest.json. If using the download, unzip it first.
Changes do not appear Reload Needle at chrome://extensions, then refresh the webpage.
No searchable text Try a regular webpage. Built-in PDF viewers, browser settings pages, images and scanned text are unsupported.

API Key and Connection Settings

Setting Where to put it Purpose
AI_GATEWAY_API_KEY Backend .env, or Vercel project environment variables Pays for and authenticates Jev inference; never goes into the extension
NEEDLE_ACCESS_TOKEN Backend environment, then the same value in extension settings Protects access to your backend; required on Vercel, optional locally
Needle server URL Extension settings Your local backend or your own HTTPS deployment

For the web playground on a protected backend, enter the access token in How it works → Server access token. This is a separate app-specific token, not the Gateway key. Whoever owns the backend’s Gateway key pays for its searches.

Optional: Deploy to Vercel

  1. Import your fork into Vercel. Set Root Directory to advanced_llm_apps/needle and Framework Preset to Vite. The included vercel.json specifies the build output and API function duration.

  2. Add AI_GATEWAY_API_KEY and a randomly generated NEEDLE_ACCESS_TOKEN to the project’s environment variables. For example, generate the access token with:

    node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"
  3. Deploy. In extension settings, use your deployment’s HTTPS origin and the access token. Allow access to that server when Chrome prompts you.

  4. Test a real search. /api/health confirms whether a key is configured; it does not validate the key or account credits.

The backend refuses search requests on Vercel if NEEDLE_ACCESS_TOKEN is missing. Use the token only for your own installation or a small trusted group. A general public service needs individual user authentication, rate limits, quotas and a billing decision; this template does not implement those. If Vercel Deployment Protection is enabled, the extension cannot complete its browser-login challenge. Use a backend reachable by the extension and retain Needle’s token check.

Project Structure

needle/
|-- src/                  React app, components, styles and example documents
|-- extension/            Chrome extension, settings, manifest and icons
|-- server/               Local server, Jev requests and sentence mapping
|-- api/                  Vercel API functions
|-- public/               App assets and generated extension download
|-- scripts/              Extension ZIP packaging
|-- tests/                Search, sentence, access and packaging checks
|-- .env.example          API key and optional settings
`-- README.md

Data Handling and Limits

  • Search sends all captured passages plus your query, not just the highlighted result, to the configured backend and AI Gateway. Use it only on pages you are comfortable sending to those services.
  • The extension runs when you invoke it, rather than monitoring every page. It selects rendered paragraph/list/heading-style elements. It does not collect password/input values, browsing history, cookies, or screenshots. Text embedded within selected page elements is part of the capture.
  • The backend does not intentionally persist or log page text. Hosting and model-provider policies still apply. The playground keeps up to 25 results in tab memory, and a protected-backend token in session storage. The extension stores its server URL and app access token in Chrome local storage.
  • Up to 160 passages / 60,000 characters, with at most 2,200 characters per passage. The extension skips oversized passages and reports omissions. Very long pages may only be partially searched. Pasted text is split into bounded passages.
  • Chrome system pages, the Chrome Web Store, built-in PDF viewers, scanned text, cross-origin frames and shadow-root content are unsupported. Dynamic page changes may invalidate results; search again.
  • Jev access/credit errors appear explicitly. There are no fabricated fallback matches.

Development

npm test
npm run format:check
npm run build
npm run preview

Stop the dev server before running preview on the same port, or choose another PORT in .env. Preview serves the production build and the real local backend.

npm run package:extension produces:

  • artifacts/needle-extension-v1.1.1.zip for release attachment.
  • public/needle-extension.zip for the app’s download link; production builds copy it to dist/.

ZIP packaging uses an explicit file allowlist and does not include the backend, .env, dependencies or development output. Build artifacts are not committed.

Before sharing a package, load it in Chrome and check the connection, search, highlights and navigation. Automated tests do not cover Chrome’s installation and permission prompts.

Licensed under the repository’s Apache-2.0 license.