Glance: self-hosted dashboard for feeds and services
What Glance is
Glance is a self-hosted dashboard that pulls the feeds and status information a developer or homelab owner checks every day into a single page. The project describes itself as a lightweight, highly customizable dashboard that displays your feeds in a streamlined interface, and the widget list makes the intent concrete: RSS feeds, subreddit posts, Hacker News and Lobsters, YouTube channel uploads, Twitch channels, market prices, weather forecasts, GitHub releases, Docker container status, server stats and DNS-blocker statistics, plus several ways to build custom widgets.
The audience is anyone who has a browser tab per source today and would rather open one page. That includes developers who follow a handful of release feeds and newsletters, people running a home server who want a status board for their services, and small teams who want a shared start page with links, monitors and a search bar. Glance is written in Go, ships as a single binary or a small Docker image, and is configured entirely through YAML files rather than a database or a web admin panel.
The project's own framing emphasises restraint. The README lists low memory usage, few dependencies, minimal vanilla JavaScript and a single binary under 20 MB as features, and the contributing guidelines ask contributors to avoid new dependencies and avoid backwards-incompatible configuration changes, and state plainly that there is no package.json. That philosophy shapes most of the trade-offs described below.
How it works
Glance is a server-rendered application. When a page is requested, the server fetches the data each widget needs (an RSS feed, the Hacker News front page, a GitHub releases endpoint, the Docker socket), renders HTML and returns it. The README's FAQ is explicit that nothing happens in the background: no requests are made periodically, information is only fetched when the page is loaded and is then cached. Each widget has its own default cache lifetime, which can be overridden with a shared cache property (for example cache: 12h on an RSS widget or cache: 1m on a monitor).
A consequence of this design is that pages do not update themselves. The FAQ says a page refresh is required to update the information, with exceptions only where it makes sense, such as the clock widget and relative timestamps. Uncached pages, according to the README, usually load within about a second, depending on connection speed and how many widgets are on the page.
Pages, columns and widgets
The configuration model has three levels. A config file defines one or more pages, which become tabs in the navigation. Each page has up to three columns, and each column holds a list of widgets. Columns come in two sizes: a small column has a fixed width of 300px and a full column takes the remaining width. The configuration docs state that a page can have up to three columns and must have either one or two full columns, so layouts such as small-full-small, full-small and full-full are all valid.
Widgets share a handful of common properties (type, title, title-url, hide-header, cache and css-class) and then add their own options. A group widget stacks several widgets behind tabs in one slot, and a split-column widget lets a full column hold widgets side by side.
Configuration loading
Configuration is read from YAML and supports several conveniences that matter once a dashboard grows beyond a single file:
- Auto reload. Changes to the config file take effect on save without restarting the process. If a saved change is invalid, Glance logs the error and keeps running with the previous configuration; an invalid config at startup makes it exit. Changing environment variables still needs a restart.
- Environment variables. Any value can reference
${ENV_VAR}, including numbers and parts of URLs. A missing variable is treated as an error. A backslash escapes the syntax when a literal is needed. - Secrets.
${secret:github_token}reads a Docker secret from/run/secrets/, and${readFileFromEnv:TOKEN_FILE}reads a file whose path is held in an environment variable. - Includes. A
$includedirective pulls another YAML file into place at the correct indentation, so pages or individual widgets can live in separate files. Included files are watched for changes too.
Because includes are resolved before YAML parsing, line numbers in parse errors can be wrong. The docs recommend printing the fully resolved config with the built-in command:
glance --config /path/to/glance.yml config:print | less -N
Key features
- Feed widgets. RSS (with list, card and detailed styles, per-feed limits and custom headers), Videos for YouTube channels and playlists, Hacker News, Lobsters, Reddit and Twitch channels and top games.
- Releases widget. Shows the latest releases for repositories on GitHub, GitLab, Codeberg or Docker Hub, using prefixes such as
gitlab:,codeberg:anddockerhub:. A GitHub token can be supplied to avoid the unauthenticated limit of 60 requests per hour. - Repository widget. Displays details of a single GitHub repository, again with an optional token.
- Monitor widget. Sends a GET request to each listed URL and marks the site as up when the response is 200, showing the response time in milliseconds.
- Docker Containers widget. Lists containers with icons, links and descriptions, configured through
glance.*labels on each container or through acontainersmap in the Glance config. - DNS Stats widget. Reads statistics from AdGuard Home, Pi-hole or Technitium.
- Server Stats widget. Shows CPU, memory and disk usage for the local machine, or for remote machines running the separate Glance Agent.
- Search widget. A search bar with a configurable engine and custom "bangs" such as
!ytthat redirect to a site-specific search URL, with keyboard shortcuts to focus and submit. - Productivity widgets. Bookmarks, a calendar, a clock with multiple time zones, a ChangeDetection.io widget, a weather widget, a markets widget and a to-do list.
- Custom widgets.
iframeembeds another site,htmlinserts static HTML,extensionfetches HTML from a URL you run, andcustom-apifetches JSON and renders it through a Go template. - Theming and branding. Themes are defined with a few HSL numbers (background, primary, positive and negative colours plus contrast and saturation multipliers), presets can be offered in a theme picker, and a custom CSS file can be loaded. Branding options can replace the logo, favicon, footer and the app name used when the dashboard is installed as a web app.
- Icons. Widgets that accept icons can use URLs or prefixed names from Simple Icons (
si:), selfh.st icons (sh:), Dashboard Icons (di:) and Material Design Icons (mdi:). - Mobile layout. The README calls out a layout optimised for phones, with an optional mobile header per page.
Getting started
The README recommends Docker Compose with a template directory. This command creates a glance directory containing a compose file and starter config:
mkdir glance && cd glance && curl -sL https://github.com/glanceapp/docker-compose-template/archive/refs/heads/main.tar.gz | tar -xzf - --strip-components 2
The template contains docker-compose.yml (port and volumes), config/home.yml (the home page widgets), config/glance.yml (theme and extra pages), a .env file for variables referenced in the config and assets/user.css for custom CSS. Once edited, start it and check the logs if something is off:
docker compose up -d
docker compose logs
A manual Compose setup is also documented. The minimal service definition from the README is:
services:
glance:
container_name: glance
image: glanceapp/glance
restart: unless-stopped
volumes:
- ./config:/app/config
ports:
- 8080:8080
The dashboard is then served on port 8080. For a bare-metal install, precompiled binaries are published for Linux, Windows and macOS on x86, x86_64, ARM and ARM64. By default the binary looks for glance.yml in its own directory; a different path can be passed with --config:
/opt/glance/glance --config /etc/glance.yml
Third-party install channels listed in the README include a Proxmox VE helper script, a NixOS package, Hostinger and Coolify. To build from source, the README requires Go 1.23 or newer:
go build -o build/glance .
Adding authentication
Glance has built-in username and password authentication configured through a top-level auth block with a secret-key and a map of users. The secret key should be generated with the CLI:
docker run --rm glanceapp/glance secret:make
Passwords can be stored as bcrypt hashes instead of plain text by using password-hash in place of password:
docker run --rm glanceapp/glance password:hash mysecretpassword
Glance blocks an IP address after five failed logins within five minutes. Behind a reverse proxy such as nginx, Traefik or Nginx Proxy Manager, the docs say to set proxied: true under server so the real client address is taken from X-Forwarded-For; otherwise every request appears to come from the proxy.
Use cases
- A developer start page. Combine Hacker News, Lobsters, a few engineering blogs over RSS, the releases of the libraries a project depends on and a search widget with bangs for documentation sites.
- A homelab status board. Use the Monitor widget for service health, Docker Containers for what is running, Server Stats for CPU, memory and disk, and DNS Stats for an AdGuard Home or Pi-hole instance.
- Release tracking. A releases widget across GitHub, GitLab, Codeberg and Docker Hub gives a single view of upstream versions for self-hosted apps, which helps when deciding what to upgrade.
- Internal dashboards from APIs. The
custom-apiwidget can call an internal JSON endpoint with custom headers and render counts or lists, which the docs demonstrate with an Immich statistics example. - A shared team page. Authentication with multiple users, bookmarks and monitors make it workable as a lightweight internal portal, provided the team is comfortable editing YAML.
Extending Glance
There are four documented routes to content Glance does not ship with. The iframe and html widgets are the simplest. The custom-api widget fetches JSON from a URL, optionally with headers, and renders it through a template; the docs note that it requires some knowledge of HTML, CSS, the Go template language and Glance-specific helpers, and the separate custom API guide documents those helpers. The extension widget calls an HTTP server you run and inserts the HTML it returns, guided by a few special response headers.
The extensions document is marked as a work in progress, and it warns that the API may change and that extension authors are responsible for maintaining their extensions. HTML from an extension is treated cautiously by default: an allow-potentially-dangerous-html option must be enabled before unsanitised markup is rendered. The default cache for extension widgets is 30 minutes, and the docs suggest a one-second cache while developing so changes appear without restarts. A separate community-widgets repository collects shared configurations.
How it compares
Glance sits in the same space as other self-hosted start pages and homelab dashboards, such as Homepage, Homarr, Dashy and Heimdall. Exact feature differences are best checked against each project's own documentation, but a few design choices distinguish Glance on its own terms. It is configured only through YAML files, with no in-browser editor. It leans on content feeds (RSS, Reddit, Hacker News, YouTube, releases) as much as on service links and status. It fetches data on page load rather than polling in the background. And it keeps its own footprint small, with a single Go binary and minimal client-side JavaScript.
For people who mainly want a grid of service links with status dots, a more link-centric dashboard may feel more direct. For people who want a reading page that also shows the health of their servers, Glance's mix of feeds and infrastructure widgets is the main draw. The fact that the dashboard is plain configuration also means it can be kept in Git and reviewed like any other file.
Things to know before adopting
- Licence. Glance is licensed under AGPL-3.0. Running it unmodified for yourself or a team is straightforward, but if you modify the code and let others use it over a network, the AGPL requires making the modified source available to those users.
- No background refresh. Data is fetched on page load and cached. A dashboard left open on a wall display will not update its feeds until it is reloaded.
- Reloads clear the cache. The docs caution that reloading the config clears cached data, so frequent edits can trigger API rate limits. A cache that survives reloads is described as planned, not current.
- Rate limits and DNS blockers. The README's most common issue is request timeouts caused by Pi-hole, AdGuard Home or other ad-blocking DNS resolvers whose default rate limits are easily exceeded by a busy page. The fix is to raise the limit in the DNS service. GitHub widgets without a token are limited to 60 requests per hour.
- Reddit changes. The v0.8.7 release notes say the Reddit widget's
searchproperty no longer works unlessapp-authis configured, following Reddit API changes. - Experimental parts. The Server Stats widget is labelled as under development, and the remote Glance Agent is described as still in development. The extensions API is a work in progress.
- Docker socket access. The Docker Containers widget needs
/var/run/docker.sockmounted into the container, which gives Glance access to the Docker API on that host; weigh that before enabling it on a shared machine. - Network exposure. By default the server listens on all interfaces. Setting
host: localhostrestricts it to the local machine, and serving under a sub-path needsbase-urlplus prefix stripping in the reverse proxy. - External icon CDN. Prefixed icons are loaded from
cdn.jsdelivr.net. The docs suggest downloading icons into anassets-pathdirectory for fully self-contained setups. - Client-side state. The to-do widget stores tasks in the browser's local storage, so tasks do not follow a user between browsers or devices.
- Upgrades. Version 0.7.0 moved
glance.ymlinto aconfig/directory mounted at/app/config; older Compose files need updating, and the repo includes an upgrade note for this. - Browser extensions. The README notes that Dark Reader commonly breaks the layout of the markets, bookmarks and other widgets; disabling it for the dashboard's domain fixes it.
Project activity
As of November 2026 the repository has about 37,900 stars on GitHub. It was created in April 2024, is written in Go and is licensed under AGPL-3.0. The latest release at the time of writing is v0.8.7, published in October 2026, which fixed the Reddit widget after API changes, corrected AdGuard Home blocked-domain counts and limited authentication request bodies to 512 KB. Feature requests are triaged with roadmap, backlog and icebox labels, and the maintainers ask contributors to open a feature request before starting work on new features.
Source code, releases and the full configuration reference are at github.com/glanceapp/glance, with configuration documentation in the repository's docs/configuration.md.
Enjoying this project?
Discover more amazing open-source projects on TechLogHub. We curate the best developer tools and projects.
Repository:https://github.com/glanceapp/glance
GitHub - glanceapp/glance: Glance: self-hosted dashboard for feeds and services
Glance is a lightweight self-hosted dashboard written in Go that combines RSS, Reddit, Hacker News, YouTube and release feeds with monitors, Docker container st...
github - glanceapp/glance
Related Projects
RAGFlow: Open-Source RAG Engine with Agentic Retrieval
Self-hosted RAG engine with deep document parsing, grounded citations and agentic retrieval.
Hugo: Fast Static Site Generator Written in Go
Single-binary Go static site generator with built-in asset pipelines, live dev server and Hugo Modules.
Syncthing: Continuous Peer-to-Peer File Synchronization
Open-source peer-to-peer file sync between your own devices, encrypted with TLS and no central cloud copy.
Maintain Glance: self-hosted dashboard for feeds and services? Add the badge to your README
Show that the project is featured on TechLogHub and send readers to this write-up.
[](https://techloghub.com/open-source/glance-self-hosted-dashboard?utm_source=techloghub_badge&utm_medium=referral&utm_campaign=readme)

