# 1History copies your browser history into one SQLite file and serves a web UI over it

> 1History is a Rust binary that imports history from Chrome, Firefox and Safari into a local SQLite database and exposes it through a browser interface for search, charts and manual backup triggers. It suits someone who wants their browsing record in a portable file they control, and it depends on a browser's history database being readable at the moment the backup runs.

**localfirstapp/1History** — All your history in one file.

- Repository: https://github.com/localfirstapp/1History
- Stars: 556 · Forks: 27
- Language: JavaScript
- License: GPL-3.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/localfirstapp-1history

## The product is a single file plus a local web server

The pitch is one sentence: All your history in one file. 1History backs up your browser history into a single local file and lets you explore it through a modern web UI, with search, visualization and management, and no extra CLI commands needed after the initial setup.

That last clause is the design decision. The tool is not only a command line backup utility. The command line exists for the first backup and for scripting, and everything else is meant to happen in a browser.

The interfaces are listed in the README. The dashboard at / gives KPI cards, a daily page view chart, and top pages and domains. Search at / does keyword search across all history with instant filtering. The database page at /db lets you trigger new backups, monitor progress and view import history.

The data itself lands in a SQLite database, and the Cargo.toml shows the default path is ~/onehistory.db, overridable with the -d flag or the OH_DB_FILE environment variable. The dependencies explain the shape of the implementation: rusqlite with the bundled feature for the database, clap for the command line, warp and tokio for the HTTP server, serde for serialization, minijinja for templating, csv for the export, and rust-embed, which is how the web interface is shipped inside the binary rather than as files you have to deploy.

That last point is what makes the tool a single binary. The frontend build output is embedded at compile time, so there is no static directory to serve and nothing to install alongside it.

## Which browsers it reads, and the three file names that matter

Auto-detection covers all major browsers, and the README gives the file names that detection looks for.

| Browser | History file    |
|---------|-----------------|
| Chrome  | `History`       |
| Firefox | `places.sqlite` |
| Safari  | `History.db`    |

The feature list claims support for Chrome, Firefox and Safari on macOS, Linux and Windows, and the Cargo.toml includes the home crate for locating profile directories, which is what makes cross-platform path resolution possible.

Detection is not always sufficient. The backup command has a -f flag for SQLite file paths of different browsers, given as History.db or places.sqlite style paths, and a -d flag to disable auto detect history files. The README gives the reason for the combination in a comment: it skips auto-detect, which is useful when browsers are open.

That comment is the important part, and the FAQ makes it explicit. A browser that is running holds a lock on its history database, and a backup that tries to read it directly fails with Error code 5: The database file is locked. The documented remedies are to close the browser first, or to use -d -f to point at a copy of the history file outside the browser's profile directory.

So the honest description of the tool is that it reads databases that browsers own, and browsers do not always let you read them while they are running.

## Installing the binary and taking the first backup

On Linux and macOS there is an install script that downloads a prebuilt binary from GitHub Releases and installs it to ~/.local/bin.

```bash
curl -fsSL https://raw.githubusercontent.com/localfirstapp/1History/main/install.sh | sh
```

The script takes options after the pipe using sh -s --, which covers pinning a version, choosing a prefix, and using a mirror.

```bash
# Install a specific version
curl -fsSL https://raw.githubusercontent.com/localfirstapp/1History/main/install.sh | sh -s -- --version v0.4.0

# Install to a custom directory
curl -fsSL https://raw.githubusercontent.com/localfirstapp/1History/main/install.sh | sh -s -- --prefix /usr/local/bin

# Use a mirror for users in China
curl -fsSL https://raw.githubusercontent.com/localfirstapp/1History/main/install.sh | sh -s -- --china
```

There is a Cargo path as well, for anyone who would rather build or install through the package manager.

```bash
cargo install onehistory
```

Then the first backup, which auto-detects the supported browsers.

```bash
onehistory backup
```

And then the server, which you open at the loopback address.

```bash
# Start the web UI
onehistory serve
# Open http://127.0.0.1:9960
```

The port 9960 is the one to remember, and it is also the port the frontend dev server proxies to during development. The server binds the loopback interface rather than a public address, so the UI is not reachable from other machines by default.

The backup command also has a -D dry-run option that previews what would be imported without writing to the database. Running that first is the cheapest way to find out whether detection finds your browsers at all.

## The CLI is small on purpose, and export is there for the exit

The README states plainly that the CLI is only needed for the initial setup and for scripting and automation use cases, and the command list is short enough to read in one go.

```text
Usage: onehistory [OPTIONS] <COMMAND>

Commands:
  backup  Backup browser history to 1History
  serve   Start HTTP server to visualize history
  show    Show default history files on your computer
  export  Export history to CSV file
  help    Print this message or the help of the given subcommand(s)

Options:
  -d, --db-file <DB_FILE>  Database path [env: OH_DB_FILE=] [default: ~/onehistory.db]
  -v, --verbose            Enable verbose logging
  -h, --help               Print help
  -V, --version            Print version
```

