diff --git a/.gitignore b/.gitignore
index ea9a2744..ffdd6593 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,6 @@
# Never store certificates.
*.pem
+
+# npm manifest
+package-lock.json
diff --git a/README.npm.md b/README.npm.md
new file mode 100644
index 00000000..ef1bc44a
--- /dev/null
+++ b/README.npm.md
@@ -0,0 +1,39 @@
+# GoatCounter
+
+This package contains the source of [GoatCounter's](https://www.goatcounter.com/) `count.js` and its corresponding TypeScript definitions.
+
+## Installation
+
+```bash
+npm install goatcounter
+```
+
+## Usage
+
+This package facilitates [self-hosting](https://www.goatcounter.com/help/countjs-host) and/or provides TypeScript definitions. It does not intend to be imported as a conventional module.
+
+### Self-Hosting
+
+1. Programmatically copy `./node_modules/goatcounter/public/count.js` to a public webroot directory during your application's build process.
+
+2. Reference the script via relative URL:
+
+ ```html
+
+ ```
+
+### TypeScript
+
+To extend the global `Window` interface with a typed `goatcounter` property, configure TSConfig [`types`](https://www.typescriptlang.org/tsconfig/#types):
+
+```json
+{
+ "compilerOptions": {
+ "types": ["goatcounter"]
+ }
+}
+```
diff --git a/count.d.ts b/count.d.ts
new file mode 100644
index 00000000..a5447a2d
--- /dev/null
+++ b/count.d.ts
@@ -0,0 +1,146 @@
+interface Window {
+ /**
+ * GoatCounter JavaScript API
+ *
+ * @see https://www.goatcounter.com/help/js
+ */
+ goatcounter:
+ | (GoatCounter.Settings &
+ GoatCounter.DataParameters &
+ GoatCounter.Methods)
+ | undefined;
+}
+
+declare namespace GoatCounter {
+ /**
+ * Settings that can be defined via:
+ *
+ * - `window.goatcounter` object, declared _before_ loading `count.js`
+ * - `