How to Set Up Hister as a Private Search Engine: Complete Self-Hosted Guide
Hister is a self-hosted, Go-based search engine that indexes your local files and browsing history into a private SQLite database, accessible via a Svelte web interface or terminal UI without sending data to external clouds.
Hister, developed by asciimoo/hister, transforms your personal data into a fully searchable knowledge base. Unlike commercial search services, Hister stores everything locally by default—your indexed content never leaves your machine unless you explicitly configure external embedding endpoints.
Download and Install the Binary
Hister distributes pre-built binaries for all major platforms. According to the repository's quick-start documentation, you can get running in seconds without compiling from source.
Download the latest release for your operating system and rename the file to hister (or hister.exe on Windows):
# Linux/macOS example
chmod +x hister
sudo mv hister /usr/local/bin/
On Windows, simply rename the downloaded file to hister.exe and place it in a directory included in your system PATH.
Starting the Hister Server
The config.Config struct in config/config.go (lines 32-66) handles initialization, loading a YAML configuration if present, or falling back to secure defaults.
Launching the Default Configuration
Run the server with a single command:
./hister listen
By default, the server listens on 127.0.0.1:4433 (controlled by DefaultServerAddress in the configuration). The server.Listen function in server/server.go (lines 44-62) initializes the HTTP server, sets up session management, and begins serving the embedded Svelte UI from static.FS.
Verifying the Server is Running
Upon startup, Hister logs its configuration to stdout. The source code in server/server.go (lines 61-63) shows the exact logging output:
log.Info().
Str("Address", cfg.Server.Address).
Str("Version", Version).
Str("URL", cfg.BaseURL("/")).
Msg("Starting webserver")
Open your browser and navigate to http://127.0.0.1:4433 to access the web UI.
Configuring Browser Integration
To index your browsing history in real-time, install the official browser extension:
- Firefox: https://addons.mozilla.org/en-US/firefox/addon/hister/
- Chrome: https://chromewebstore.google.com/detail/hister/cciilamhchpmbdnniabclekddabkifhb
The extension transmits visited page content to Hister's /import endpoint via POST request, where the indexer.Indexer (defined in server/indexer/update.go) processes the HTML, extracts text, and adds it to the search index.
Advanced Configuration Options
For production deployments or specialized use cases, create a YAML configuration file. Hister searches for config files in the paths returned by config.GetConfigSearchPaths (typically ~/.config/hister/config.yml on Linux).
Customizing the Data Directory and Listen Address
The config.CreateDefaultConfig() function generates sensible defaults, but you can override critical settings:
server:
address: "0.0.0.0:8443"
base_url: "https://search.example.com"
app:
directory: "/var/lib/hister"
public: false
All data persists under config.App.Directory in a SQLite file named db.sqlite3 unless you specify a PostgreSQL DSN.
Enabling Semantic Search with Embeddings
Hister supports vector-based semantic search through configurable embedding endpoints. In config/config.go (lines 68-86), the SemanticSearch.Validate method checks your configuration at startup.
Enable semantic search in your config file:
semantic_search:
enable: true
embedding_endpoint: "http://localhost:11434/v1/embeddings"
embedding_model: "qwen3-embedding:8b"
This integrates with Ollama or any OpenAI-compatible embedding service running locally.
Setting Up Multi-User Access and Public Mode
The configuration validates public mode settings in config/config.go (lines 91-99). To require authentication for access, enable app.public and configure OAuth or access tokens:
app:
public: true
user_handling: "oauth"
When public: false (default), Hister operates in single-user mode with CSRF protection and secure cookie handling managed by an auto-generated .secret_key file created during Config.init.
Importing Local Files via CLI
Beyond browser history, index local documents using the command-line client. The cmd/import_file.go implementation shares the same code path as the web upload interface:
hister import file ./documents/report.pdf \
--label "work" \
--skip-existing
For programmatic access, query the search index directly:
curl -s "http://127.0.0.1:4433/search?q=project+deadline" | jq .
Or use the terminal UI with hister tui for an interactive search experience.
Summary
- Hister stores all indexed data locally in SQLite by default, located in
~/.config/hister/or your configuredapp.directory. - The HTTP server (
server.Listen) serves a Svelte web UI on port 4433 by default, with session management and CSRF protection. - Browser extensions automatically push visited pages to the
/importendpoint for real-time indexing. - Configure semantic search by pointing to a local Ollama or compatible embedding endpoint in the YAML config.
- Use
hister importto index local files, andhister searchfor CLI-based queries that return JSON.
Frequently Asked Questions
Where does Hister store my indexed data?
Hister persists all data in the directory specified by config.App.Directory, defaulting to OS-standard config paths (e.g., ~/.config/hister on Linux). The primary storage is a SQLite database file named db.sqlite3, though you can configure a PostgreSQL connection string instead. No data is transmitted to external services unless you explicitly enable semantic search with a third-party embedding endpoint.
Can I run Hister on a VPS with a custom domain?
Yes. Modify the server.address to bind to 0.0.0.0:PORT and set server.base_url to your public URL in the configuration YAML. The server parses static Svelte assets at runtime to inject the dynamic base path, allowing the UI to function correctly behind reverse proxies or on custom subdomains without recompiling the frontend.
Does Hister support semantic search without cloud APIs?
Absolutely. The SemanticSearch configuration accepts any OpenAI-compatible embedding endpoint. By running Ollama locally (http://localhost:11434/v1/embeddings), you can generate vector embeddings entirely offline. The indexer.Indexer handles language detection and embedding generation without transmitting your indexed content to proprietary cloud services.
How do I back up my Hister search index?
Since Hister uses file-based storage by default, simply back up the entire app.directory (containing db.sqlite3 and .secret_key). For SQLite specifically, you can also use standard database backup tools: sqlite3 db.sqlite3 ".backup to backup.sqlite3". The configuration file and secret key must be preserved together to maintain session integrity and user authentication.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →