instally
Conveniently & consistently install packages en masse
instally
is a portable interactive
CLI script for conveniently & consistently installing packages en masse on
Linux, featuring:
- 🚚 JSON-driven flexibility: Specify packages for
instally
to install using JSON, enjoying support for:- organizing packages in groups,
- preferring methods of installation on a package-by-package basis,
- fallback installation methods,
- OS-specific installation methods,
- 9 different package managers,
- and even running your own installation commands!
- ⛺ Minimal dependencies: Owing to
instally
’s simplicity, you can bringinstally
to any Linux distribution capable of running Bash andjq
. - 💼 Superb portability: With
instally
and your own custompackage.json
file, you can bring your favorite packages to (almost) any distro and install them right away.
Visit instally
’s GitHub page for the full manual.
User Experience
The UI guidelines we use today for heuristic analysis were coded during the
1960s and 70s for command-line interface programs: instally
is a CLI script,
but I still used the same UX principles a designer would apply to, say, a
mobile app or a website.
User & Use-Case
instally
’s primary use-case is for the developer or Linux user (aficionado?)
who is going to open their terminal upon installing their OS. This is
because they’re about to invoke apt
, dnf
, or zypper
with a laundry list of
packages to install.
With that in mind, installing and using instally
is pretty trivial:
# Download instally off GitHub, unarchive, and run instally:
wget -P ~/Downloads \
https://github.com/jelizaga/instally/archive/refs/tags/v0.23.tar.gz
tar -xzvf ~/Downloads/v0.23.tar.gz
cd ~/Downloads/instally-0.23
./instally
Alternatively (and most effectively), instally
makes a great git
submodule
or script in a dotfiles
repo.
This is because a user on a fresh install will:
- install
git
(if it’s missing) - clone their
.dotfiles
repo (to import & symlink their configs)
If instally
is already included in their .dotfiles
along with a
package.json
, all the user has to do is run instally
to select their
packages for installation.
Given that instally
supports 9 different package managers and OS-specific
installation methods, this process of installing their package environments is
made a whole lot easier: Users don’t have to remember what packages to install,
or even what package IDs to use for which package managers on particular
operating systems.
Basically, we’re leveraging recognition over recall.
Recognition > Recall
For example, on Debian-based distros Taskwarrior can be installed like so:
sudo apt install taskwarrior
But on RHEL-based distros, this same application is installed with a different
ID (task
instead of taskwarrior
):
sudo dnf install task
If the user recently switched from a Debian-based distro to Fedora, they’ll be
running sudo dnf install taskwarrior
, get a message from dnf
saying, “No,
taskwarrior
doesn’t exist,” and either try sudo dnf install task
out of
instinct or try searching dnf
for the package—which is a bit of a waste of
cognition, especially if they’re installing dozens (or hundreds) of packages
just like this.
This is the inefficiency of recall; users drawing package IDs from fallible memory.
Using instally
, we can avoid this inefficiency entirely:
{
"name": "Taskwarrior",
"description": "command-line todo list for staying on-task",
"apt": {
"id": "taskwarrior"
},
"dnf": {
"id": "task"
},
"zypper": {
"id": "taskwarrior"
}
}
↑ Taskwarrior’s the same app, but now we have three different installation methods depending on whichever package manager’s available.
Now all the user has to do is recognize Taskwarrior in instally
and
select it for installation:
No memorization; no recall—users know they’ll be getting Taskwarrior without fussing with package ID discrepencies and package managers.
IxD Grammar
instally
has a dense IxD grammar:
Object | Install | Select | Edit |
---|---|---|---|
Package | ☑ | ☑ | ☑ |
Package Manager | ☑ | ☑ | ☑ |
Installation Method | ☐ | ☑ | ☑ |
Group | ☐ | ☑ | ☑ |
| ☐ | ☑ | ☑ |
| ☐ | ☑ | ☑ |
The actions (install, select, and edit) for instally
’s objects are
consistent: this consistent vocabulary reduces possible cognitive load and
ambiguity, training a perceptual pattern with which the user learns to
navigate their instally
experience: instally
is all about selecting
and installing, and any object of instally
is conceivably
editable.
Information Architecture
Colors
instally
has three colors, each with their own function:
- Active color - Highlights ‘active’ menu items and suggested keystrokes the user can perform.
- Accent color - Partially decorative, but also used to embellish important information, such as the package report at the end of install runs.
- Selected color - Used to denote menu items and selections made.
This simplicity and consistency makes instally
easy to use.
Typography
Typography is used to make information scannable. For example, instally
bolds
packages being installed, dependencies, and package managers (software) due to
their importance:
↑ Instructions and prompts are consistently italicized, whereas output and
instally
’s operations are plain.
instally
’s ‘sections’ are separated by a line break and each have a bolded
and underlined heading, making it completely unambiguous where the user ‘is’
and what’s going on:
This creates a typographical ‘language’ that users can easily scan with minimal focus.
Iconography
While installing packages, consistent, emoji-based iconography is used to further make information effortlessly scannable:
- 🎁 - Installed packages,
- 👍 - Already installed packages,
- ❗ - Packages that could not be installed,
- ❌ - Missing (but expected) packages,
- ❓ - Ambiguously installed packages (shell commands with non-
0
exit codes), - 🌎 - Installation in-progress,
- 👉 - Helpful tips (usually on resolving errors),
- ✨ - Updated package indices (
apt update
, for example), - ⚠️ - Warnings (for user-defined shell commands being executed, for example),
- 📒 -
package.json
, - 🐛 - Bugs & errors.
With a cursory glance down the left side of the terminal, a user can assess the progress of their installation run:
If they’d like further detail, they can actually read the messages—not that it’s
necessary; the whole point of instally
is to reduce mental investment
into the installation process.
Background
This is going to get a bit in-the-weeds:
I wrote instally
between
Pop!_OS
22.04 and System76’s next LTS release,
Pop!_OS 24.04, because there was a whole two years between 22.04 and 24.04
during which I anticipated making a clean reinstall of Pop! due to the projected
addition of the new
COSMIC desktop environment
to Pop!_OS 24.04.
I didn’t (and still don’t—24.04 isn’t out yet) know if COSMIC was going to be a
polished enough experience to warrant using Pop!_OS 24.04, it being a new
desktop environment and all, so instally
’s my way of bringing my system to
whatever Linux distribution I ultimately end up using, Pop!_OS or not.
I chose to parse package.json
with jq
is because I wanted to learn how to
use it and JSON lends itself handily to nesting data; the shape of
package.json
was self-evident from the get-go. I wanted to minimize
instally
’s dependencies, but I also didn’t want to wrangle awk
into being
the thing reading the package file, because awk
looked like it’d take much
longer to grok than jq
and asking ChatGPT to hold my hand through that one
would feel like cheating.
Afterthoughts
I learned a whole lot of Bash I wouldn’t have otherwise known while
writing instally
, and ultimately came to the conclusion that something much
more polished could’ve been made in Python with a TUI library instead. Of
course, I’d have to call this hypothetical sequel to instally
installyy
.
The fact that it’s in Bash really does make instally
portable, though, and its
dependencies can all be grabbed as binaries. It’s not a very economical script,
but it’s no-fuss.
For all the UX principles used to design instally
, I haven’t user-tested it.
Like a lot of FOSS TUI stuff, its use-case is niche and I think it serves its
purpose effectively enough to not warrant whittling it into something wholly
refined. If I’m going to do some serious testing, it’d have to be on something
with a larger user demographic and better incentives beyond sating personal
curiosity.
That said, I think instally
has its place, which is mostly in my .dotfiles
repo where I can set it and forget it while it installs a bunch of
packages and runs a few scripts whenever I make a clean install or spin a
virtual machine.
Joel Elizaga
Joel Elizaga is a UX engineer based in the Pacific Northwest.