A self-hosted link archival tool
  • Go 77%
  • Vue 16.5%
  • TypeScript 3%
  • HTML 1.6%
  • CSS 0.9%
  • Other 1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Felipe M 70b0896183
All checks were successful
CI / goreleaser-lint (push) Successful in 11s
CI / format (push) Successful in 44s
CI / lint (push) Successful in 5m30s
CI / test (push) Successful in 7m24s
CI / build (push) Successful in 7m8s
Release / release (push) Successful in 7m28s
CI / e2e (push) Successful in 26m54s
deps: upgrade dependencies and add a JS runtime for yt-dlp (#3)
Upgrades every dependency in the code and the packaging, and adds a JS runtime to the container image so yt-dlp can solve YouTube JS challenges.

## Code

- **Go server:** `modernc.org/sqlite` 1.59.0 → 1.60.1, `modernc.org/libc` 1.77.1, `xstrings` 1.6.2, `go-strftime` 1.1.0 (all indirect; no direct module had a newer version).
- **Go e2e:** `moby/moby/api` 1.56.1, `moby/moby/client` 0.6.1, `gopsutil` 4.26.9, `klauspost/compress` 1.20.1.
- **Webapp:** `vite` 8.3.2, `@tabler/icons-vue` 3.48.0, `dompurify` 3.4.16, `eslint-plugin-vue` 10.11.1.
- **TypeScript 5.9.3 → 6.0.3.** Version 6 is now stable and inside the `typescript-eslint` range (`<6.1.0`). TypeScript 7 still breaks `typescript-eslint`.
- `package-lock.json` stays on lockfile format v2 to keep the diff small.

## Packaging and CI

- **Alpine 3.23 → 3.24** in `Containerfile` and `e2e/Dockerfile.e2e`.
- **`docker:27-dind` → `docker:29-dind`** for the e2e CI service.
- **`goreleaser-action` v6.4.0 → v7.2.3**, **`setup-qemu-action` / `setup-buildx-action` v3 → v4**. The only breaking change in their release notes is the Node 24 runtime.
- **`golangci-lint` v2.13.2 → v2.14.0.**

## JS runtime for yt-dlp

yt-dlp solves YouTube JS challenges with `yt-dlp-ejs` and a JS runtime.

- **amd64 and arm64:** the image installs `deno` and `yt-dlp-ejs`.
- **armv7:** Alpine ships no deno for armv7 (3.24 or edge). The image installs `nodejs` and writes `--js-runtimes node` to `/etc/yt-dlp.conf`, because yt-dlp only runs deno unless told otherwise. hako does not pass `--ignore-config`, so the file applies.

## Verification

- `go test -race ./...`, e2e `go vet`, `golangci-lint` v2.14.0 (0 issues).
- `eslint`, `vite build`, `goreleaser check`.
- Built the `Containerfile` for `linux/amd64`, `linux/arm64` and `linux/arm/v7`. `yt-dlp -v` reports `JS runtimes: deno-2.7.4` on amd64/arm64 and `node-24.18.1` on armv7.
- A real YouTube URL on amd64 resolved formats with deno as the JS challenge provider. Not tested on arm64 or armv7.
- The e2e suite was not run locally.

## Known issues

- **Docker 29 dind** is not tested yet. The e2e job starts `containerd` and `dockerd` with a custom command; this PR's CI run will show if it still works.
- **`vue-tsc` reports 9 type errors, all also present on `master`:** the 8 known from #2, plus `process` in `vite.config.ts` (no `@types/node`). TypeScript 5.9.3 gives the same error.

Reviewed-on: #3
2026-10-02 13:10:18 +02:00
.github/workflows deps: upgrade dependencies and add a JS runtime for yt-dlp (#3) 2026-10-02 13:10:18 +02:00
.readme docs: screenshots 2026-01-12 21:18:29 +01:00
cmd/hako feat: enhance build configuration and implement versioning 2026-01-03 13:49:17 +01:00
devdata feat: add server host and interface binding configuration 2026-01-29 12:57:10 +01:00
docs docs: screenshots 2026-01-12 21:18:29 +01:00
e2e deps: upgrade dependencies and add a JS runtime for yt-dlp (#3) 2026-10-02 13:10:18 +02:00
internal fix: archive yt-dlp videos when other assets fail (#4) 2026-10-02 11:46:03 +02:00
scripts ci: migrate from Woodpecker CI to Forgejo Actions (#1) 2026-09-22 17:33:29 +02:00
webapp deps: upgrade dependencies and add a JS runtime for yt-dlp (#3) 2026-10-02 13:10:18 +02:00
.dockerignore ci: migrate from Woodpecker CI to Forgejo Actions (#1) 2026-09-22 17:33:29 +02:00
.gitignore chore: add default config file for development 2026-01-29 12:52:15 +01:00
.golangci.yaml feat: search 2026-01-18 09:51:25 +01:00
.goreleaser.yml ci: migrate from Woodpecker CI to Forgejo Actions (#1) 2026-09-22 17:33:29 +02:00
Containerfile deps: upgrade dependencies and add a JS runtime for yt-dlp (#3) 2026-10-02 13:10:18 +02:00
docker-compose.yml ci: copy the release binary from its per-platform context path 2026-09-22 21:33:38 +02:00
go.mod deps: upgrade dependencies and add a JS runtime for yt-dlp (#3) 2026-10-02 13:10:18 +02:00
go.sum deps: upgrade dependencies and add a JS runtime for yt-dlp (#3) 2026-10-02 13:10:18 +02:00
LICENSE initial boilerplate 2026-01-03 11:43:21 +01:00
Makefile deps: upgrade dependencies and add a JS runtime for yt-dlp (#3) 2026-10-02 13:10:18 +02:00
README.md feat(e2e): add HTML report generation with embedded screenshots 2026-01-18 18:45:09 +01:00

Hako

Hako is a self-hosted link archival service that automatically saves and preserves web content. Save URLs and let Hako archive them using multiple archival methods, extract content for full-text search, and organize your saved links with categories.

Features

  • Link Archival: Save URLs and automatically archive web content.
  • Multiple Archivers: Support for different archival methods depending on the site or content type.
  • Content Extraction: Extract text content from PDFs and web pages for full-text search
  • Rule Engine: Configurable rules that automatically select appropriate archivers based on URL patterns, hostnames, and content types
  • Categories: Organize links in categories.
  • Archive History: Track multiple archive versions for each link if archived multiple times.
  • Full-Text Search: Search through archived content.
  • Self-Hosted: Full control over your archived data

Tech stack

  • Go
  • Vue 3
  • Bun

Screenshots

See docs/screenshots.

Running the Application

This project uses a Makefile for common tasks. Run make help to see all available commands.

Backend

To build and run the backend:

# Build the webapp (required for embedded frontend)
make build-webapp

# Run the server only (without building webapp)
make run-server

Frontend

The frontend is built with Vue.js and Vite, using Bun as the package manager:

# Run the webapp in development mode with hot-reload
make run-webapp

# Build the webapp for production
make build-webapp

Docker

Running with Docker Compose

To run Hako locally using Docker Compose:

# Build the docker binaries
make build-docker

# Start the container
docker compose up

# Or run in detached mode
docker compose up -d

The service will be available at http://localhost:8080.

Building Docker Images

To build Docker images using goreleaser (for production builds):

# Build Docker image locally (creates multi-arch images)
make build-docker

This will build Docker images for multiple architectures (amd64, arm64, armv7) using goreleaser.

Development

Development Commands

Common development tasks:

# Run linting (server and webapp)
make lint

# Run test suite
make test

# Run integration tests
make e2e

# Format code
make format

# Clean build artifacts
make clean

# Clear dev data (keeps config.yaml)
make clean-devdata

Run make help to see all available commands.