diff --git a/script/build-app b/script/build-app
new file mode 100755
index 00000000..65d1368e
--- /dev/null
+++ b/script/build-app
@@ -0,0 +1,33 @@
+#!/bin/bash
+# Build "native" desktop app using nativefier
+# https://github.com/jiahaog/nativefier
+set -e
+
+if !which nativefier >/dev/null 2>&1; then
+ echo "nativefier not found!" >&2
+ echo "npm install -g nativefier" >&2
+ exit 1
+fi
+
+export BASE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../" && pwd )"
+export OS_NAME=$(node -e "console.log(os.platform())")
+export OS_ARCH=$(node -e "console.log(os.arch())")
+export ELECTRON_VERSION=${ELECTRON_VERSION:-7.1.1}
+
+if [ "$OS_NAME" = "linux" ] && ! which snapcraft >/dev/null; then
+ echo "snapcraft not available!" >&2
+ echo "we need snapcrat to build the snap package" >&2
+ exit 1
+fi
+
+if [ ! -f $BASE_PATH/script/build-app-$OS_NAME ]; then
+ echo "$OS_NAME is not currently supported." >&2
+ exit 1
+fi
+
+if [ ! -f beehive ]; then
+ echo "Run 'make embed' first." >&2
+ exit 1
+fi
+
+$BASE_PATH/script/build-app-$OS_NAME
diff --git a/script/build-app-darwin b/script/build-app-darwin
new file mode 100755
index 00000000..384c8633
--- /dev/null
+++ b/script/build-app-darwin
@@ -0,0 +1,69 @@
+#!/bin/bash
+set -e
+
+cleanup_macos() {
+ if [ -f "$icns_file" ]; then
+ rm -f $icns_file
+ fi
+}
+
+trap cleanup_macos EXIT
+
+BIN_PATH=build/app/Beehive-$OS_NAME-$OS_ARCH/Beehive.app/Contents/MacOS
+RES_PATH=build/app/Beehive-$OS_NAME-$OS_ARCH/Beehive.app/Contents/Resources
+icns_file=$($BASE_PATH/script/build-icns)
+nativefier -e $ELECTRON_VERSION --icon $icns_file --name Beehive http://localhost:8181 $BASE_PATH/build/app
+mkdir -p $RES_PATH
+cp beehive $BIN_PATH/beehived
+chmod +x $BIN_PATH/beehived
+mv $BIN_PATH/Beehive $BIN_PATH/Beehive.bin
+
+cat > $BIN_PATH/Beehive << "EOF"
+#!/bin/bash
+set -e
+
+BASE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd )"
+RES_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../Resources" && pwd )"
+LIBRARY_PATH=$HOME/Library/Application\ Support/Beehive
+LA_PLIST=$HOME/Library/LaunchAgents/com.github.muesli.beehive.plist
+mkdir -p "$LIBRARY_PATH"
+cp $RES_PATH/launchagent.plist $LA_PLIST
+sed -i '' s/@@user@@/$USER/ $LA_PLIST
+sed -i '' s,@@bin_path@@,$BASE_PATH/beehived, $LA_PLIST
+launchctl load $LA_PLIST
+# Wait a bit for beehived to be ready
+for i in $(seq 20); do
+ s=$(curl -s -o /dev/null -w "%{http_code}" localhost:8181)
+ [ "$s" = 200 ] && break
+ sleep 0.1
+done
+$BASE_PATH/Beehive.bin
+EOF
+chmod +x build/app/Beehive-$OS_NAME-$OS_ARCH/Beehive.app/Contents/MacOS/Beehive
+
+cat > $RES_PATH/launchagent.plist << "EOF"
+
+
+
+
+ Label
+ com.muesli.beehive
+
+ ProgramArguments
+
+ @@bin_path@@
+ --config
+ /Users/@@user@@/Library/Application Support/Beehive/beehive.conf
+
+
+ KeepAlive
+
+
+ LowPriorityIO
+
+
+ ProcessType
+ Background
+
+
+EOF
diff --git a/script/build-app-linux b/script/build-app-linux
new file mode 100755
index 00000000..3ffd8f92
--- /dev/null
+++ b/script/build-app-linux
@@ -0,0 +1,32 @@
+#!/bin/bash
+set -e
+
+cleanup_linux() {
+ true
+}
+
+trap cleanup_linux EXIT
+
+nativefier -e $ELECTRON_VERSION --icon $BASE_PATH/assets/logo.png --name Beehive http://localhost:8181 build/app
+
+mkdir -p build/app
+cp beehive build/app
+chmod +x build/app/beehive
+cat > build/app/beehive-linux-x64/beehive.wrapper << "EOF"
+#!/bin/bash
+
+export BASE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../" && pwd )"
+
+# Start the daemon
+$BASE_PATH/beehive --config $SNAP_USER_DATA/beehive.conf &
+bpid=$!
+finish() {
+ [[ -z "$bpid" ]] || kill $bpid > /dev/null 2>&1
+}
+trap finish EXIT
+
+# Start the GUI shell
+$BASE_PATH/beehive-linux-x64/beehive
+EOF
+chmod +x build/app/beehive-linux-x64/beehive.wrapper
+snapcraft
diff --git a/script/build-icns b/script/build-icns
new file mode 100755
index 00000000..f09632a1
--- /dev/null
+++ b/script/build-icns
@@ -0,0 +1,30 @@
+#!/bin/bash
+set -e
+
+tmpd=$TMPDIR/beehive.iconset
+icns=$TMPDIR/beehive.icns
+logfile=$TMPDIR/build-icns.log
+
+cleanup() {
+ rm -rf $tmpd
+ rm -f $logfile
+}
+
+trap cleanup EXIT
+
+{
+ mkdir $tmpd
+ sips -z 16 16 assets/logo.png --out $tmpd/icon_16x16.png
+ sips -z 32 32 assets/logo.png --out $tmpd/icon_16x16@2x.png
+ sips -z 32 32 assets/logo.png --out $tmpd/icon_32x32.png
+ sips -z 64 64 assets/logo.png --out $tmpd/icon_32x32@2x.png
+ sips -z 128 128 assets/logo.png --out $tmpd/icon_128x128.png
+ sips -z 256 256 assets/logo.png --out $tmpd/icon_128x128@2x.png
+ sips -z 256 256 assets/logo.png --out $tmpd/icon_256x256.png
+ sips -z 512 512 assets/logo.png --out $tmpd/icon_256x256@2x.png
+ sips -z 512 512 assets/logo.png --out $tmpd/icon_512x512.png
+ cp assets/logo.png $tmpd/icon_512x512@2x.png
+ iconutil -c icns $tmpd
+} > $logfile 2>&1
+
+echo $icns
diff --git a/snap/gui/beehive.desktop b/snap/gui/beehive.desktop
new file mode 100644
index 00000000..c5bfb7e2
--- /dev/null
+++ b/snap/gui/beehive.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Name=Beehive
+Comment=Beehive
+Exec=beehive
+Terminal=false
+Type=Application
+Icon=${SNAP}/meta/gui/icon.png
+StartupWMClass=beehive
+X-Desktop-File-Install-Version=0.24
+
diff --git a/snap/gui/icon.png b/snap/gui/icon.png
new file mode 100644
index 00000000..18067b00
Binary files /dev/null and b/snap/gui/icon.png differ
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
new file mode 100644
index 00000000..df354a26
--- /dev/null
+++ b/snap/snapcraft.yaml
@@ -0,0 +1,47 @@
+name: beehive # you probably want to 'snapcraft register '
+base: core18 # the base snap is the execution environment for this snap
+version: '0.4' # just for humans, typically '1.2+git' or '1.3.2'
+summary: A flexible event/agent & automation system with lots of bees 🐝
+description: |
+ Beehive is an event and agent system, which allows you to create your own
+ agents that perform automated tasks triggered by events and filters.
+ It is modular, flexible and really easy to extend for anyone. It has
+ modules (we call them Hives), so it can interface with, talk to, or retrieve
+ information from Twitter, Tumblr, Email, IRC, Jabber, RSS, Jenkins,
+ Hue - to name just a few.
+
+grade: stable # must be 'stable' to release into candidate/stable channels
+confinement: classic # use 'strict' once you have the right plugs and slots
+apps:
+ beehive:
+ command: bin/beehive
+ extensions: [gnome-3-28]
+parts:
+ beehive:
+ plugin: dump
+ source: build/app
+ organize:
+ beehive-linux-x64/beehive.wrapper: bin/beehive
+ stage-packages:
+ - libx11-6
+ - libxcb-xtest0
+ - libx11-xcb1
+ - libnotify4
+ - libappindicator1
+ - libxtst6
+ - libnss3
+ - libxss1
+ - fontconfig-config
+ - gconf2
+ - libasound2
+ - pulseaudio
+ - libatk-bridge2.0-0
+ - libatspi2.0-0
+ - libcairo-gobject2
+ - libepoxy0
+ - libgtk-3-0
+ - libwayland-client0
+ - libwayland-cursor0
+ - libwayland-egl1
+ - libxkbcommon0
+