Where engines live
Custom engines live in data/engines/ (or
DEGOOG_ENGINES_DIR). Each engine is a file or folder with
an entry file that exports an object or class with
name and executeSearch.
Engine contract
Required:
- name — Display name in Settings → Engines.
-
executeSearch(query, page?, timeFilter?, context)
(async) — Return a Promise of an array of results. Each result is an
object with
title,url,snippet,source, and optionalthumbnail,duration. Thecontextargument providescontext.fetch; use it for all outbound HTTP requests so the engine respects the user’s proxy (Settings → General).
Optional:
-
bangShortcut — Enables
!shortcut queryto search this engine only (e.g.bangShortcut: "ecosia"→!ecosia linux). -
settingsSchema,
configure(settings) — Same as plugins. Configure
button in Settings → Engines; values in
data/plugin-settings.json.
SettingField shape: key, label,
type (text, password, url, toggle, textarea, select,
urllist), and optional required,
placeholder, description,
secret, options (for select).
Search types
Export a named type: "web" (default),
"images", "videos", "news", or
a custom string (e.g. "books"). A custom type creates a
new tab on the search results page; when selected, all engines with
that type run.
Proxies
When users enable a proxy for search, engine requests can go through it. For your engine to work with the proxy:
-
Use
context.fetchfor every outbound HTTP request (not globalfetch). -
Export outgoingHosts — array of hostname strings
(no protocol or path). Those hostnames are added to the proxy
allowlist. Use
["*"]only if the engine fetches from arbitrary user-configured URLs.
export const outgoingHosts = ["www.example.com", "example.com"];
export default class MyEngine {
name = "My Search";
async executeSearch(query, page = 1, _timeFilter, context) {
const url = `https://www.example.com/search?q=${encodeURIComponent(query)}`;
const doFetch = context?.fetch ?? fetch;
const response = await doFetch(url, { headers: { "User-Agent": "my-engine/1.0" } });
const html = await response.text();
// parse and return array of { title, url, snippet, source, ... }
}
}
Setup
Create data/engines/ (or set
DEGOOG_ENGINES_DIR). Add a single file (e.g.
my-engine.js) or a folder with index.js (or
.ts, .mjs, .cjs). The engine id is the filename or folder name with an
engine- prefix (e.g. ecosia/index.js →
engine-ecosia).
How settings work
-
Declare
settingsSchema— Configure appears in Settings → Engines. -
User saves; values stored in
data/plugin-settings.json. -
configure(settings)is called after save and on restart if settings exist. -
Return an empty array from
executeSearchwhen required settings are missing.
Examples from the official store
-
Ecosia
— web engine with
outgoingHosts,bangShortcut, usescontext.fetch. - Startpage — web engine with optional Anonymous View settings.
- Internet Archive — file-type engine; can be used as a dependency by the File tab plugin.
When distributing via the Store, add a
screenshots/ folder in the engine folder for the Store
card.