Vitals: a GNOME Shell top bar extension built to avoid blocking sensor polls
A glimpse into your computer's temperature, voltage, fan speed, memory usage and CPU load.
At a glance
- What is it?
- Vitals is a GPL-2.0 GNOME Shell extension that puts temperature, voltage, fan speed, memory, load, network and storage figures in the top menu bar, forked from Freon specifically to stop blocking on I/O. It is a plain JavaScript extension with no package manager, four different support-package commands, and a beta channel that is a branch rather than a release.
- Who is it for?
- Adopt Vitals if you run GNOME Shell and want hardware and resource figures in the top bar without launching a monitoring window, and if you are the kind of user who reads a PKGBUILD before running makepkg. Do not adopt it as the basis for a fan curve, an undervolt or any decision where a wrong reading costs money, because the project disclaims responsibility for improperly represented data and sources its numbers from hwmon and GTop with no stated error handling.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 11 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The fork exists because Freon blocked on I/O
The Credits section gives the origin in one paragraph, and it is the most useful thing in the README. Vitals was originally forked from gnome-shell-extension-freon, and the reason is stated as a personal irritation rather than a feature gap: the author's biggest pet peeve was random system delays because of I/O blocking polls. The idea for Vitals was born from that.
That is a specific engineering complaint with a specific architectural answer. Freon, as described here, was a resource friendly and up to date system monitor that suffered from blocking reads. Vitals uses asynchronous polling instead, and the README leads with that as its defining characteristic. The Credits section is also honest about the debt: the project has been refactored several times over, so most of the code is new or different, while the voltage and fan symbolic icons are inherited from Freon.
This makes Freon the real alternative to Vitals, and the difference in approach is the whole article. Freon is the upstream project with the original design; Vitals is a rewrite of the polling layer that kept the problem domain and the iconography. If your complaint is a blocking poll causing UI stutter, the fork is the answer. If your complaint is that you want a different set of readings, the fork is irrelevant and the upstream is equally capable.
The data source is named in the Disclaimer rather than the feature list: sensor data is obtained from the system using hwmon and GTop. hwmon is the kernel's hardware monitoring interface, which is why the lm-sensors package appears in the install instructions, and GTop is the library behind GNOME's System Monitor.
sensors.js and values.js separate reading from presentation
The repository root is flat and small enough to read in one pass: extension.js, sensors.js, values.js, menuItem.js, prefs.js, prefs.ui, metadata.json, stylesheet.css, and the schemas/, locale/, helpers/ and icons/ directories. Two of those filenames describe the whole design.
sensors.js is the layer that talks to hwmon and GTop. values.js is the layer that turns what comes back into something you can fit in a menu bar. menuItem.js is the panel indicator. That separation is the reason asynchronous polling is achievable: a poll that returns late updates a stored value, and the redraw reads the stored value, so a slow sensor cannot block the panel. It is also the reason a sensor that stops responding shows a stale figure rather than freezing the shell, though the README does not say what figure is shown in that case.
What is missing from that listing is as informative as what is in it. There is no package.json at the repository root, no lockfile, no bundler configuration and no transpilation step. A GNOME Shell extension is loaded as plain JavaScript by the shell itself, so there is nothing to compile, and the only build steps the project documents are glib-compile-schemas for the GSettings schemas and msgfmt for the translation catalogue. That is a low-friction setup for a user and a thin one for a contributor: there is no test command, no linter and no dependency manifest anywhere in the repository listing, so a new contributor has to read the source to learn the conventions.
There is a .github directory and an AGENTS.md at the root, which is where a contributor would look for the project-level rules that the README does not state.
Four support-package commands, and openSUSE is the odd one out
Step 1 of the installation is different on every distribution, and the differences are not cosmetic.
On Ubuntu and Debian:
sudo apt install gnome-shell-extension-manager gir1.2-gtop-2.0 lm-sensorsOn Fedora the command is sudo dnf install libgtop2-devel lm_sensors, on Arch and Manjaro it is sudo pacman -Syu libgtop lm_sensors gnome-icon-theme-symbolic gnome-icon-theme git, and on openSUSE it is sudo zypper install libgtop-devel.
Three observations. First, the Ubuntu and Fedora commands name the GObject introspection package (gir1.2-gtop-2.0) or the development package (libgtop2-devel), while Arch installs the plain runtime library, libgtop. The README does not explain why the package sets differ, and for a JavaScript consumer reading GTop through introspection the distinction is not obvious.
Second, lm-sensors appears in three of the four commands, as lm-sensors or lm_sensors, and is absent from the openSUSE command. Since the Disclaimer names hwmon as a data source, an openSUSE user following the README literally may end up with a panel that shows memory and load but no temperature or fan figures, and nothing in the documentation explains that as a possible outcome.
Third, the Arch command is the only one that pulls in gnome-icon-theme-symbolic, gnome-icon-theme and git. The icon theme packages explain themselves. The git dependency does not, and it is presumably there for the AUR route in step 2 rather than for the extension itself.
Step 2 is shorter. Ubuntu and Debian users go through the Extension Manager installed in step 1 and search for Vitals. Fedora users visit the Gnome Extensions website and click the power icon. Neither requires a command.
The AUR route is the only one that exposes a version number
Arch and Manjaro users get a different install path, and it is the most informative block in the README:
git clone https://aur.archlinux.org/gnome-shell-extension-vitals-git.git/
cd gnome-shell-extension-vitals-git
# always verify content before installing
less PKGBUILD
makepkg
# example filename, different each release
pacman -U gnome-shell-extension-vitals-git-v52.0.4.r0.gb446cfc-1-any.pkg.tar.zstThe instruction to read the PKGBUILD before building is the project being explicit about a supply chain risk in its own distribution channel, and the comment marking the filename as an example that changes each release is there because a hard-coded filename in a README is a hard-coded filename that goes stale.
The filename itself is the useful part. v52.0.4.r0.gb446cfc carries an extension version in the low fifties, a PKGBUILD revision of zero, a short git hash, and the -any and pkg.tar.zst markers of a distribution-independent zstd package. Compare that with the release tags on the repository, where the three most recent are v84.0.0 on 2026-09-05, v83.0.1 on 2026-09-05 and v83.0.0 on 2026-09-04. The README does not explain how a v52 example filename and a v84 release tag relate, and a user reading both will reasonably wonder whether the extension version and the release version are counted separately.
The cadence behind those tags is its own story. Three releases landed inside about three hours on 2026-09-04 and 2026-09-05, at 83.0.0, 83.0.1 and 84.0.0. A patch followed a minor within minutes, which suggests a packaging or metadata problem fixed immediately, and the minor bump the same night suggests something shipped. Without a CHANGELOG in the repository listing, the tags alone do not tell you what either one changed.
Beta testing is a branch and a manual removal, not a channel
The Beta testing section is the most unusual part of the documentation, because it describes a QA process rather than a distribution channel. Advanced users requesting bug fixes or asking for new features may occasionally be asked to help QA. That is the whole policy: there is no public beta, no separate download and no opt-in flag. Being asked is the entry requirement.
The procedure starts by removing the installed copy:
rm -rI ~/.local/share/gnome-shell/extensions/[email protected]The capital I on rm is the single-confirmation guard, and the README labels the step expert users only. Then you create the extensions directory, clone the develop branch straight into the extension path, and compile the schemas:
mkdir -p ~/.local/share/gnome-shell/extensions
git clone https://github.com/corecoding/Vitals.git ~/.local/share/gnome-shell/extensions/[email protected] -b develop
glib-compile-schemas --strict ~/.local/share/gnome-shell/extensions/Vitals\@CoreCoding.com/schemas/The escaped @ in the last line is a shell detail worth noting, because the extension UUID contains an @ and the command fails without the backslash. The --strict flag on glib-compile-schemas is also not decorative: it turns schema warnings into errors, which is the difference between a typo in schemas/ being ignored and being caught at compile time.
The cost of running the develop branch is stated in the same section. On Ubuntu, Debian and Fedora you have to log out and back in to pick up the new code, and on Arch or Manjaro you toggle the extension off and on in the Extensions application. There is no hot reload, so every QA iteration is a session restart. For a project on a three-hourly release cadence, that is a workable arrangement; for anyone wanting to track the tip casually, it is not.
The disclaimer is short and it matters more than usual here
The Disclaimer is two sentences. Sensor data is obtained from the system using hwmon and GTop. Core Coding and the Vitals authors are not responsible for improperly represented data, with no warranty expressed or implied.
For a panel decoration that is boilerplate. For a tool people use to decide whether their machine is thermally healthy, it is the sentence you should read twice. Nothing in the README describes what happens when a sensor disappears, returns a value outside its expected range, or is reported by a driver that lies. There is no averaging window documented, no hysteresis, no threshold at which a reading is considered stale, and no error state described for the panel.
The licence is GPL-2.0, and a LICENSE file is present at the root. For a distributed desktop extension that is the expected choice and the practical consequence is that anyone modifying Vitals and redistributing the modified version has to publish that source. It does not restrict reading the figures off your own panel, which is the direction most self-monitoring use runs in.
The project is published through extensions.gnome.org at extension 1460, which is the declared homepage and the mechanism behind the one-click install path on Fedora. That gives the extension a distribution channel with its own review, which is the strongest quality signal available here, and it is a signal about the packaging rather than about the sensor accuracy.
The icons are credited individually, down to which theme each symbolic file came from: voltage and fan from Freon, system and storage from the Pop! OS theme, battery and storage from Adwaita, and temperature and cpu from the GNOME Theme set by daudix. The two themes are selectable, so the panel can match either a GNOME desktop or a Pop! OS one.
dconf, journalctl and the hot-sensors naming rule
The Development Commands table is the most practically useful documentation in the repository, and it contains one rule that is easy to get wrong.
The panel contents are stored in a GSettings array, and you can read it with dconf read /org/gnome/shell/extensions/vitals/hot-sensors. To set it, the README gives a concrete example:
dconf write /org/gnome/shell/extensions/vitals/hot-sensors "['_memory_usage_', '_system_load_1m_']"The rule for building a sensor name is specified rather than guessed: click the extension to show the drop-down menu, take the category label and the label of the individual sensor, convert them to snake_case, and format them as _category_sensor_. So system load over one minute becomes _system_load_1m_ and memory usage becomes _memory_usage_, both wrapped in single underscores at each end. A name that does not resolve produces no error. The panel simply does not show that entry, so a mistyped sensor is indistinguishable from a missing one.
The rest of the table covers the loop a contributor works in. Launch the preferences with gnome-shell-extension-prefs [email protected]. Follow the extension's log output with a journalctl invocation filtered through grep for Vitals, timestamped from the moment you run it. Recompile the schemas with glib-compile-schemas --strict schemas/ and rebuild the translation catalogue with msgfmt vitals.po -o vitals.mo. And run a nested Wayland session with dbus-run-session -- gnome-shell --nested --wayland, which is how you get a second GNOME Shell to install an unreleased extension into without disturbing the one you are using.
That last command is the answer to the session-restart problem in the beta section, and the README documents it in a table rather than in the QA walkthrough, which is a small example of documentation that is complete but not in the order a new contributor needs it.
Editorial conclusion
Adopt Vitals if you run GNOME Shell and want hardware and resource figures in the top bar without launching a monitoring window, and if you are the kind of user who reads a PKGBUILD before running makepkg. Do not adopt it as the basis for a fan curve, an undervolt or any decision where a wrong reading costs money, because the project disclaims responsibility for improperly represented data and sources its numbers from hwmon and GTop with no stated error handling. Verify three things in order. Run the support-package command for your distribution and confirm GTop introspection and lm-sensors are present, since without them the panel entries simply stay empty. Then install and check that dconf write on the hot-sensors key accepts your sensor names, because the snake_case format is easy to get wrong and the panel gives no error when a name does not resolve. Then decide between the main branch and the develop branch deliberately, since the develop branch is what QA is asked to run and the removal step before switching is rm -rI on your existing extension directory. Vitals is a good panel citizen for one desktop and a bad telemetry source for anything automated.
Frequently asked questions
What does the Vitals GNOME extension show in the top bar?
It displays temperature, voltage, fan speed, memory usage, processor load, system resources, network speed and storage statistics in the GNOME Shell top menu bar. Sensor data is obtained from the system using hwmon and GTop, and the extension uses asynchronous polling rather than blocking reads.
How do I install Vitals on Ubuntu or Debian?
First run sudo apt install gnome-shell-extension-manager gir1.2-gtop-2.0 lm-sensors, then open the Extension Manager, search for Vitals and click Install. Vitals should then be running; if you reversed the two steps you will need to log out and back in to restart your session.
What is the difference between Vitals and Freon?
Vitals was originally forked from gnome-shell-extension-freen and has been refactored several times since, so most of the code is new or different. The reason for the fork was that Freon's blocking I/O polls caused random system delays, and Vitals was written to use asynchronous polling instead.
How do I choose which sensors Vitals shows?
Write the hot-sensors GSettings array with dconf. Take the category label and the individual sensor label from the extension's drop-down menu, convert them to snake_case and wrap them as _category_sensor_, for example dconf write /org/gnome/shell/extensions/vitals/hot-sensors "['_memory_usage_', '_system_load_1m_']". A name that does not resolve is simply not displayed.
Can I install a development version of Vitals?
The README describes a QA process rather than a public beta. You remove the existing copy, clone the repository with the -b develop branch into ~/.local/share/gnome-shell/extensions/[email protected], and run glib-compile-schemas --strict on the schemas directory. You then need to log out and back in, or toggle the extension in the Extensions application.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/corecoding-vitals)