diff --git a/README.rst b/README.rst
index 5174f923a994c0632c64a28e626d3588fc5dc7ad..6e07ca139aced110a703e3d1d737ab6e3995f5b3 100644
--- a/README.rst
+++ b/README.rst
@@ -16,6 +16,7 @@ Features
 - A simple ``manage.py`` script.
 - CSS and JS minification using Flask-Assets
 - Easily switch between development and production environments through the MYFLASKAPP_ENV system  variable.
+- Utilizes best practices: `Blueprints <http://flask.pocoo.org/docs/blueprints/>`_ and `Application Factory <http://flask.pocoo.org/docs/patterns/appfactories/>`_ patterns
 
 Screenshots
 -----------
@@ -42,9 +43,10 @@ Inspiration
 -----------
 
 - `Building Websites in Python with Flask <http://maximebf.com/blog/2012/10/building-websites-in-python-with-flask/>`_
+- `Getting Bigger with Flask <http://maximebf.com/blog/2012/11/getting-bigger-with-flask/>`_
 - `Structuring Flask Apps <http://charlesleifer.com/blog/structuring-flask-apps-a-how-to-for-those-coming-from-django/>`_
-- `Flask-Foundation <https://github.com/JackStouffer/Flask-Foundation>`_
-- `flask-basic-registration <https://github.com/mjhea0/flask-basic-registration>`_
+- `Flask-Foundation <https://github.com/JackStouffer/Flask-Foundation>`_ by `@JackStouffer <https://github.com/JackStouffer>`_
+- `flask-basic-registration <https://github.com/mjhea0/flask-basic-registration>`_ by `@mjhea0 <https://github.com/mjhea0>`_
 - `Flask Official Documentation <http://flask.pocoo.org/docs/>`_
 
 
diff --git a/{{cookiecutter.repo_name}}/manage.py b/{{cookiecutter.repo_name}}/manage.py
index a9b19b53679631124d72d47472c068cbf3eb4ec0..4fe3a76e933b3a528d6f8014e662b088ea0ca6be 100644
--- a/{{cookiecutter.repo_name}}/manage.py
+++ b/{{cookiecutter.repo_name}}/manage.py
@@ -1,9 +1,16 @@
 #!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import os
 import sys
 import subprocess
 from flask.ext.script import Manager, Shell, Server
-from {{ cookiecutter.repo_name }} import models
-from {{ cookiecutter.repo_name }}.main import app, db
+from {{cookiecutter.repo_name }} import models
+from {{cookiecutter.repo_name }}.app import create_app
+from {{cookiecutter.repo_name}}.models import db
+
+env = os.environ.get("{{cookiecutter.repo_name | upper }}_ENV", 'prod')
+app = create_app("{{cookiecutter.repo_name}}.settings.{0}Config"
+                    .format(env.capitalize()), env)
 
 manager = Manager(app)
 TEST_CMD = "nosetests"
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/app.py b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/app.py
index 88947a0892e77c8af69b2caa051ae3b684be3d19..f83f4390212962fefa5e0b5fc4ac1b3bd83d8719 100644
--- a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/app.py
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/app.py
@@ -6,19 +6,31 @@ from flask.ext.assets import Environment
 from webassets.loaders import PythonLoader
 
 from {{cookiecutter.repo_name}} import assets
+from {{cookiecutter.repo_name}}.models import db
 
-app = Flask(__name__)
-# The environment variable, either 'prod' or 'dev'
-env = os.environ.get("{{cookiecutter.repo_name | upper}}_ENV", "prod")
-# Use the appropriate environment-specific settings
-app.config.from_object('{{cookiecutter.repo_name}}.settings.{env}Config'
-                        .format(env=env.capitalize()))
-app.config['ENV'] = env
-db = SQLAlchemy(app)
-
-# Register asset bundles
 assets_env = Environment()
