diff --git a/.github/workflows/publish-develop-docs.yml b/.github/workflows/publish-develop-docs.yml
index 584be64..a1434ba 100644
--- a/.github/workflows/publish-develop-docs.yml
+++ b/.github/workflows/publish-develop-docs.yml
@@ -4,7 +4,7 @@ on:
     branches:
       - main
 jobs:
-  deploy:
+  publish-develop-docs:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
@@ -17,14 +17,12 @@ jobs:
         with:
           python-version: 3.x
       - name: Install dependencies
-        run: |
-          pip install --upgrade hatch uv
+        run: pip install --upgrade pip hatch uv
       - name: Configure Git
         run: |
           git config user.name github-actions
           git config user.email github-actions@github.com
       - name: Publish Develop Docs
-        run: |
-          hatch run docs:deploy_develop
+        run: hatch run docs:deploy_develop
     concurrency:
       group: publish-docs
diff --git a/.github/workflows/publish-latest-docs.yml b/.github/workflows/publish-latest-docs.yml
index 3ff83a7..0a1e996 100644
--- a/.github/workflows/publish-latest-docs.yml
+++ b/.github/workflows/publish-latest-docs.yml
@@ -18,13 +18,12 @@ jobs:
           python-version: 3.x
       - name: Install dependencies
         run: |
-          pip install --upgrade hatch uv
+          pip install --upgrade pip hatch uv
       - name: Configure Git
         run: |
           git config user.name github-actions
           git config user.email github-actions@github.com
-      - name: Publish Develop Docs
-        run: |
-          hatch run docs:deploy_latest ${{ github.ref_name }}
+      - name: Publish ${{ github.event.release.name }} Docs
+        run: hatch run docs:deploy_latest ${{ github.ref_name }}
     concurrency:
       group: publish-docs
