diff --git a/djblets/dependencies.py b/djblets/dependencies.py
index 6c226df8f86979e75168a5cc0d061dc45a58732b..8612c91983136f9d90dc985ffa607d49d16e2f36 100644
--- a/djblets/dependencies.py
+++ b/djblets/dependencies.py
@@ -66,6 +66,12 @@ frontend_buildkit_npm_dependencies = {
     '@beanbag/frontend-buildkit': (
         os.environ.get('BEANBAG_FRONTEND_BUILDKIT_PATH') or
         '^1.1.0'),
+
+    # Consumers are required to provide their own Spina file on any pages
+    # using it, but this is still needed for types.
+    '@beanbag/spina': (
+        os.environ.get('BEANBAG_SPINA_PATH') or
+        '^1.0.1'),
 }
 
 #: Dependencies required for static media linting.
diff --git a/package-lock.json b/package-lock.json
index b2fc36c44559f3394a168fa58e4d56cc4c93c70b..6f3dc4f0e27985340490373a921d615c0b51434d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
       "dependencies": {
         "@beanbag/eslint-plugin": "^1.0.0",
         "@beanbag/frontend-buildkit": "^1.1.0",
+        "@beanbag/spina": "^1.0.1",
         "eslint": "^8.29.0"
       },
       "devDependencies": {}
@@ -1551,6 +1552,16 @@
         "node": ">=4.0.0"
       }
     },
+    "node_modules/@beanbag/spina": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@beanbag/spina/-/spina-1.0.1.tgz",
+      "integrity": "sha512-+aHc68ftnxV6PpwxQ9Z6tBUX3+4dHztfMGAxH8PaEAyd2+0AmCN7C/ONv+B3OgpY/edEh/1zJeLPaJswiONFIA==",
+      "dependencies": {
+        "@types/jquery": "^3.5.16",
+        "@types/underscore": "^1.11.4",
+        "backbone": "^1.4.1"
+      }
+    },
     "node_modules/@eslint/eslintrc": {
       "version": "1.4.1",
       "license": "MIT",
@@ -1754,6 +1765,14 @@
       "version": "1.0.0",
       "license": "MIT"
     },
+    "node_modules/@types/jquery": {
+      "version": "3.5.16",
+      "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.16.tgz",
+      "integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==",
+      "dependencies": {
+        "@types/sizzle": "*"
+      }
+    },
     "node_modules/@types/json-schema": {
       "version": "7.0.11",
       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
@@ -1768,6 +1787,16 @@
       "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
       "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw=="
     },
+    "node_modules/@types/sizzle": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
+      "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ=="
+    },
+    "node_modules/@types/underscore": {
+      "version": "1.11.4",
+      "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz",
+      "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg=="
+    },
     "node_modules/@typescript-eslint/eslint-plugin": {
       "version": "5.48.1",
       "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.1.tgz",
@@ -2313,6 +2342,14 @@
         "@babel/core": "^7.0.0-0"
       }
     },
+    "node_modules/backbone": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.1.tgz",
+      "integrity": "sha512-ADy1ztN074YkWbHi8ojJVFe3vAanO/lrzMGZWUClIP7oDD/Pjy2vrASraUP+2EVCfIiTtCW4FChVow01XneivA==",
+      "dependencies": {
+        "underscore": ">=1.8.3"
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "license": "MIT"
@@ -4029,6 +4066,11 @@
         "node": ">=0.8.0"
       }
     },
+    "node_modules/underscore": {
+      "version": "1.13.6",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
+      "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
+    },
     "node_modules/unicode-canonical-property-names-ecmascript": {
       "version": "2.0.0",
       "license": "MIT",
diff --git a/rollup.config.js b/rollup.config.js
index 475cd0dc1a0d104a28cf22b762b798bf22f38331..3420c7ea38816b03c9a7d1539c8e90b710cebf80 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -11,6 +11,7 @@ const extensions = [
 
 
 const globalsMap = {
+    '@beanbag/spina': 'Spina',
     Backbone: 'Backbone',
     Djblets: 'Djblets',
     django: 'django',
diff --git a/tsconfig.json b/tsconfig.json
index c23ec7864d0775cb6e75baa934902423ad7ed731..ceb10a53e01715f63e91d0bdcb646ecebb96abc5 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -13,6 +13,7 @@
         ],
         "noEmit": true,
         "paths": {
+            "Backbone": ["node_modules/@beanbag/spina/lib/@types/backbone"],
             "djblets/*": ["djblets/static/djblets/js/*"]
         },
         "target": "ESNext"
