Liwan - Project Overview
Liwan is an open-source, self-hosted web analytics platform designed for privacy-conscious developers and organizations.
Written in Rust and using modern web technologies, Liwan provides real-time insights without compromising user privacy.
- Description: Easy setup with a single binary and sub-1KB tracking script.
- Key Features: Quick setup, privacy-first, lightweight, real-time analytics, bot filtering.
- Modules: Backend API & CLI, web dashboard, tracker script, utility scripts, migrations, and test suite.
- Languages & Technologies: Rust (backend), TypeScript/JavaScript & Astro (frontend), Bash (scripts), SQL (DuckDB/SQLite migrations).
- Dependencies: Tokio, Poem, DuckDB, SQLite, Astro, React, D3, Bun.
- Configuration & Environment: liwan.config.toml, environment variables (LIWAN_CONFIG,LIWAN_DATA_DIR), Docker support.
- Static Code Analysis: Strict typing in Rust and TypeScript, migration tests via Refinery, unit & integration tests in tests/andweb/src.
Why This Matters 🚀
Self-hosting analytics empowers you with full control over your data, improves performance with a lightweight setup, and aligns with privacy regulations by avoiding third-party tracking.
And additionally, with Liwan we get:
- Quickly get started with Liwan with a single, self-contained binary .
No database or complex setup required.
The tracking script is a single line of code that works with any website and less than 1KB in size.
- Privacy first
Liwan respects your users’ privacy by default. No cookies, no cross-site tracking, no persistent identifiers. All data is stored on your server.
Module Descriptions
- Backend (src/): Core application logic including event processing, geoIP lookup, session management, and REST API built with Poem.
- Database Migrations (src/migrations/): SQL migrations managed by Refinery for DuckDB and SQLite schemas.
- Utilities (src/utils/): Helpers for hashing, geo lookup, referrer parsing, compression, and user-agent detection.
- Web API & Server (src/web/): API routes for admin, authentication, dashboard data, and event ingestion; also embeds the frontend assets.
- Web Frontend (web/): Astro-based dashboard with React components, D3-powered charts, and pages for login, settings, and project views.
- Tracker Script (tracker/): Sub-1KB TypeScript module for sending pageview and custom events to the API.
- Scripts (scripts/): Build, license aggregation, tracker bundling, demo deployment, and Dockerfile for container image.
- Data (data/): Example configuration, GeoIP data, referrer and spammer lists, and asset samples.
- Tests (tests/): Integration tests for authentication, dashboard functionality, and event handling.
Key Concepts and Algorithms
- Event Ingestion: Efficient, asynchronous handling of pageview and custom events using Tokio and channels.
- Bot & Crawler Filtering: User-agent analysis via uaparserand referrer lists to exclude non-human traffic.
- GeoIP Lookup: Optional MaxMind integration or bundled DB for visitor geolocation.
- Query Caching: In-memory caching to reduce database load and speed up dashboard queries.
- Flexible Storage: Dual support for DuckDB and SQLite with connection pooling via r2d2.
- Custom Graph Rendering: Client-side D3 implementation for performant, interactive charts.
Dependencies
- Rust Crates: tokio,poem,poem-openapi,duckdb,rusqlite,refinery,serde,tracing,reqwest,argon2,md-5, and others.
- Frontend: astro,@astrojs/react,react,@tanstack/react-query,d3-array,d3-axis,d3-geo,d3-scale,@radix-ui/react-accordion, and related modules.
- Tracker: Native Fetch API; no external runtime dependencies.
- Build & Deployment: Bash, curl, tar, rsync, Docker.
Liwan Deployment
Liwan can run as a standalone binary or inside a Docker container.
It listens on port 9042 by default and stores data in a local DuckDB or SQLite file.
Deploying with Docker
Use the provided multi-stage Dockerfile (with docker CLI) to quickly get started:
$ docker build -t liwan .
$ docker run -d \
  -p 9042:9042 \
  -e LIWAN_CONFIG=/config/liwan.config.toml \
  -e LIWAN_DATA_DIR=/data \
  -v $(pwd)/liwan.config.toml:/config/liwan.config.toml \
  -v liwan_data:/data \
  liwan
Liwan Docker Compose
If you prefere going the docker compose route to install Liwan:
#sudo docker logs liwan
#docker-compose -f liwan_docker-compose.yml up -d
#version: "3.8"
services:
  liwan:
    image: ghcr.io/explodingcamera/liwan:1.1 
    container_name: liwan #https://github.com/explodingcamera/liwan
    ports:
        - "127.0.0.1:80:9042"
    volumes:
        - liwan-data:/data
    # See https://liwan.dev/reference/configuration for all configuration options
    environment:
        - LIWAN_BASE_URL=http://localhost #https://a.example.com
volumes:
  liwan-data:
As you can see, no database involved. You will need a Proxy though!
sudo docker-compose up -d
#docker-compose -f liwan_docker-compose.yml up -d
 
sudo docker logs liwan
#sudo docker stats liwan
Liwan is really lightweight ~10mb RAM taken!
During the first setup:
 
You will create your admin user/pass:
 
And finally, your Liwan web analytics dashboard:
 
Configuration
Copy the example config and adjust as needed:
# liwan.config.toml
base_url = "http://localhost:9042"
port = 9042
[geoip]
# maxmind_account_id = "YOUR_ID"
# maxmind_license_key = "YOUR_KEY"
[duckdb]
# threads = 2
# memory_limit = "2G"
Conclusion
Liwan offers a compelling, privacy-first alternative to third-party analytics, combining Rust performance with a modern web dashboard.
Its minimal footprint allows it to run on modest hardware, giving you full control over your visitor data.
Self-hosting alternatives include Plausible, Umami, Matomo, GoatCounter, Countly…and the recently covered, Rybbit!
Latest Releases
At the time of writing, I got it working with the following commit, yet Liwan docker container version 1.1!
git log -1 --pretty=format:'%h %s (%ci)'
#9dc8716 chore: always checkpoint before shutdown (2025-05-15 20:55:12 +0200)
git describe --tags --abbrev=0
#liwan-v1.2.0-rc.10
git tag --sort=-v:refname | head -n 5
- Unreleased: Relicensed under Apache-2.0; updated DuckDB to 1.2; refreshed referrer and user-agent lists; UI improvements for long URLs; ARM64 container fixes; performance and memory optimizations.
- v1.1.0 (2024-12-28): Improved query caching; country codes for Google referrers; enhanced multi-user project access.
- v1.0.0 (2024-12-06): UTM parameter support; new date ranges; UI polish; bounce rate and average time metrics; D3-based graphs; optional favicon fetching.
- v0.1.1 (2024-09-24): Performance enhancements via database index optimizations.
- v0.1.0 (2024-09-18): Initial full release with live tracking, GeoIP, user management, filters, core metrics, and a clean UI.