-assets_env.init_app(app)
-assets_loader = PythonLoader(assets)
-for name, bundle in assets_loader.load_bundles().iteritems():
-    assets_env.register(name, bundle)
+
+def create_app(config_object, env):
+    '''An application factory, as explained here:
+        http://flask.pocoo.org/docs/patterns/appfactories/
+
+    :param config_object: The configuration object to use.
+    :param env: A string, the current environment. Either "dev" or "prod"
+    '''
+    app = Flask(__name__)
+    app.config.from_object('{{cookiecutter.repo_name}}.settings.{env}Config'
+                            .format(env=env.capitalize()))
+    app.config['ENV'] = env
+    # Initialize SQLAlchemy
+    db.init_app(app)
+    # Register asset bundles
+    assets_env.init_app(app)
+    assets_loader = PythonLoader(assets)
+    for name, bundle in assets_loader.load_bundles().iteritems():
+        assets_env.register(name, bundle)
+    # Register blueprints
+    from {{cookiecutter.repo_name}}.modules import public, member
+    app.register_blueprint(public.blueprint)
+    app.register_blueprint(member.blueprint)
+
+    return app
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/main.py b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/main.py
index 153bad06908f85b4eb8bd5a1369c12d71e08da00..56528350794af0b45590d9e55c01e005a8e75b08 100644
--- a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/main.py
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/main.py
@@ -4,11 +4,12 @@
 Entry point for all things, to avoid circular imports.
 """
 import os
-from .app import app, db, assets_env
-from .models import *
-from .views import *
-
+from .app import create_app
+from .models import User, db
+import {{cookiecutter.repo_name}}.modules as modules
 
 if __name__ == '__main__':
-    port = int(os.environ.get('PORT', 5000))
-    app.run(host='0.0.0.0', port=port)
+    # Get the environment setting from the system environment variable
+    env = os.environ.get("{{cookiecutter.repo_name | upper}}_ENV", "prod")
+    app = create_app("{{cookiecutter.repo_name}}.settings.{env}Config"
+                        .format(env=env.capitalize()), env)
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/models.py b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/models.py
index fa200d2a57e9fc5881af31962be71f2457938c9f..fe93bd5b0b8d9aeca2a19d46c7ff8d83f6b399f8 100644
--- a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/models.py
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/models.py
@@ -3,7 +3,9 @@
 """
 {{cookiecutter.project_name}} models.
 """
-from .app import db
+from flask.ext.sqlalchemy import SQLAlchemy
+
+db = SQLAlchemy()
 
 class User(db.Model):
 
@@ -22,5 +24,3 @@ class User(db.Model):
 
     def __repr__(self):
         return '<User "{username}">'.format(username=self.username)
-
-db.create_all()
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/__init__.py b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..33bdd6a83587b4b9fd908dc91f2fd7011725f74f
--- /dev/null
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/__init__.py
@@ -0,0 +1 @@
+'''Blueprint modules for {{cookiecutter.repo_name}}.'''
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/member.py b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/member.py
new file mode 100644
index 0000000000000000000000000000000000000000..e732f6ea5c010d5d802c0130ca5e5dfecbf1701e
--- /dev/null
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/member.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+'''Members-only module, typically including the app itself.
+'''
+from flask import Blueprint, render_template
+from {{cookiecutter.repo_name}}.utils import login_required
+
+blueprint = Blueprint('member', __name__,
+                        static_folder="../static",
+                        template_folder="../templates")
+
+@blueprint.route("/members/")
+@login_required
+def members():
+    return render_template("members.html")
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/views.py b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/public.py
similarity index 54%
rename from {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/views.py
rename to {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/public.py
index 6ed52085befe2d882f5e8f3c367708633749fb5f..d69025df38512e5697d3c1539836d6b80431a731 100644
--- a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/views.py
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/public.py
@@ -1,29 +1,20 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-from flask import render_template, session, request, flash, redirect, url_for
-from functools import wraps
-from .app import app, db
-from .models import User
-from .forms import RegisterForm, LoginForm
+'''Public section, including homepage and signup.'''
+from flask import (Blueprint, request, render_template, flash, url_for,
+                    redirect, session)
 from sqlalchemy.exc import IntegrityError
 
-def flash_errors(form):
-    for field, errors in form.errors.items():
-        for error in errors:
-            flash("Error in the {0} field - {1}"
-                    .format(getattr(form, field).label.text, error), 'error')
+from {{cookiecutter.repo_name}}.models import User
+from {{cookiecutter.repo_name}}.forms import RegisterForm, LoginForm
+from {{cookiecutter.repo_name}}.utils import flash_errors
+from {{cookiecutter.repo_name}}.models import db
+
+blueprint = Blueprint('public', __name__,
+                        static_folder="../static",
+                        template_folder="../templates")
 
-def login_required(test):
-    @wraps(test)
-    def wrap(*args, **kwargs):
-        if 'logged_in' in session:
-            return test(*args, **kwargs)
-        else:
-            flash('You need to log in first.')
-            return redirect(url_for('home'))
-    return wrap
 
-@app.route("/", methods=["GET", "POST"])
+@blueprint.route("/", methods=["GET", "POST"])
 def home():
     form = LoginForm(request.form)
     if request.method == 'POST':
@@ -31,29 +22,22 @@ def home():
                                 password=request.form['password']).first()
         if u is None:
             error = 'Invalid username or password.'
-            flash(error, 'error')
+            flash(error, 'warning')
         else:
             session['logged_in'] = True
             session['username'] = u.username
             flash("You are logged in.", 'success')
-            return redirect(url_for("members"))
+            return redirect(url_for("member.members"))
     return render_template("home.html", form=form)
 
-
-@app.route("/members/")
-@login_required
-def members():
-    return render_template("members.html")
-
-
-@app.route('/logout/')
+@blueprint.route('/logout/')
 def logout():
     session.pop('logged_in', None)
     session.pop('username', None)
     flash('You are logged out.', 'info')
-    return redirect(url_for('home'))
+    return redirect(url_for('public.home'))
 
-@app.route("/register/", methods=['GET', 'POST'])
+@blueprint.route("/register/", methods=['GET', 'POST'])
 def register():
     form = RegisterForm(request.form, csrf_enabled=False)
     if form.validate_on_submit():
@@ -62,21 +46,19 @@ def register():
             db.session.add(new_user)
             db.session.commit()
             flash("Thank you for registering. You can now log in.", 'success')
-            return redirect(url_for('home'))
+            return redirect(url_for('public.home'))
         except IntegrityError as err:
             print(err)
-            flash("That username and/or email already exists. Try again.", 'error')
+            flash("That username and/or email already exists. Try again.", 'warning')
     else:
         flash_errors(form)
     return render_template('register.html', form=form)
 
-
-@app.route("/about/")
+@blueprint.route("/about/")
 def about():
     form = LoginForm(request.form)
     return render_template("about.html", form=form)
 
-
-@app.errorhandler(404)
+@blueprint.errorhandler(404)
 def page_not_found(e):
     return render_template("404.html"), 404
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/settings.py b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/settings.py
index 574df755b1bc0c506f8978f809a3a50bcebeb8f6..243bda4e872144a098fc489649e96a479b421b71 100644
--- a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/settings.py
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/settings.py
@@ -18,6 +18,3 @@ class DevConfig(Config):
     DB_PATH = os.path.join(Config.PROJECT_ROOT, DB_NAME)
     SQLALCHEMY_DATABASE_URI = "sqlite:///{0}".format(DB_PATH)
     SQLALCHEMY_ECHO = True
-
-
-
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/_layouts/footer.html b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/_layouts/footer.html
index da563ebfa2e9041151a3433b8cb00ba3d26fa873..5f4bf3af82213f02ab615275bd2474055e52bf68 100644
--- a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/_layouts/footer.html
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/_layouts/footer.html
@@ -6,9 +6,9 @@
 
     <ul class="footer-nav">
 {% raw %}
-      <li><a href="{{ url_for('about') }}">About</a></li>
+      <li><a href="{{ url_for('public.about') }}">About</a></li>
 {% endraw %}
       <li><a href="mailto:{{ cookiecutter.email }}">Contact</a></li>
     </ul>
   </small>
-</footer>
\ No newline at end of file
+</footer>
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/_layouts/nav.html b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/_layouts/nav.html
index 479b970c1a26857e84ccd65227e8edbf4c6e2e0c..7406f4984f6313d5fdfa9dd14b731bbc36ee7c89 100644
--- a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/_layouts/nav.html
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/_layouts/nav.html
@@ -8,7 +8,7 @@
       <span class="icon-bar"></span>
       <span class="icon-bar"></span>
     </button>
-    <a class="navbar-brand" href="{{ url_for('home') }}">
+    <a class="navbar-brand" href="{{ url_for('public.home') }}">
 {% endraw %}
       {{cookiecutter.project_name}}
 {% raw %}
@@ -17,17 +17,17 @@
   <!-- Collect the nav links, forms, and other content for toggling -->
   <div class="collapse navbar-collapse navbar-ex1-collapse">
     <ul class="nav navbar-nav">
-      <li class="active"><a href="{{ url_for('home') }}">Home</a></li>
-      <li><a href="{{ url_for('about') }}">About</a></li>
+      <li class="active"><a href="{{ url_for('public.home') }}">Home</a></li>
+      <li><a href="{{ url_for('public.about') }}">About</a></li>
     </ul>
     {% if session.logged_in %}
-    <a class="btn btn-default btn-sm navbar-btn navbar-right" href="{{ url_for('logout') }}">Log out</a>
+    <a class="btn btn-default btn-sm navbar-btn navbar-right" href="{{ url_for('public.logout') }}">Log out</a>
     <ul class="nav navbar-nav navbar-right">
-      <li><a href="{{ url_for('members') }}">Logged in as {{ session.username }}</a></li>
+      <li><a href="{{ url_for('member.members') }}">Logged in as {{ session.username }}</a></li>
     </ul>
     {% elif form %}
     <ul class="nav navbar-nav navbar-right">
-      <li><a href="{{ url_for('register') }}">Create account</a></li>
+      <li><a href="{{ url_for('public.register') }}">Create account</a></li>
     </ul>
     <form method="POST" class="navbar-form form-inline navbar-right" action="" role="login">
       {{ form.hidden_tag() }}
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/tests/unit_tests.py b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/tests/unit_tests.py
index 653984a08079161f168f450e2af6a8a08182b6fc..51fbb28f0a5106b88c0dc5ed9951d9205047369e 100644
--- a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/tests/unit_tests.py
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/tests/unit_tests.py
@@ -7,11 +7,12 @@ except ImportError:
     import sys
     print('nose required. Run "pip install nose".')
 
-from {{cookiecutter.repo_name}}.main import app
+from {{cookiecutter.repo_name}}.main import create_app
 
 class Test{{cookiecutter.repo_name | capitalize}}(unittest.TestCase):
 
     def setUp(self):
+        app = create_app("{{cookiecutter.repo_name}}.settings.DevConfig", 'dev')
         app.config['TESTING'] = True
         self.app = app.test_client()
 
diff --git a/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/utils.py b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..61cbe740ea8c91ac8f9bc7e351a1be38314e3c6f
--- /dev/null
+++ b/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/utils.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+'''Helper utilities and decorators.'''
+from flask import session, flash, redirect, url_for
+from functools import wraps
+
+def flash_errors(form):
+    '''Flash all errors for a form.'''
+    for field, errors in form.errors.items():
+        for error in errors:
+            flash("Error in the {0} field - {1}"
+                    .format(getattr(form, field).label.text, error), 'warning')
+
+def login_required(test):
+    '''Decorator that makes a view require authentication.'''
+    @wraps(test)
+    def wrap(*args, **kwargs):
+        if 'logged_in' in session:
+            return test(*args, **kwargs)
+        else:
+            flash('You need to log in first.')
+            return redirect(url_for('home'))
+    return wrap