diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e0fa957..e4cbda0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -26,4 +26,6 @@ jobs:
- run: npm run format:check
+ - run: npm run typecheck
+
- run: npm run build
diff --git a/.gitignore b/.gitignore
index 0658cf9..d0df3d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
.next
.vercel
node_modules
+*.tsbuildinfo
diff --git a/.oxlintrc.json b/.oxlintrc.json
index bdd0ada..ead5ddc 100644
--- a/.oxlintrc.json
+++ b/.oxlintrc.json
@@ -7,5 +7,6 @@
"rules": {
"no-console": "warn",
"no-unused-vars": "warn"
- }
+ },
+ "ignorePatterns": ["next-env.d.ts", ".next/", "node_modules/"]
}
diff --git a/next-env.d.ts b/next-env.d.ts
new file mode 100644
index 0000000..254b73c
--- /dev/null
+++ b/next-env.d.ts
@@ -0,0 +1,6 @@
+///
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
diff --git a/package-lock.json b/package-lock.json
index 2e0a074..39f28ab 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,11 +24,15 @@
"@tailwindcss/forms": "^0.5.6",
"@tailwindcss/line-clamp": "^0.4.4",
"@tailwindcss/typography": "^0.5.9",
+ "@types/node": "^25.6.1",
+ "@types/react": "^19.2.14",
+ "@types/react-dom": "^19.2.3",
"autoprefixer": "^10.4.15",
"oxfmt": "^0.48.0",
"oxlint": "^1.63.0",
"postcss": "^8.5.10",
- "tailwindcss": "^3.3.3"
+ "tailwindcss": "^3.3.3",
+ "typescript": "^6.0.3"
},
"engines": {
"node": "24.x"
@@ -1731,6 +1735,36 @@
"url": "https://github.com/sponsors/tannerlinsley"
}
},
+ "node_modules/@types/node": {
+ "version": "25.6.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.1.tgz",
+ "integrity": "sha512-coJCN8O1q4AGyyqCAUSP06P+SrMTu18BkEj3NVAK07q6QUneD2wzj3CLv9+yP+BMeZQlMvneXqqvDe3w+xcq7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.19.0"
+ }
+ },
+ "node_modules/@types/react": {
+ "version": "19.2.14",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
+ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.2.0"
+ }
+ },
"node_modules/@workos-inc/node": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/@workos-inc/node/-/node-8.13.0.tgz",
@@ -1962,6 +1996,13 @@
"node": ">=4"
}
},
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -3149,6 +3190,27 @@
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"dev": true
},
+ "node_modules/typescript": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.19.2",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz",
+ "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/update-browserslist-db": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
@@ -4024,6 +4086,31 @@
"resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.14.0.tgz",
"integrity": "sha512-JLANqGy/D6k4Ujmh8Tr25lGimuOXNiaVyXaCAZS0W+1390sADdGnyUdSWNIfd49gebtIxGMij4IktRVzrdr12Q=="
},
+ "@types/node": {
+ "version": "25.6.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.1.tgz",
+ "integrity": "sha512-coJCN8O1q4AGyyqCAUSP06P+SrMTu18BkEj3NVAK07q6QUneD2wzj3CLv9+yP+BMeZQlMvneXqqvDe3w+xcq7g==",
+ "dev": true,
+ "requires": {
+ "undici-types": "~7.19.0"
+ }
+ },
+ "@types/react": {
+ "version": "19.2.14",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
+ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
+ "dev": true,
+ "requires": {
+ "csstype": "^3.2.2"
+ }
+ },
+ "@types/react-dom": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
+ "dev": true,
+ "requires": {}
+ },
"@workos-inc/node": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/@workos-inc/node/-/node-8.13.0.tgz",
@@ -4165,6 +4252,12 @@
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true
},
+ "csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "dev": true
+ },
"detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -4953,6 +5046,18 @@
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"dev": true
},
+ "typescript": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
+ "dev": true
+ },
+ "undici-types": {
+ "version": "7.19.2",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz",
+ "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==",
+ "dev": true
+ },
"update-browserslist-db": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
diff --git a/package.json b/package.json
index be2cf53..8662e77 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,8 @@
"lint": "oxlint",
"lint:fix": "oxlint --fix",
"format": "oxfmt",
- "format:check": "oxfmt --check"
+ "format:check": "oxfmt --check",
+ "typecheck": "tsc --noEmit"
},
"dependencies": {
"@datadog/browser-rum": "^7.0.0",
@@ -26,11 +27,15 @@
"@tailwindcss/forms": "^0.5.6",
"@tailwindcss/line-clamp": "^0.4.4",
"@tailwindcss/typography": "^0.5.9",
+ "@types/node": "^25.6.1",
+ "@types/react": "^19.2.14",
+ "@types/react-dom": "^19.2.3",
"autoprefixer": "^10.4.15",
"oxfmt": "^0.48.0",
"oxlint": "^1.63.0",
"postcss": "^8.5.10",
- "tailwindcss": "^3.3.3"
+ "tailwindcss": "^3.3.3",
+ "typescript": "^6.0.3"
},
"engines": {
"node": "24.x"
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..6e91715
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,33 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "skipLibCheck": true,
+ "strict": true,
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitOverride": true,
+ "noUncheckedIndexedAccess": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": ["./*"]
+ },
+ "allowJs": true
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules"]
+}