diff --git a/.github/workflows/publish-py.yaml b/.github/workflows/publish-py.yaml
deleted file mode 100644
index d69b475..0000000
--- a/.github/workflows/publish-py.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-# This workflows will upload a Python Package using Twine when a release is created
-# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
-
-name: Publish Python
-
-on:
-  release:
-    types: [published]
-
-jobs:
-  publish-package:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-      - uses: oven-sh/setup-bun@v2
-        with:
-          bun-version: latest
-      - name: Set up Python
-        uses: actions/setup-python@v5
-        with:
-          python-version: "3.x"
-      - name: Install dependencies
-        run: |
-          pip3 --quiet install --upgrade hatch uv twine
-      - name: Build Package
-        run: |
-          hatch build --clean
-      - name: Publish to PyPI
-        env:
-          TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
-          TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
-        run: |
-          twine upload dist/*
diff --git a/.github/workflows/publish-python.yaml b/.github/workflows/publish-python.yaml
new file mode 100644
index 0000000..a2228a7
--- /dev/null
+++ b/.github/workflows/publish-python.yaml
@@ -0,0 +1,27 @@
+name: Publish Python
+
+on:
+  release:
+    types: [published]
+
+jobs:
+  publish-python:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: oven-sh/setup-bun@v2
+        with:
+          bun-version: latest
+      - name: Set up Python
+        uses: actions/setup-python@v5
+        with:
+          python-version: "3.x"
+      - name: Install dependencies
+        run: pip install --upgrade pip hatch uv
+      - name: Build Package
+        run: hatch build --clean
+      - name: Publish to PyPI
+        env:
+          HATCH_INDEX_USER: ${{ secrets.PYPI_USERNAME }}
+          HATCH_INDEX_AUTH: ${{ secrets.PYPI_PASSWORD }}
+        run: hatch publish --yes
diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml
index 6a4de7b..0a81d18 100644
--- a/.github/workflows/test-docs.yml
+++ b/.github/workflows/test-docs.yml
@@ -24,12 +24,10 @@ jobs:
         with:
           python-version: 3.x
       - name: Install Python Dependencies
-        run: |
-          pip3 --quiet install --upgrade hatch uv ruff
+        run: pip install --upgrade pip hatch uv
+      - name: Check documentation links
+        run: hatch run docs:linkcheck
       - name: Check docs build
-        run: |
-          hatch run docs:build
-          hatch run docs:linkcheck
+        run: hatch run docs:build
       - name: Check docs examples
-        run: |
-          ruff check docs/examples/python/
+        run: hatch fmt docs --check
diff --git a/.github/workflows/test-style.yml b/.github/workflows/test-javascript.yml
similarity index 70%
rename from .github/workflows/test-style.yml
rename to .github/workflows/test-javascript.yml
index c1e45ab..5f62c0e 100644
--- a/.github/workflows/test-style.yml
+++ b/.github/workflows/test-javascript.yml
@@ -1,4 +1,4 @@
-name: Test Style
+name: Test
 
 on:
   push:
@@ -9,7 +9,7 @@ on:
       - main
 
 jobs:
-  test-style:
+  javascript:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
@@ -18,10 +18,8 @@ jobs:
           bun-version: latest
       - uses: actions/setup-python@v5
         with:
-          python-version: "3.x"
+          python-version: 3.x
       - name: Install Python Dependencies
-        run: |
-          pip3 install hatch uv
+        run: pip install --upgrade pip hatch uv
       - name: Run Tests
-        run: |
-          hatch fmt --check
+        run: hatch run javascript:check
diff --git a/.github/workflows/test-src.yml b/.github/workflows/test-python.yml
similarity index 73%
rename from .github/workflows/test-src.yml
rename to .github/workflows/test-python.yml
index 6f1aebf..9390316 100644
--- a/.github/workflows/test-src.yml
+++ b/.github/workflows/test-python.yml
@@ -11,7 +11,7 @@ on:
     - cron: "0 0 * * *"
 
 jobs:
-  source:
+  python-source:
     runs-on: ubuntu-latest
     strategy:
       matrix:
@@ -26,8 +26,7 @@ jobs:
         with:
           python-version: ${{ matrix.python-version }}
       - name: Install Python Dependencies
-        run: |
-          pip3 install hatch uv
+        run: pip install --upgrade pip hatch uv
       - name: Run Tests
         run: |
           hatch test --cover --python ${{ matrix.python-version }}
@@ -40,18 +39,18 @@ jobs:
           if-no-files-found: error
           include-hidden-files: true
           retention-days: 7
-  coverage:
+
+  python-coverage:
     needs:
-      - source
+      - python-source
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
-      - name: Use Latest Python
-        uses: actions/setup-python@v5
+      - uses: actions/setup-python@v5
         with:
           python-version: "3.x"
       - name: Install Python Dependencies
-        run: python -m pip install --upgrade coverage[toml]
+        run: pip install --upgrade coverage[toml]
       - name: Download data
         uses: actions/download-artifact@v4
         with:
@@ -66,3 +65,18 @@ jobs:
         with:
           name: coverage-report
           path: htmlcov
+
+  python-formatting:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: oven-sh/setup-bun@v2
+        with:
+          bun-version: latest
+      - uses: actions/setup-python@v5
+        with:
+          python-version: "3.x"
+      - name: Install Python Dependencies
+        run: pip install --upgrade pip hatch uv
+      - name: Check Python formatting
+        run: hatch fmt src tests --check
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66617e3..e3fa727 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,7 +34,9 @@ Using the following categories, list your changes in this order:
 
 ## [Unreleased]
 
--   Nothing (yet)!
+### Changed
+
+-   Set upper limit on ReactPy version to `<2.0.0`.
 
 ## [1.0.3] - 2024-11-21
 
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index 8f8a1a1..28df470 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -145,6 +145,6 @@ site_description: It's React-Router, but in Python.
 copyright: '&copy;<div id="year"> </div> <script> document.getElementById("year").innerHTML = new Date().getFullYear(); </script>Reactive Python and affiliates.<div class="legal-footer-right">This project has no affiliation to ReactJS or Meta Platforms, Inc.</div>'
 repo_url: https://github.com/reactive-python/reactpy-router
 site_url: https://reactive-python.github.io/reactpy-router
-repo_name: ReactPy Router (GitHub)
+repo_name: ReactPy Router
 edit_uri: edit/main/docs/src/
 docs_dir: src
diff --git a/docs/src/about/contributing.md b/docs/src/about/contributing.md
index d23b77f..c7cf012 100644
--- a/docs/src/about/contributing.md
+++ b/docs/src/about/contributing.md
@@ -5,6 +5,7 @@ If you plan to make code changes to this repository, you will need to install th
 -   [Git](https://git-scm.com/downloads)
 -   [Python 3.9+](https://www.python.org/downloads/)
 -   [Hatch](https://hatch.pypa.io/latest/)
+-   [Bun](https://bun.sh/)
 
 Once you finish installing these dependencies, you can clone this repository:
 
@@ -40,6 +41,8 @@ By utilizing `hatch`, the following commands are available to manage the develop
 | `hatch fmt --check` | Run all linters and formatters, but do not save fixes to the disk |
 | `hatch fmt --linter` | Run only linters |
 | `hatch fmt --formatter` | Run only formatters |
+| `hatch run javascript:check` | Run the JavaScript linter/formatter |
+| `hatch run javascript:fix` | Run the JavaScript linter/formatter and write fixes to disk |
 
 ??? tip "Configure your IDE for linting"
 
@@ -54,6 +57,7 @@ By utilizing `hatch`, the following commands are available to manage the develop
 | `hatch run docs:serve` | Start the [`mkdocs`](https://www.mkdocs.org/) server to view documentation locally |
 | `hatch run docs:build` | Build the documentation |
 | `hatch run docs:linkcheck` | Check for broken links in the documentation |
+| `hatch fmt docs --check` | Run linter on code examples in the documentation |
 
 ### Environment Management
 
diff --git a/docs/src/dictionary.txt b/docs/src/dictionary.txt
index 435700c..b487e39 100644
--- a/docs/src/dictionary.txt
+++ b/docs/src/dictionary.txt
@@ -39,6 +39,7 @@ backhaul
 sublicense
 contravariant
 formatters
+linter
 linters
 linting
 pytest
diff --git a/pyproject.toml b/pyproject.toml
index 956b2a2..6472bdf 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -2,6 +2,10 @@
 build-backend = "hatchling.build"
 requires = ["hatchling", "hatch-build-scripts"]
 
+##############################
+# >>> Hatch Build Config <<< #
+##############################
+
 [project]
 name = "reactpy_router"
 description = "A URL router for ReactPy."
@@ -24,7 +28,7 @@ classifiers = [
   "Environment :: Web Environment",
   "Typing :: Typed",
 ]
-dependencies = ["reactpy>=1.0.0", "typing_extensions"]
+dependencies = ["reactpy>=1.0.0, <2.0.0", "typing_extensions"]
 dynamic = ["version"]
 urls.Changelog = "https://reactive-python.github.io/reactpy-router/latest/about/changelog/"
 urls.Documentation = "https://reactive-python.github.io/reactpy-router/latest/"
@@ -35,10 +39,10 @@ path = "src/reactpy_router/__init__.py"
 
 [tool.hatch.build.targets.sdist]
 include = ["/src"]
-artifacts = ["/src/reactpy_router/static/bundle.js"]
+artifacts = ["/src/reactpy_router/static/"]
 
 [tool.hatch.build.targets.wheel]
-artifacts = ["/src/reactpy_router/static/bundle.js"]
+artifacts = ["/src/reactpy_router/static/"]
 
 [tool.hatch.metadata]
 license-files = { paths = ["LICENSE.md"] }
@@ -53,7 +57,9 @@ commands = [
 ]
 artifacts = []
 
-# >>> Hatch Tests <<<
+#############################
+# >>> Hatch Test Runner <<< #
+#############################
 
 [tool.hatch.envs.hatch-test]
 extra-dependencies = ["pytest-sugar", "anyio", "reactpy[testing,starlette]"]
@@ -63,24 +69,30 @@ matrix-name-format = "{variable}-{value}"
 [[tool.hatch.envs.hatch-test.matrix]]
 python = ["3.9", "3.10", "3.11", "3.12"]
 
-# >>> Hatch Documentation Scripts <<<
+[tool.pytest.ini_options]
+addopts = """\
+    --strict-config
+    --strict-markers
+    """
+
+#######################################
+# >>> Hatch Documentation Scripts <<< #
+#######################################
 
 [tool.hatch.envs.docs]
 template = "docs"
-detached = true
 dependencies = [
   "mkdocs",
   "mkdocs-git-revision-date-localized-plugin",
   "mkdocs-material==9.4.0",
   "mkdocs-include-markdown-plugin",
-  "linkcheckmd",
   "mkdocs-spellcheck[all]",
   "mkdocs-git-authors-plugin",
   "mkdocs-minify-plugin",
   "mike",
   "mkdocstrings[python]",
-  "black",
-  "reactpy_router @ {root:uri}",
+  "black",                                     # Used by mkdocstrings for auto formatting
+  "linkcheckmd",
 ]
 
 [tool.hatch.envs.docs.scripts]
@@ -94,10 +106,23 @@ linkcheck = [
 deploy_latest = ["cd docs && mike deploy --push --update-aliases {args} latest"]
 deploy_develop = ["cd docs && mike deploy --push develop"]
 
+############################
+# >>> Hatch JS Scripts <<< #
+############################
 
-# >>> Generic Tools <<<
+[tool.hatch.envs.javascript]
+detached = true
+
+[tool.hatch.envs.javascript.scripts]
+check = ["cd src/js && bun install", "cd src/js && bun run check"]
+fix = ["cd src/js && bun install", "cd src/js && bun run format"]
+
+#########################
+# >>> Generic Tools <<< #
+#########################
 
 [tool.ruff]
+extend-exclude = [".venv/*", ".eggs/*", "build/*"]
 line-length = 120
 format.preview = true
 lint.extend-ignore = [
@@ -111,13 +136,6 @@ lint.extend-ignore = [
   "SLF001",  # Private member accessed
 ]
 lint.preview = true
-extend-exclude = [".venv/*", ".eggs/*", "build/*"]
-
-[tool.pytest.ini_options]
-addopts = """\
-    --strict-config
-    --strict-markers
-    """
 
 [tool.coverage.run]
 branch = true