instally
is a portable interactive CLI script for conveniently & consistently installing packages en masse.
- 🚚 JSON-driven flexibility: Specify packages for
instally
to install using JSON and enjoy support for:- organizing packages in groups,
- preferred methods of installation,
- fallback installation methods,
- OS-specific installation methods,
- 9 different package managers,
- and even running your own installation commands.
- ⛺ Minimal dependencies: Owing to its simplicity, you can bring
instally
to any* machine that's capable of running Bash andjq
. - 💼 Super portable: With
instally
and your own custompackage.json
file, you can bring your favorite packages to (almost) any distro and install them right away.
- 💽 Installation
- 🙂 Usage
- 🎨 Configuration
- 👉 Protips
- 🔧 Troubleshooting
- Download
instally
's latest release. - Un-archive the downloaded release one of these ways:
- Double-click the downloaded file.
- For
.tar.gz
-tar -zxvf instally.tar.gz
- For
instally.zip
-unzip instally.zip
- Start
instally
! There's a few different ways to startinstally
:→ bash instally
→ ./instally
(you may need to→ chmod +x instally
first)- To install
instally
and make it accesible from anywhere in your terminal, try moving theinstally
script to~/.local/bin
. Now you can runinstally
like so:→ instally
.
instally
checks for and automatically installs its own dependencies if
they're missing upon initial run:
curl
- For installinggum
and as a fallback installation method.gum
- For interactivity.jq
- For reading yourpackage.json
file and installing packages.
You can install curl
, gum
, and jq
using whatever installation methods you
prefer, if you'd rather not have instally
install them for you.
- Start
instally
. - You'll need to specify the packages you'd like to be installed in the
package.json
file. Don't worry—instally
will create and open this file for you. instally
will read yourpackage.json
and provide an interactive CLI for package selection and installation.
Now you can take your custom package.json
file anywhere with instally
, and
install your favorite packages on (almost) anything!
package.json
is the brains behind your instally
experience. Using
package.json
, you can configure:
- What packages
instally
can install, - Installation methods, fallback installation methods, and OS-specific installation methods,
- Grouping of packages,
- What order packages are installed in.
Here's a simple example of a package.json
:
{
"packages": [
{
"name": "Sensors",
"description": "hardware health monitoring",
"apt": {
"id": "lm-sensors"
},
"dnf": {
"id": "lm_sensors"
},
"zypper": {
"id": "sensors"
}
},
{
"name": "Vim",
"apt": {
"id": "vim-gtk3"
},
"dnf": {
"id": "vim-X11"
},
"zypper": {
"id": "vim"
}
},
{
"name": "Taskwarrior",
"description": "CLI todo list",
"apt": {
"id": "taskwarrior"
},
"dnf": {
"id": "task"
}
}
],
"groups": [
{
"group": "🎨 Graphics",
"packages": [
{
"name": "Blender",
"description": "legendary FOSS 3D computer graphics suite",
"prefer": "flatpak",
"apt": {
"id": "blender"
},
"dnf": {
"id": "blender"
},
"flatpak": {
"id": "org.blender.Blender"
},
"zypper": {
"id": "blender"
}
}
]
},
{
"group": "🐮 Goofy",
"description": "very important superfluous extras",
"packages": [
{
"name": "cmatrix",
"description": "cascading text in your terminal, just like the Matrix",
"apt": {
"id": "cmatrix"
},
"dnf": {
"id": "cmatrix"
},
},
{
"name": "figlet",
"description": "generate ASCII text on the fly in all sorts of fun fonts",
"apt": {
"id": "figlet"
},
"dnf": {
"id": "figlet"
},
"zypper": {
"id": "zypper"
}
},
{
"name": "cowsay",
"description": "cow that speaks wisdom",
"apt": {
"id": "cowsay"
},
"dnf": {
"id": "cowsay"
},
"zypper": {
"id": "cowsay"
}
}
]
}
]
}
"packages"
- An array of package objects listing the packages for installation."groups"
- Optional array of package groups containing package objects for installation.
Package objects are the atomic pieces of your instally
experience; each
package object represents a package you'd like to install and its different
installation methods.
instally
package objects are shaped like so:
{
"name": "Vim",
"description": "your favorite text editor",
"apt": {
"id": "vim-gtk3"
},
"dnf": {
"id": "vim-X11"
},
"zypper": {
"id": "vim"
}
}
"name"
- The name of the package. This could be virtually anything and spelled in any way."description"
- Optional description of the package.- Installation methods -
"apt"
,"dnf"
"flatpak"
,"go"
,"npm"
,"pip"
,"snap"
,"yum"
, and"zypper"
are all valid installation methods using package managers.instally
can also install packages using custom shell commands ("command"
). "prefer"
- Optional preferred installation method. See preferring installation methods.
Within a package object, you can specify as few or as many installation methods as you'd like.
These are all valid installation methods:
instally
currently supports 9 different package managers.
Here, we're using 3 of them:
{
"name": "Vim",
"description": "play the legendary text editing instrument like a cool kid",
"apt": {
"id": "vim-gtk3"
},
"dnf": {
"id": "vim-X11"
},
"zypper": {
"id": "vim"
}
}
↑ On systems with apt
instally
will use apt
to install "vim-gtk3"
, and
on systems with dnf
instally
will use dnf
to install "vim-x11"
, and so
on.
- 👉 Protip: See getting package IDs for help getting
the
"id"
s of your packages.
instally
supports 10 package managers:
apt
- needs an"id"
dnf
- needs an"id"
; falls back toyum
automatically ifdnf
isn't installedflatpak
- needs an"id"
go
- needs a"path"
containing the URL or path to the packagenpm
- needs an"id"
pip
- needs an"id"
snap
- needs an"id"
yum
- needs an"id"
zypper
- needs an"id"
Install packages using shell commands with the "command"
field in a package
object:
{
"name": "VirtualBox",
"description": "x86 virtualization",
"command": "wget -P ~/Downloads https://download.virtualbox.org/virtualbox/7.0.6/virtualbox-7.0_7.0.6-155176~Ubuntu~jammy_amd64.deb; sudo dpkg -i ~/Downloads/virtualbox-7.0_7.0.6-155176~Ubuntu~jammy_amd64.deb; rm ~/Downloads/virtualbox-7.0_7.0.6-155176~Ubuntu~jammy_amd64.deb;"
}
instally
will run the contents of your "command"
field to install your
package.
- ⚠ Caution: Make sure you know what you're doing.
instally
will run whatever is in the"command"
field without sanitization or guardrails. - 👉 Protip:
instally
will choose other existing installation methods over the"command"
method due to its risk and inflexibility, so you may need to"prefer"
your"command"
if other installation methods exist for the package. - 👉 Protip: String together shell commands in sequence using
;
or&&
. - 👉 Protip: You can use
"command"
to execute your own scripts. - 👉 Protip: Remember to delete downloaded files and install scripts if you
don't want them anymore. You can automate this by adding an
rm
statement at the end of your command, as in the above example.
Prefer an installation method for a package by specifying your preferred
method using the "prefer"
field:
{
"name": "Blender",
"prefer": "flatpak",
"apt": {
"id": "blender"
},
"flatpak": {
"id": "org.blender.Blender"
}
}
↑ Since "prefer"
is "flatpak"
, instally
will install this package using
flatpak
instead of apt
.
Specify installation methods for a specific OS by adding a field in the package object containing your OS's name:
{
"name": "Visual Studio Code",
"apt": {
"id": "code"
},
"Fedora Linux": {
"command": "sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc; sudo sh -c 'echo -e \"[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc\" > /etc/yum.repos.d/vscode.repo'; dnf check-update; sudo dnf install code;"
},
"openSUSE Tumbleweed": {
"command": "sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc; sudo sh -c 'echo -e \"[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ntype=rpm-md\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc\" > /etc/zypp/repos.d/vscode.repo'; sudo zypper refresh; sudo zypper install code;"
}
}
↑ On a Fedora Linux system, instally
will try to install this package using
the given "command"
installation method under "Fedora Linux"
. On an
openSUSE Tumbleweed system, instally
will use a totally different command to
install the package.
-
👉 Protip: You can check the
/etc/os-release
file for your OS's name (in case you forgot it):# Linux: Get your OS's name: echo $(grep '^NAME=' /etc/os-release | cut -d= -f2 | tr -d '"')
Specify installation methods for a specific version of an OS by adding a field in the package object containing your OS's full name:
{
"name": "VirtualBox",
"apt": "virtualbox",
"Debian GNU/Linux 11 (bullseye)": {
"command": "wget -P ~/Downloads https://download.virtualbox.org/virtualbox/7.0.8/virtualbox-7.0_7.0.8-156879~Debian~bullseye_amd64.deb; sudo dpkg -i ~/Downloads/virtualbox-7.0_7.0.8-156879~Debian~bullseye_amd64.deb; rm ~/Downloads/virtualbox-7.0_7.0.8-156879~Debian~bullseye_amd64.deb;"
},
"Debian GNU/Linux 10 (buster)": {
"command": "wget -P ~/Downloads https://download.virtualbox.org/virtualbox/7.0.8/virtualbox-7.0_7.0.8-156879~Debian~buster_amd64.deb; sudo dpkg -i ~/Downloads/virtualbox-7.0_7.0.8-156879~Debian~buster_amd64.deb; rm ~/Downloads/virtualbox-7.0_7.0.8-156879~Debian~buster_amd64.deb;"
},
}
↑ instally
will install this package using different commands specific to
different versions of Debian, and use apt
if it's ran on a system with apt
available that isn't Debian 11 or Debian 10.
-
👉 Protip:
instally
will choose version-specific installation methods for a package over OS-specific installation methods. -
👉 Protip: You can find your current OS's full name, including its version, at
instally
's main menu:
instally
will automatically chose whatever methods are appropriate for your OS, unless you prefer an installation method.- If OS-specific installation methods are specified for a package,
instally
will only choose from installation methods for the encountered OS.
Group packages using the "groups"
field to create an
array of groups:
{
"groups": [
{
"group": "🎸 Music",
"packages": [
{
"name": "Spotify",
"description": "massive audio streaming service",
"flatpak": {
"id": "com.spotify.Client"
}
},
{
"name": "ncmpcpp",
"description": "CLI music player",
"apt": {
"id": "ncmpcpp"
}
}
]
},
{
"group": "🎨 Graphics",
"packages": [
{
"name": "GIMP",
"description": "GNU Image Manipulation Program",
"apt": {
"id": "gimp"
}
},
{
"name": "Krita",
"description": "digital painting suite",
"apt": {
"id": "krita"
},
"flatpak": {
"id": "org.kde.krita"
}
}
]
}
]
}
"groups"
should be an array of group objects.- Each group object within
"groups"
has:"group"
- the name of your group,"packages"
- the array of packages contained within the group,"description"
- optional description of your group.
instally
installs packages from package.json
sequentially, from the top
to the bottom of the file, so the order of package installation is up to the
user.
- 👉 Protip: Remember to install dependencies before the packages that depend on them.
- 👉 Protip: Using grouping, you can bundle packages together with their dependencies.
instally
has been successfully tested and ran on:
- Linux:
- Debian-based:
- Debian 11
- Ubuntu 22.04 LTS
- Pop!_OS 22.04 LTS
- RHEL-based:
- Fedora Linux 37
- CentOS Linux 7
- SUSE-based:
- openSUSE Tumbleweed
- Debian-based:
Feel free to contribute and expand instally
's compatibility!
- 👉 Protip: Hypothetically,
instally
could work on any distro by using the flexible"command"
installation method. Combine this technique with OS-specific installation methods for your enigmatic distro and you'll be good-to-go. - ⚠ Warning:
instally
does not currently run on macOS.
See also: Supported package managers
Configure instally
in "Settings":
Alternatively, you can configure instally
by editing
~/.instally/instally.conf
:
# package.json path:
PACKAGE_JSON=/path/to/desired/package.json/file
# Active color; use a hex code or ANSI color code:
COLOR_ACTIVE=117
# Accent color; use a hex code or ANSI color code:
COLOR_ACCENT=#008000
# Cursor used to point to menu items:
CURSOR=→
# Character symbolizing unselected menu items:
CHOOSE_DEFAULT=-
# Character symbolizing selected menu items:
CHOOSE_SELECTED=✔
package.json
and instally.conf
can be saved in a git
repo and taken to any
machine with instally
installed, making bringing your favorite packages and
environment to any distro pretty trivial.
If you find yourself constantly recalling and reinstalling packages on freshly
installed operating systems over a matter of days (or weeks),
instally
's the thing for you: It can massively reduce your cognitive load and
the time it takes to load your system with all the software you need.
There's some up-front cost in writing your package.json
, but with your
package.json
version-controlled, easily accessible, and polished to
accommodate the different operating systems and package managers you'll be
using, it can be a really flexible and foolproof way to install consistent
experiences across systems.
instally
uses your $EDITOR
to determine what application to edit
package.json
in. If your $EDITOR
isn't set, instally
will open
package.json
with nano
.
You can set your default $EDITOR
to your preferred text editor like so:
# Examples
# Bash users: Set default $EDITOR to gedit:
echo 'export EDITOR=gedit' >> ~/.bashrc
# Zsh users: Set default $EDITOR to gedit:
echo 'export EDITOR=gedit' >> ~/.zshrc
Search for the package:
→ apt search [PACKAGE NAME]
The "id"
is "cmatrix"
:
cmatrix/jammy,now 2.0-3 amd64 [installed]
simulates the display from "The Matrix"
Search for the package:
→ dnf search [PACKAGE NAME]
The "id"
is "task"
(or "task.x86_64"
):
Last metadata expiration check: 0:09:21 ago on Thu 13 Apr 2023 05:08:31 PM EDT.
========================= Summary Matched: taskwarrior =========================
task.x86_64 : Taskwarrior - a command-line TODO list manager
taskopen.noarch : Script for taking notes and open urls with taskwarrior
tasksh.x86_64 : Shell command that wraps Taskwarrior commands
vit.noarch : Visual Interactive Taskwarrior full-screen terminal interface
Search for the package:
→ flatpak search [PACKAGE NAME]
The "id"
is "com.spotify.Client"
, under Application ID
:
Name Description Application ID Version Branch Remotes
Spotify Online music streaming service com.spotify.Client 1.2.8.923.g4f94bf0d stable flathub
Search for the package:
→ npm search [PACKAGE NAME]
The "id"
is "tiddlywiki"
, under NAME
:
NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS
tiddlywiki | a non-linear… | =jermolene | 2023-03-26 | 5.2.7 | tiddlywiki tiddlywiki5 wiki
- Search for the package at https://pypi.org/search/.
- The
"id"
is in the installation command at the top of your package's page. Example: inpip install buku
,"buku"
is the"id"
.
pip search [PACKAGE NAME]
isn't supported by PyPI.
Search for the package:
→ snap search [PACKAGE NAME]
The "id"
is "krita"
under "Name"
:
Name Version Publisher Notes Summary
krita 5.1.5 krita✓ - Digital Painting, Creative Freedom
Search for the package:
→ yum search [PACKAGE NAME]
The "id"
is "nano"
(or "nano.x86_64"
):
================================== N/S matched: nano ==================================
nano.x86_64 : A small text editor
Name and summary matches only, use "search all" for everything.
Search for the package:
→ zypper search [PACKAGE NAME]
The "id"
is "blender"
under Name
:
S | Name | Summary | Type
--+--------------+--------------------------------------+--------
| blender | A 3D Modelling And Rendering Package | package
| blender-demo | Some Blender demo files | package
| blender-lang | Translations for package blender | package
package.json
is in ~/.instally
(a directory called .instally
, located in
your home directory).
If you're having trouble finding /.instally
, try the ctrl+h
shortcut in your
file manager to view hidden files.
instally.conf
is in ~/.instally
, just like package.json
.
If you encounter an error like this:
🐛 Error: Go is installed, and gum also might be installed, but Go is not finding gum.
Ensure your Go binaries (/go/bin) are included in your PATH variable below:
...
See https://github.com/jelizaga/instally/#gum-is-installed-but-wont-run for help.
... it's likely that gum
was successfully installed using Go, but you haven't
added Go binaries to your $PATH
yet, so gum
can't be found.
Make sure you've added your Go binaries to your $PATH
variable, so they can be
used:
# Prints the contents of your $PATH. Make sure there's a /go/bin:
→ echo $PATH
If your Go binaries are in ~/go/bin
(Go's default binary location), add the
path to /go/bin
to your $PATH
like so:
# Bash users: Adds ~/go/bin to your $PATH:
→ echo 'export PATH=$PATH:$HOME/go/bin' >> ~/.bashrc
# Zsh users: Also adds ~/go/bin to your $PATH:
→ echo 'export PATH=$PATH:$HOME/go/bin' >> ~/.zshrc
Now restart your terminal, then try instally
again.