diff --git a/spiderweb/tests/test_spiderweb.py b/docs/.nojekyll
similarity index 100%
rename from spiderweb/tests/test_spiderweb.py
rename to docs/.nojekyll
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..9365dac
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,44 @@
+# spiderweb
+
+As a professional web developer focusing on arcane uses of Django for arcane purposes, it occurred to me a little while ago that I didn't actually know how a web framework _worked_.
+
+> So I built one.
+
+This is `spiderweb`, a web framework that's just big enough to hold a spider. When building it, my goals were simple:
+
+- Learn a lot
+- Create an unholy blend of Django and Flask
+- Not look at any existing code. Go off of vibes alone and try to solve all the problems I could think of in my own way
+
+> [!WARNING]
+> This is a learning project. It should not be used for production without heavy auditing. It's not secure. It's not fast. It's not well-tested. It's not well-documented. It's not well-anything. It's a learning project.
+>
+> That being said, it's fun and it works, so I'm counting that as a win.
+
+
+Here's a non-exhaustive list of things this can do:
+
+ * Function-based views
+ * Optional Flask-style URL routing
+ * Optional Django-style URL routing
+ * URLs with variables in them a lá Django
+ * Full middleware implementation
+ * Limit routes by HTTP verbs
+ * (Only GET and POST are implemented right now)
+ * Custom error routes
+ * Built-in dev server
+ * Gunicorn support
+ * HTML templates with Jinja2
+ * Static files support
+ * Cookies (reading and setting)
+ * Optional append_slash (with automatic redirects!)
+ * ~~CSRF middleware implementation~~ (it's there, but it's crappy and unsafe. This might be beyond my skillset.)
+ * Optional POST data validation middleware with Pydantic
+ * Database support (using Peewee, but the end user can use whatever they want as long as there's a Peewee driver for it)
+ * Session middleware with built-in session store
+ * Tests (currently a little over 80% coverage)
+
+The TODO list:
+
+ * Fix CSRF middleware
+ * Add more HTTP verbs
diff --git a/docs/_media/DMSans-Bold.ttf b/docs/_media/DMSans-Bold.ttf
new file mode 100644
index 0000000..9e0ffa3
--- /dev/null
+++ b/docs/_media/DMSans-Bold.ttf
@@ -0,0 +1 @@
+https://www.hubspot.com/hubfs/brand-kit-generator/prototype/fonts/DMSans-Bold.ttf
\ No newline at end of file
diff --git a/docs/_media/DMSans-Medium.ttf b/docs/_media/DMSans-Medium.ttf
new file mode 100644
index 0000000..841d31d
Binary files /dev/null and b/docs/_media/DMSans-Medium.ttf differ
diff --git a/docs/_media/Favicon-32x32.png b/docs/_media/Favicon-32x32.png
new file mode 100644
index 0000000..ed5c9a5
Binary files /dev/null and b/docs/_media/Favicon-32x32.png differ
diff --git a/docs/_media/favicon.png b/docs/_media/favicon.png
new file mode 100644
index 0000000..ed5c9a5
Binary files /dev/null and b/docs/_media/favicon.png differ
diff --git a/docs/_media/spiderweb_logo.png b/docs/_media/spiderweb_logo.png
new file mode 100644
index 0000000..91b7c9a
Binary files /dev/null and b/docs/_media/spiderweb_logo.png differ
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
new file mode 100644
index 0000000..1a1fd70
--- /dev/null
+++ b/docs/_sidebar.md
@@ -0,0 +1,6 @@
+- [home](README.md)
+- [quickstart](quickstart.md)
+- [responses](responses.md)
+- Middleware
+ - [middleware](middleware/test.md)
+ - [middleware2](middleware/test2.md)
\ No newline at end of file
diff --git a/docs/example.md b/docs/example.md
new file mode 100644
index 0000000..b1289fd
--- /dev/null
+++ b/docs/example.md
@@ -0,0 +1,12 @@
+
+> [!ATTENTION]
+> An alert of type 'attention' using global style 'callout'.
+
+> [!TIP]
+> An alert of type 'tip' using global style 'callout'.
+
+> [!WARNING]
+> An alert of type 'warning' using global style 'callout'.
+
+> [!NOTE]
+> An alert of type 'note' using global style 'callout'.
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..b4b94b8
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/middleware/test.md b/docs/middleware/test.md
new file mode 100644
index 0000000..5e40c08
--- /dev/null
+++ b/docs/middleware/test.md
@@ -0,0 +1 @@
+asdf
\ No newline at end of file
diff --git a/docs/middleware/test2.md b/docs/middleware/test2.md
new file mode 100644
index 0000000..eb0fb96
--- /dev/null
+++ b/docs/middleware/test2.md
@@ -0,0 +1 @@
+asdfawaasdf
\ No newline at end of file
diff --git a/docs/quickstart.md b/docs/quickstart.md
new file mode 100644
index 0000000..046291f
--- /dev/null
+++ b/docs/quickstart.md
@@ -0,0 +1,93 @@
+# quickstart
+
+Start by installing the package with your favorite package manager:
+
+
+
+
+
+```shell
+poetry add spiderweb-framework
+```
+
+
+
+```shell
+pip install spiderweb-framework
+```
+
+
+
+```shell
+pipenv install spiderweb-framework
+```
+
+
+
+Then, create a new file and drop this in it:
+
+```python
+from spiderweb import SpiderwebRouter
+from spiderweb.response import HttpResponse
+
+app = SpiderwebRouter()
+
+@app.route("/")
+def index(request):
+ return HttpResponse("HELLO, WORLD!")
+
+if __name__ == "__main__":
+ app.start()
+```
+
+Start the dev server by running `python {yourfile.py}` and navigating to `http://localhost:8000/` in your browser. You should see `HELLO, WORLD!` displayed on the page. Press `Ctrl+C` to stop the server.
+
+That's it! You've got a working web app. Let's take a look at what these few lines of code are doing:
+
+```python
+from spiderweb import SpiderwebRouter
+```
+
+The `SpiderwebRouter` class is the main object that everything stems from in `spiderweb`. It's where you'll set your options, your routes, and more.
+
+```python
+from spiderweb.response import HttpResponse
+```
+
+Rather than trying to infer what you want, spiderweb wants you to be specific about what you want it to do. Part of that is the One Response Rule:
+
+> Every view must return a Response, and each Response must be a specific type.
+
+There are four different types of responses; if you want to skip ahead, hop over to [the responses page](responses.md) to learn more. For this example, we'll focus on `HttpResponse`, which is the base response.
+
+```python
+app = SpiderwebRouter()
+```
+
+This line creates a new instance of the `SpiderwebRouter` class and assigns it to the variable `app`. This is the object that will handle all of your requests and responses. If you need to pass any options into spiderweb, you'll do that here.
+
+```python
+@app.route("/")
+def index(request):
+ return HttpResponse("HELLO, WORLD!")
+```
+
+This is an example view. There are a few things to note here:
+
+- The `@app.route("/")` decorator tells spiderweb that this view should be called when the user navigates to the root of the site.
+- The `def index(request):` function is the view itself. It takes a single argument, `request`, which is a `Request` object that contains all the information about the incoming request.
+- The `return HttpResponse("HELLO, WORLD!")` line is the response. In this case, it's a simple `HttpResponse` object that contains the string `HELLO, WORLD!`. This will be sent back to the user's browser.
+
+> [!TIP]
+> Every view must accept a `request` object as its first argument. This object contains all the information about the incoming request, including headers, cookies, and more.
+>
+> There's more that we can pass in, but for now, we'll keep it simple.
+
+```python
+if __name__ == "__main__":
+ app.start()
+```
+
+Once you finish setting up your app, it's time to start it! You can start the dev server by just calling `app.start()` (and its counterpart `app.stop()` to stop it). This will start a simple server on `localhost:8000` that you can access in your browser. It's not a secure server; don't even think about using it in production. It's just good enough for development.
+
+Now that your app is done, you can also run it with Gunicorn by running `gunicorn --workers=2 {yourfile}:app` in your terminal. This will start a Gunicorn server on `localhost:8000` that you can access in your browser and is a little more robust than the dev server.
\ No newline at end of file
diff --git a/docs/responses.md b/docs/responses.md
new file mode 100644
index 0000000..4ad160b
--- /dev/null
+++ b/docs/responses.md
@@ -0,0 +1,3 @@
+# responses
+
+...
\ No newline at end of file
diff --git a/test.py b/test.py
new file mode 100644
index 0000000..04eaa41
--- /dev/null
+++ b/test.py
@@ -0,0 +1,40 @@
+from peewee import *
+from playhouse.migrate import SqliteMigrator, migrate
+
+from spiderweb.db import SpiderwebModel
+
+db = SqliteDatabase("people.db")
+migrator = SqliteMigrator(db)
+
+
+class Person(SpiderwebModel):
+ name = CharField()
+ birthday = DateField()
+
+ class Meta:
+ database = db # This model uses the "people.db" database.
+
+
+class Pet(SpiderwebModel):
+ owner = ForeignKeyField(Person, backref="pets")
+ name = CharField(max_length=40)
+ animal_type = CharField()
+ age = IntegerField(null=True)
+ favorite_color = CharField(null=True)
+
+ class Meta:
+ database = db # this model uses the "people.db" database
+
+
+if __name__ == "__main__":
+ db.connect()
+ Pet.check_for_needed_migration()
+ # try:
+ # Pet.check_for_needed_migration()
+ # except:
+ # migrate(
+ # migrator.add_column(
+ # Pet._meta.table_name, 'favorite_color', CharField(null=True)
+ # ),
+ # )
+ db.create_tables([Person, Pet])