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:

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 configured app.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 /import endpoint for real-time indexing.
  • Configure semantic search by pointing to a local Ollama or compatible embedding endpoint in the YAML config.
  • Use hister import to index local files, and hister search for 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →