diff --git a/hugo/content/post/pidgin3-dev-scripts.md b/hugo/content/post/pidgin3-dev-scripts.md
new file mode 100644
--- /dev/null
+++ b/hugo/content/post/pidgin3-dev-scripts.md
@@ -0,0 +1,187 @@
+---
+title: "Pidgin3 Development Scripts"
+date: 2021-06-09T01:26:16-05:00
+---
+
+Developing Pidgin 3 can be quite complicated and error prone. Compilation and
+installation takes a long time and even running an additional instance can be
+a painful as there's current two command line arguments that need to be set to
+make it work.
+
+To make all of this work we use a number of scripts. In fact you may even have
+seen some of them in use on [grim's stream](https://twitch.tv/rw_grim). But
+there's one more piece to all of this and that is the installation prefix.
+
+All projects that use autotooks, cmake, meson, qmake, etc have what we call
+an installation prefix. It's what tells the build system where to install the
+software. By default this is typically `/usr/local` which means your executables
+will end up in `/usr/local/bin`, your libraries in `/usr/local/lib` and so on.
+
+Using the default is usually fine if you're just running the software, but while
+developing the need might arise for you to delete everything that's been
+installed. While all of these build systems include an uninstall target, there
+are times when you'll update your local copy and not realize that installed
+files have been removed and they end up polluting your install prefix and can
+cause bugs that are very difficult to debug because there are files that are
+there that you're not expecting.
+
+To avoid this or having to run the uninstall target before every update we make
+it easy to delete everything by using a custom prefix. You're free to use
+whatever prefix you like, but grim uses `~/l`. The `l` is just an abbreviation
+of `local` and is less likely to be confused with `~/.local` which is something
+[completely different](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
+
+To set the prefix we pass it as an argument to meson during initial
+configuration via `meson --prefix=~/l build` or after the fact using
+`meson configure --prefix=~/l` from an existing build directory.
+
+Now that the prefix is setup we can start talking about the main developer
+scripts. They are `dev-log-grep`, `dev-pidgin`, `local-pidgin`, and `dev-glade`.
+
+`dev-log-grep` is to help sort through the compiler output as there are
+currently many deprecation warnings that we're slowing churning through. Next
+we have `dev-pidgin` and `local-pidgin` which are used to run Pidgin 3 from
+a build directory and a local installation respectively. Finally, we have
+`dev-glade` which is used to create and edit our user interface templates in
+Glade.
+
+These scripts need to be available on your `PATH`. Typically people put these
+in `~/bin` or `~/.local/bin` and will need to be added to your `PATH`
+environment variable via your shell's initialization which is outside of the
+scope of this document.
+
+## dev-log-grep
+
+`dev-log-grep` is a simple script that uses grep to ignore the deprecation
+warnings from the compiler output. However, it was built to run after the build.
+This works best when doing a clean build, that is running `ninja clean` before
+running `ninja` but that isn't necessary. However, you need to slightly modify
+your `ninja` command to make this work. The ninja command you need to use is
+`ninja |& tee log`. This will run the build like normal, then you can use
+`dev-log-grep` to see the warnings that we aren't ignoring.
+
+The contents of `dev-log-grep` can be found below.
+
+```
+#!/bin/sh
+
+grep -i warning log | grep -vi deprec | grep -vi "failed to parse" | grep -vi "bare structure or union" | grep -vi "callbacks cannot be return values" | grep -v "Unresolved type"
+```
+
+## dev-pidgin
+
+The contents of `dev-pidgin` are below. You can tweak them as necessary, but
+we'll walk through what it does.
+
+```sh
+#!/bin/sh -e
+
+PREFIX="gdb --args"
+#PREFIX="valgrind --leak-check=full --suppressions=/usr/share/glib-2.0/valgrind/glib.supp --suppressions=/usr/share/gtk-3.0/valgrind/gtk.supp"
+
+export LD_LIBRARY_PATH=libpurple/:pidgin/
+
+${PREFIX} pidgin/pidgin3 \
+	--gapplication-app-id=im.pidgin.dev \
+	--config ~/.pidgin3-dev \
+	--debug \
+	${@}
+```
+
+The first line sets up our shell interpreter and tells it to exit on the first
+error it encounters. Lines 3 and 4 are an optional prefix we can use to run
+Pidgin 3 in either gdb or valgrind.
+
+We use gdb for debugging and valgrind for finding memory leaks and other memory
+errors. The paths for the valgrind suppressions are distribution dependent and
+may not be available on distributions. The ones listed here are from a Debian
+system. Only one of these can be used at a time so just make sure to uncomment
+the one you would like to use.
+
+Next we update `LD_LIBRARY_PATH` to tell the dynamic linker where to find the
+libraries that are part of our build. If you're on MacOS you'll need to set
+`DYLIB_LIBRARY_PATH` instead.
+
+Finally we have the command that will actually run Pidgin 3. It uses the prefix
+variable if defined, then specifies the `pidgin3` executable to run.  The
+`--gapplication-app-id` argument is used to uniquely identify this instance of
+Pidgin 3. This identifier is used to allow only one instance matching this
+identifier to run at a time.
+
+The `--config` argument specifies where Pidgin 3 will store it's configuration
+data. Next the `--debug` argument tells Pidgin to output all of the debug
+statements to the console. Finally `${@}` will pass any arguments that were
+passed to `dev-pidgin` to be passed to `pidgin3` executable.
+
+## local-pidgin
+
+`local-pidgin` is nearly identical to `dev-pidgin` so we won't go into much
+depth as most of it is already covered above. The point of `local-pidgin` is
+to be able to run `pidgin3` from an installed prefix that is not `/usr` or
+`/usr/local`. In the example below we have Pidgin 3 installed with a prefix of
+`~/l` like we discussed earlier.
+
+```
+#!/bin/sh -e
+
+PREFIX="gdb --args"
+#PREFIX="valgrind --leak-check=full --suppressions=/usr/share/glib-2.0/valgrind/glib.supp --suppressions=/usr/share/gtk-3.0/valgrind/gtk.supp"
+
+export LD_LIBRARY_PATH=~/l/lib/x86_64-linux-gnu
+
+${PREFIX} ~/l/bin/pidgin3 \
+	--gapplication-app-id=im.pidgin.local \
+	--config ~/.pidgin3-local \
+	--debug \
+	${@}
+```
+
+Since this is for the installed version of Pidgin 3 we just need to point to
+everything for that installation. That means updating `LD_LIBARY_PATH`, or
+`DYLIB_LIBRARY_PATH` if your one Mac OS, as well as changing path to the
+`pidgin3` executable.
+
+Finally we set a separate application id as well as configuration directory.
+These do not need to be different than the ones from `dev-pidgin` but if you
+want to run both instances for testing things this makes it easier.
+
+## dev-pidgin-glade
+
+`dev-pidgin-glade` is the last of our development scripts. Its purpose is to
+allow developers to create and modify glade templates for Pidgin 3. This works
+by the use of a Glade catalog for the Pidgin widgets. However, in this intro
+we're just going to cover how to edit templates for Pidgin 3 but not adding
+new widgets to the catalog.
+
+This script is designed to be run from a Pidgin 3 build directory after Pidgin 3
+has been built. This is necessary so that Glade can actually load the required
+libraries and catalogs.
+
+Note this currently depends on
+[review request 747](https://reviews.imfreedom.org/r/747/).
+
+```
+#!/bin/sh
+
+export LD_LIBRARY_PATH=pidgin/:libpurple/:subprojects/talkatu/talkatu:subprojects/gplugin/gplugin-gtk/
+
+export GLADE_CATALOG_SEARCH_PATH=pidgin/glade:subprojects/gplugin/gplugin-gtk:subprojects/talkatu/talkatu
+
+glade ${@}
+```
+
+Like the other script here, this one sets up `LD_LIBRARY_PATH` to point to the
+libraries in the build directory. Remember if you're on Mac OS this needs to be
+`DYLIB_LIBRARY_PATH`.
+
+Next, we tell Glade where to find the catalogs for Pidgin, GPluginGtk, and
+Talkatu all of which are we should be building.
+
+With everything set up we can finally run glade passing along any arguments that
+were passed to our script.
+
+---
+
+We hope you all found this information useful and we will keep this post updated
+in the future.
+
