diff --git a/osx.sh b/osx.sh
new file mode 100755
index 00000000..ca05ffde
--- /dev/null
+++ b/osx.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# OS X Build script wrapper around the py2app script.
+# These build can only be generated on OS X.
+# Requires all build dependencies for Bitmessage
+
+export ARCHFLAGS="-arch i386 -arch x86_64" 
+
+if [[ -z "$1" ]]; then
+  echo "Please supply a version number for this release as the first argument."
+  exit
+fi
+
+echo "Creating OS X packages for Bitmessage. This script will ask for sudo to create the dmg volume"
+
+cd src && python build_osx.py py2app
+
+if [[ $? = "0" ]]; then
+  sudo hdiutil create -fs HFS+ -volname "Bitmessage" -srcfolder dist/Bitmessage.app dist/bitmessage-v$1.dmg
+else
+  echo "Problem creating Bitmessage.app, stopping."
+  exit
+fi
diff --git a/src/build_osx.py b/src/build_osx.py
new file mode 100644
index 00000000..ded1be4a
--- /dev/null
+++ b/src/build_osx.py
@@ -0,0 +1,71 @@
+"""
+py2app/py2exe build script for Bitmessage
+
+Usage (Mac OS X):
+     python setup.py py2app
+
+Usage (Windows):
+     python setup.py py2exe
+"""
+
+import sys, os, shutil, re
+from setuptools import setup
+
+
+name = "Bitmessage"
+mainscript = 'bitmessagemain.py'
+version = "0.3.3"
+
+if sys.platform == 'darwin':
+    extra_options = dict(
+        setup_requires=['py2app'],
+        app=[mainscript],
+        options=dict(py2app=dict(argv_emulation=True,
+                                 includes = ['PyQt4.QtCore','PyQt4.QtGui', 'sip', 'sqlite'],
+                                 packages = ['bitmessageqt'],
+                                 iconfile='images/bitmessage.icns',
+                                 resources=["images"])),
+    )
+elif sys.platform == 'win32':
+    extra_options = dict(
+        setup_requires=['py2exe'],
+        app=[mainscript],
+    )
+else:
+    extra_options = dict(
+        # Normally unix-like platforms will use "setup.py install"
+        # and install the main script as such
+        scripts=[mainscript],
+    )
+
+setup(
+    name = name,
+    version = version,
+    **extra_options
+)
+from distutils import dir_util
+
+if sys.platform == 'darwin':
+    resource = "dist/" + name + ".app/Contents/Resources/"
+
+    # Try to locate qt_menu
+    # Let's try the port version first!
+    if os.path.isfile("/opt/local/lib/Resources/qt_menu.nib"):
+      qt_menu_location = "/opt/local/lib/Resources/qt_menu.nib"
+    else:
+      # No dice? Then let's try the brew version
+      qt_menu_location = os.popen("find /usr/local/Cellar -name qt_menu.nib | tail -n 1").read()
+      qt_menu_location = re.sub('\n','', qt_menu_location)
+
+    if(len(qt_menu_location) == 0):
+      print "Sorry couldn't find your qt_menu.nib this probably won't work"
+    else:
+      print "Found your qib: " + qt_menu_location
+
+    # Need to include a copy of qt_menu.nib
+    shutil.copytree(qt_menu_location, resource + "qt_menu.nib")
+    # Need to touch qt.conf to avoid loading 2 sets of Qt libraries
+    fname = resource + "qt.conf"
+    with file(fname, 'a'):
+        os.utime(fname, None)
+
diff --git a/src/images/bitmessage.icns b/src/images/bitmessage.icns
new file mode 100644
index 00000000..a796f9d4
Binary files /dev/null and b/src/images/bitmessage.icns differ