Two commands deserve comment. The show subcommand lists the default history files on your computer, which is the diagnostic you want when detection finds nothing, and it avoids the guesswork of hunting through profile directories by hand. The export subcommand writes the history to a CSV file, which is the escape hatch: whatever you think of the web interface, the data can leave as a flat file and be loaded into a spreadsheet or a notebook.

The dependency list backs this up. The csv crate is there for the export, glob for locating history files, regex for the search, chrono for timestamps, indicatif for the progress bar during a long import, and tempfile plus uuid for the working copies the importer makes.

Verbose logging is a global flag rather than a per-command one, so -v works with any subcommand when you need to see which file it decided to import.

## Building it yourself means building the frontend first

The development setup has a prerequisite ordering that catches people out. The frontend must be built before cargo build, because its output is embedded into the binary.

The prerequisites are Rust on stable, a rust-toolchain.toml to pin the version, and Node.js 18 or newer.

```bash
git clone https://github.com/localfirstapp/1History
cd 1History
cd frontend && npm install && cd ..
```

And then the build, in the order that matters.

```bash
cd frontend && npm run build && cd ..
cargo build
```

The Makefile collapses that into one target.

```bash
make serve
```

For day-to-day work there is a hot reload path with two terminals. The Rust server runs in one, and the Vite dev server runs in the other, proxying API calls to port 9960.

```bash
cargo run -- serve

cd frontend && npm run dev
# Open http://localhost:5173
```

The test targets are conventional for Rust, with formatting and lint checks alongside the test run.

```bash
cargo test
cargo clippy --all-targets --all-features
cargo fmt -- --check
```

One thing to notice in the repository layout is the frontend/ directory and the static/ directory sitting side by side, with the src/ directory for the Rust side. The Makefile also carries a release-arm64 target that calls a release-arm64.sh script, and a publish target that runs cargo publish against the GitHub registry with CARGO_REGISTRY_TOKEN, so the binary is distributed both as a release asset and as a crates.io package.

## Release pace, licence, and where this stops being the right tool

The release history is compressed into a few days. Version 0.4.1 was released on 2026-04-26, 0.4.0 on 2026-04-25 and 0.3.5 on 2026-04-24, and the last push to the repository was on 2026-04-26. The repository is not archived, but the cadence suggests a young project in a burst of development rather than a settled tool.

The licence is GPL-3.0, and the copyright line reads Copyright (c) 2022 Jiacai Liu. For a local personal tool that never leaves your machine, GPL-3.0 is mostly irrelevant. It matters if you distribute the binary or bundle it into a product, because the copyleft obligations attach to derivative works.

The more interesting limits are technical. The tool reads the browsers' own databases, so it inherits their locking behaviour and their schema expectations, and the README does not document support for browser profile encryption or for browsers that store history somewhere else entirely. It backs up on demand rather than continuously, which means the history between the last backup and the present is not captured anywhere. And the database is a growing SQLite file on your disk with no documented retention or pruning policy in the README, so on a machine with years of browsing history it will get large.

The alternative in the same direction is to keep using the browsers' own history search, which is free and always current, or to move to an account-based browser history service, which costs a subscription and puts your history on someone else's server. 1History wins on control and offline access and loses on coverage, since it can only show what it managed to import.

## Conclusion

1History fits a person who wants their browsing history in one file they can back up, search and read through a browser rather than a text query, and it suits a machine where the browser profile directory is readable. It does not fit a shared or managed workstation where the history database is locked or profile access is restricted, and it does not fit a workflow that needs continuous capture, since backups are triggered manually or on a schedule you set up. Before relying on it, run `onehistory backup --dry-run` to see what the importer finds on your machine, and read the locked-database note in the FAQ, because that error is the most common reason a first backup does not complete.

## FAQ

### What does 1History do with my browser history?

It backs up your browser history into a single local file, a SQLite database at ~/onehistory.db by default, and serves a web UI over it for search, visualization and manual backup triggers. It runs entirely offline with no cloud component.

### How do I install 1History on Linux or macOS?

Run the install script, which downloads a prebuilt binary from GitHub Releases and installs it to ~/.local/bin, or use `cargo install onehistory`. The script accepts `--version`, `--prefix` and `--china` options after `sh -s --`.

### Why does my backup fail with Error code 5: The database file is locked?

This happens when your browser is open during the backup. Either close the browser first, or use `-d -f` to point at a copy of the history file outside the browser's profile directory.

### Which browsers and platforms does 1History support?

The README lists Chrome, Firefox and Safari on macOS, Linux and Windows. Auto-detection looks for the Chrome History file, the Firefox places.sqlite file and the Safari History.db file, and the -f flag lets you point at non-standard locations.

### What licence is 1History released under?

GPL-3.0, with the copyright held by Jiacai Liu and the LICENSE file at the repository root. The Cargo.toml lists the same licence for the onehistory package.

## Sources

- [Issues](https://github.com/localfirstapp/1History/issues)
- [License: GPL-3.0](https://github.com/localfirstapp/1History/blob/main/LICENSE)
- [localfirstapp/1History on GitHub](https://github.com/localfirstapp/1History)
- [README](https://github.com/localfirstapp/1History/blob/main/README.md)
- [Releases](https://github.com/localfirstapp/1History/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/localfirstapp-1history
