{"id":46167174,"url":"https://github.com/matthiasseghers/typescript-userscript-template","last_synced_at":"2026-04-25T12:00:54.541Z","repository":{"id":335843138,"uuid":"1122397350","full_name":"matthiasseghers/typescript-userscript-template","owner":"matthiasseghers","description":"Base template for userscripts, written in TypeScript with full type checking support.","archived":false,"fork":false,"pushed_at":"2026-04-21T14:51:21.000Z","size":353,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-21T16:38:14.261Z","etag":null,"topics":["boilerplate","browser","greasemonkey","starter-template","tampermonkey","template","typescript","userscript","web"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matthiasseghers.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-24T16:32:08.000Z","updated_at":"2026-04-21T14:51:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/matthiasseghers/typescript-userscript-template","commit_stats":null,"previous_names":["matthiasseghers/typescript-userscript-template"],"tags_count":4,"template":true,"template_full_name":null,"purl":"pkg:github/matthiasseghers/typescript-userscript-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthiasseghers%2Ftypescript-userscript-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthiasseghers%2Ftypescript-userscript-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthiasseghers%2Ftypescript-userscript-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthiasseghers%2Ftypescript-userscript-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matthiasseghers","download_url":"https://codeload.github.com/matthiasseghers/typescript-userscript-template/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthiasseghers%2Ftypescript-userscript-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32261124,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T09:15:33.318Z","status":"ssl_error","status_checked_at":"2026-04-25T09:15:31.997Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boilerplate","browser","greasemonkey","starter-template","tampermonkey","template","typescript","userscript","web"],"created_at":"2026-03-02T13:23:56.032Z","updated_at":"2026-04-25T12:00:54.529Z","avatar_url":"https://github.com/matthiasseghers.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TypeScript Userscript Template\n\n[![CI](https://github.com/matthiasseghers/typescript-userscript-template/actions/workflows/ci.yml/badge.svg)](https://github.com/matthiasseghers/typescript-userscript-template/actions/workflows/ci.yml)\n[![Version Bump](https://github.com/matthiasseghers/typescript-userscript-template/actions/workflows/version-bump.yml/badge.svg)](https://github.com/matthiasseghers/typescript-userscript-template/actions/workflows/version-bump.yml)\n[![Release](https://github.com/matthiasseghers/typescript-userscript-template/actions/workflows/release.yml/badge.svg)](https://github.com/matthiasseghers/typescript-userscript-template/actions/workflows/release.yml)\n[![Latest Release](https://img.shields.io/github/v/release/matthiasseghers/typescript-userscript-template)](https://github.com/matthiasseghers/typescript-userscript-template/releases/latest)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA professional template for building userscripts with TypeScript, allowing you to write modular, type-safe, **tested** code that compiles into a single userscript file.\n\n## Why Use This Template?\n\n**Transform your userscript development:**\n\n🎯 **Type Safety** - Catch bugs at compile-time, not in production. TypeScript prevents common errors before they reach users.\n\n📦 **Modularity** - Split monolithic scripts into focused, reusable modules. No more scrolling through 1000+ line files.\n\n🧪 **Built-in Testing** - Write tests with Vitest. Verify your code works before releasing to users.\n\n🔍 **IDE Superpowers** - Full autocomplete for GM APIs, instant refactoring, and go-to-definition across your entire codebase.\n\n🚀 **Modern Tooling** - ESLint, Prettier, Husky, and GitHub Actions already configured. Professional CI/CD out of the box.\n\n⚡ **Tree-Shaking** - Automatically removes unused code. Import large libraries without bloating your userscript.\n\n📚 **Maintainability** - Come back to your project months later and actually understand what you wrote. Clear structure + types = sustainable code.\n\n**Stop fighting with brittle monolithic JavaScript. Start building maintainable, professional userscripts.**\n\n## Installation\n\nDownload the latest built userscript from the [GitHub Releases](https://github.com/\u003cyourusername\u003e/typescript-userscript-template/releases/latest) page and install it in your userscript manager.\n\n*(Replace `yourusername` and `typescript-userscript-template` with your actual GitHub username and repository name)*\n\n\u003e **Note:** `dist/` is gitignored — builds are attached as release artifacts, not committed to the repo.\n\n## Using This Template\n\n**Option 1: Use GitHub Template (Recommended)**\n1. Click the \"**Use this template**\" button at the top of this repository\n2. Choose a name for your new repository\n3. Clone your new repository\n4. Run `npm run setup`\n5. Start coding!\n\n**Option 2: Clone Directly**\n```bash\ngit clone https://github.com/yourusername/typescript-userscript-template.git my-userscript\ncd my-userscript\nrm -rf .git  # Remove template git history\ngit init     # Start fresh\nnpm run setup\n```\n\n### What does `npm run setup` do?\n\nRunning `npm run setup` launches an interactive wizard that configures the template for your project in one go:\n\n- Asks for your userscript name, description, author, GitHub username, and repository name\n- Confirms your inputs before making any changes — restarts if anything looks wrong\n- Patches `package.json`, `meta.json`, `README.md`, and `cliff.toml` with your details\n- Sets `templateMode` to `false` so the CI/CD workflows behave correctly from the start\n- Runs `npm install` automatically\n- Removes template-specific files (`CHANGELOG.md`, `MIGRATION_GUIDE.md`) — git-cliff generates a fresh changelog on your first release\n- Removes itself — the setup script has no place in your actual project\n\nAfter setup completes, everything is configured and ready to go.\n\n## Features\n\n- ✅ **TypeScript Support** - Write your userscripts with full TypeScript features and type checking\n- ✅ **Modular Code** - Split your code into multiple files and modules\n- ✅ **Testing Framework** - Vitest included for unit and integration tests\n- ✅ **Automatic Bundling** - Rollup bundles everything into a single userscript file\n- ✅ **Tree-Shaking** - Unused code is automatically removed from the final bundle\n- ✅ **GM API Support** - Full TypeScript support for Tampermonkey/Greasemonkey APIs\n- ✅ **Userscript Metadata** - Automatically inject userscript headers from `meta.json`\n- ✅ **Development Mode** - Watch mode with inline sourcemaps for debugging\n- ✅ **Code Quality** - ESLint + Prettier for consistent code style\n- ✅ **Pre-commit Hooks** - Automatic validation before commits with Husky\n- ✅ **CI/CD** - GitHub Actions for automated testing and releases\n\n## Project Structure\n\n```\n.\n├── .github/\n│   └── workflows/\n│       ├── ci.yml           # Continuous integration (lint, test, build)\n│       ├── version-bump.yml # Bumps version and pushes tag\n│       └── release.yml      # Builds and publishes GitHub Release\n├── scripts/\n│   └── setup.js       # One-time setup wizard (self-deletes after running)\n├── src/\n│   ├── index.ts       # Main entry point\n│   └── utils.ts       # Utility functions (example)\n├── tests/\n│   ├── utils.test.ts  # Example tests for utilities\n│   └── index.test.ts  # Example tests for main logic\n├── dist/                   # Gitignored — created by build\n│   └── userscript.user.js  # Built userscript (auto-generated)\n├── cliff.toml         # git-cliff changelog configuration\n├── meta.json          # Userscript metadata\n├── vitest.config.ts   # Test configuration\n├── package.json       # Project dependencies\n├── tsconfig.json      # TypeScript configuration\n├── rollup.config.js   # Build configuration\n├── eslint.config.js   # ESLint configuration\n├── .prettierrc        # Prettier configuration\n└── LICENSE            # MIT License\n```\n\n## Quick Start\n\n### 1. Run Setup\n\n```bash\nnpm run setup\n```\n\nThis launches the interactive wizard, patches all files with your project details, and runs `npm install` automatically. See [What does `npm run setup` do?](#what-does-npm-run-setup-do) for details.\n\n### 2. Configure Your Userscript\n\nEdit `meta.json` to customize your userscript metadata:\n\n```json\n{\n  \"name\": \"My TypeScript Userscript\",\n  \"namespace\": \"https://github.com/yourusername\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A userscript built with TypeScript\",\n  \"author\": \"Your Name\",\n  \"match\": [\n    \"https://example.com/*\"\n  ],\n  \"grant\": [\n    \"GM_addStyle\",\n    \"GM_getValue\",\n    \"GM_setValue\"\n  ],\n  \"run-at\": \"document-end\"\n}\n```\n\n**Key fields:**\n- `match`: URLs where your userscript runs\n- `grant`: GM API permissions your script needs (see [Available GM APIs](#available-gm-apis))\n- `run-at`: When to run the script (`document-start`, `document-end`, or `document-idle`)\n- `connect`: (Optional) Domains allowed for `GM_xmlhttpRequest` cross-origin requests. Only add if you use `GM_xmlhttpRequest`. Example: `[\"api.example.com\", \"cdn.example.org\"]`\n- `version`: **This is your userscript version** - what users see in Tampermonkey. Bump this when releasing updates.\n\n**Versioning strategy:**\n\nThis depends on whether you're in **template mode** or **userscript mode** (set via `\"templateMode\"` in `package.json`):\n\n| | `package.json` | `meta.json` |\n|---|---|---|\n| **Template mode** | Template infrastructure version | Always `1.0.0` - never changed |\n| **Userscript mode** | Kept in sync with `meta.json` | Your userscript version (what Tampermonkey shows users) |\n\nIn **userscript mode**, both files are always bumped together so your git tag, `package.json`, and `meta.json` all reflect the same version.\n\n\u003e **Note:** If you used `npm run setup`, `templateMode` is already set to `false` and both files are already configured correctly. You don't need to touch this manually.\n\n### 3. Build Your Userscript\n\n```bash\n# Production build (optimized, no sourcemaps)\nnpm run build\n\n# Development mode (watch mode with inline sourcemaps for debugging)\nnpm run dev\n```\n\nThe built userscript will be in `dist/userscript.user.js`.\n\n### 4. Install in Your Browser\n\n1. Install a userscript manager extension:\n   - [Tampermonkey](https://www.tampermonkey.net/) (Chrome, Firefox, Safari, Edge)\n   - [Violentmonkey](https://violentmonkey.github.io/) (Chrome, Firefox, Edge)\n   - [Greasemonkey](https://www.greasespot.net/) (Firefox)\n\n2. Open `dist/userscript.user.js` and copy its contents\n\n3. Create a new userscript in your userscript manager and paste the code\n\n## Development Workflow\n\n1. **Write TypeScript code** in the `src/` directory\n   - `src/index.ts` is the main entry point\n   - Create additional `.ts` files as needed\n   - Import/export modules as usual\n\n2. **Write tests** for your code:\n   ```bash\n   npm test              # Run tests once\n   npm run test:watch    # Watch mode for test-driven development\n   npm run test:ui       # Interactive UI for exploring tests\n   npm run test:coverage # Generate coverage report\n   ```\n\n3. **Lint and format your code**:\n   ```bash\n   npm run lint        # Check for errors\n   npm run lint:fix    # Auto-fix errors\n   npm run format      # Format code with Prettier\n   ```\n\n4. **Run in watch mode** during development:\n   ```bash\n   npm run dev  # Includes inline sourcemaps for debugging\n   ```\n\n5. **Test in browser**:\n   - After each build, copy the updated `dist/userscript.user.js` to your userscript manager\n   - Or set up automatic reloading (see Tips below)\n\n## Writing Your Userscript\n\n### Example: Testing Your Code\n\nThe template includes Vitest for testing. Write tests alongside your code:\n\n```typescript\n// tests/utils.test.ts\nimport { describe, it, expect } from 'vitest';\nimport { log } from '../src/utils';\n\ndescribe('utils', () =\u003e {\n  it('should log with prefix', () =\u003e {\n    // Your test logic here\n  });\n});\n```\n\nSee the MIGRATION_GUIDE.md for more testing examples.\n\n### Example: Basic Structure\n\n```typescript\n// src/index.ts\nimport { log, waitForElement } from './utils';\n\nasync function main(): Promise\u003cvoid\u003e {\n  log('Userscript started!');\n  \n  try {\n    const element = await waitForElement('#my-element');\n    element.textContent = 'Modified by userscript!';\n  } catch (error) {\n    console.error('Error:', error);\n  }\n}\n\n// Start the userscript\n// Note: With @run-at document-end, the DOM is already loaded\nmain();\n```\n\n### Example: Creating Utilities\n\n```typescript\n// src/utils.ts\nexport function log(message: string): void {\n  console.log(`[UserScript] ${message}`);\n}\n\nexport function waitForElement(selector: string, timeout = 5000): Promise\u003cElement\u003e {\n  return new Promise((resolve, reject) =\u003e {\n    const startTime = Date.now();\n    const checkElement = () =\u003e {\n      const element = document.querySelector(selector);\n      if (element) {\n        resolve(element);\n      } else if (Date.now() - startTime \u003e timeout) {\n        reject(new Error(`Timeout: ${selector}`));\n      } else {\n        setTimeout(checkElement, 100);\n      }\n    };\n    checkElement();\n  });\n}\n\n// Using GM APIs\nexport function addStyles(css: string): void {\n  GM_addStyle(css);\n}\n\nexport async function store(key: string, value: any): Promise\u003cvoid\u003e {\n  await GM_setValue(key, value);\n}\n\nexport async function retrieve\u003cT\u003e(key: string, defaultValue?: T): Promise\u003cT\u003e {\n  return await GM_getValue(key, defaultValue);\n}\n\nexport function notify(text: string, title?: string): void {\n  GM_notification({ text, title: title || 'UserScript' });\n}\n```\n\n### Available GM APIs\n\nThe template includes TypeScript support for:\n\n- **`GM_addStyle(css)`** - Add CSS styles to the page\n- **`GM_getValue(key, default)`** - Get stored value (persistent across page loads)\n- **`GM_setValue(key, value)`** - Store value persistently\n- **`GM_deleteValue(key)`** - Delete stored value\n- **`GM_xmlhttpRequest(details)`** - Make cross-origin HTTP requests\n- **`GM_notification(details)`** - Show desktop notifications\n- **`GM_openInTab(url)`** - Open URL in new tab\n- **`GM_setClipboard(text)`** - Copy text to clipboard\n- **`GM_registerMenuCommand(name, fn)`** - Add menu command\n- **And many more...**\n\nAll functions have full TypeScript autocomplete and type checking!\n\n## Tips\n\n- **GM API autocomplete**: The `@types/tampermonkey` package provides full TypeScript support. Just start typing `GM_` and VS Code will show available functions!\n\n- **Grant permissions**: Always add the GM functions you use to the `grant` array in [meta.json](meta.json), otherwise they won't work\n\n- **Cross-origin requests**: If you use `GM_xmlhttpRequest` to make requests to external domains, add those specific domains to the `connect` array. Example: `\"connect\": [\"api.github.com\", \"cdn.example.com\"]`. Avoid using `\"*\"` wildcard for security reasons.\n\n- **Multiple userscripts**: Duplicate this template folder for each userscript project\n\n- **Source maps**: Use `npm run dev` for development builds with inline source maps to debug TypeScript in browser DevTools. Production builds (`npm run build`) exclude source maps for smaller file size.\n\n- **Tree-shaking**: Unused exports are automatically removed from the bundle. Only code you actually import and use will be included\n\n## Customization\n\n### Adding Dependencies\n\nYou can install and use npm packages:\n\n```bash\nnpm install \u003cpackage-name\u003e\n```\n\nThen import them in your TypeScript files:\n\n```typescript\nimport { someFunction } from 'package-name';\n```\n\n### Modifying Build Configuration\n\nEdit `rollup.config.js` to customize the build process:\n- Change output format\n- Add additional plugins\n- Enable/disable source maps (set `sourcemap: true` for debugging)\n- etc.\n\n### TypeScript Configuration\n\nEdit `tsconfig.json` to adjust TypeScript compiler options:\n- Target ECMAScript version\n- Strict mode settings\n- Library inclusions\n- etc.\n\n### Linting and Formatting\n\nThe template includes ESLint and Prettier:\n\n**Configuration files:**\n- `eslint.config.js` - ESLint rules (TypeScript-aware)\n- `.prettierrc` - Code formatting preferences\n- `.prettierignore` - Files to skip formatting\n\n**Customization:**\n- Modify `eslint.config.js` to add/change linting rules\n- Update `.prettierrc` for different formatting preferences\n- Add GM globals to ESLint if you use additional GM functions\n\n## Installation \u0026 Distribution\n\nUsers can install your userscript in multiple ways:\n\n### Method 1: From GitHub Releases (Recommended)\n\nAfter creating a release (see [Creating a Release](#creating-a-release)), users can install from:\n\n```\nhttps://github.com/user/repo/releases/latest/download/userscript.user.js\n```\n\nReplace `user/repo` with your GitHub username and repository name.\n\n### Method 2: Build Locally\n\nUsers can clone your repo and build manually:\n\n```bash\ngit clone https://github.com/user/repo.git\ncd repo\nnpm install\nnpm run build\n# Install dist/userscript.user.js in Tampermonkey/Greasemonkey\n```\n\n### Method 3: Development Installation\n\nFor development, you can use Tampermonkey's built-in editor or a local file:\n\n```bash\nnpm run dev  # Watch mode with sourcemaps\n# Point Tampermonkey to file:///path/to/dist/userscript.user.js\n```\n\n## CI/CD with GitHub Actions\n\nThree workflows are included:\n\n**`.github/workflows/ci.yml`** - Continuous Integration:\n- Runs on every push and pull request\n- Linting, formatting, type checking\n- **Runs test suite to catch bugs**\n- Grant validation and markdown link checks\n- Builds the project to ensure everything works\n- Ensures code quality and catches issues early\n\n**`.github/workflows/version-bump.yml`** - Version Bumping:\n- Manually triggered from the GitHub Actions UI\n- Select patch/minor/major bump type\n- **Auto-detects mode** from `package.json` — no manual configuration needed\n- Updates `package.json` (and `meta.json` in userscript mode), auto-generates `CHANGELOG.md` from commit messages using `git-cliff`, commits, and pushes a `v*` tag\n- Guards against forgetting to update `repository.url`\n\n**`.github/workflows/release.yml`** - Release Publishing:\n- **Triggered automatically** when a `v*` tag is pushed (i.e. after every version bump)\n- Can also be triggered manually from the Actions UI — leave the tag field empty to release the latest tag, or specify an older tag to re-release a specific version\n- Detects template vs userscript mode, builds the artifact if needed, and creates the GitHub Release\n\n### How it fits together\n\n```\nVersion Bump (manual) → pushes v* tag → Release (automatic)\n                                      ↑\n                           Release (manual) ─────────────────┘\n```\n\nThe release workflow is intentionally decoupled from the bump workflow. It triggers on any `v*` tag regardless of how the tag was created, which means you can also push a tag manually and get a release without going through the bump workflow.\n\n### Template Mode vs Userscript Mode\n\nThe workflows automatically detect how to behave based on `package.json`:\n\n```json\n{\n  \"userscript\": {\n    \"templateMode\": true   // ← set to false (or remove) when building a real userscript\n  }\n}\n```\n\n| | `templateMode: true` | `templateMode: false` (or absent) |\n|---|---|---|\n| **Updates** | `package.json` only | `package.json` + `meta.json` |\n| **Release artifact** | None | `dist/userscript.user.js` attached |\n| **Use case** | Template/boilerplate maintainers | Userscript developers |\n| **Default** | ✅ (ships with template) | Set when starting your userscript |\n\n\u003e ⚠️ **Template mode releases have no build artifact.** Since `meta.json` stays at `1.0.0` (the starting point for users of this template), attaching the built file would show a version mismatch on the release. The release exists purely as a changelog anchor and version marker. Once you set `templateMode: false`, releases will include the built artifact as normal.\n\n**If you used `npm run setup`**, `templateMode` is already `false` and everything is configured correctly.\n\n### Changelog\n\n`CHANGELOG.md` is **automatically generated** from your commit messages on every version bump using [git-cliff](https://github.com/orhun/git-cliff). You never need to write it manually.\n\nCommits are parsed by type and grouped into sections:\n\n| Commit prefix | Changelog section |\n|---|---|\n| `feat:` | Added |\n| `fix:` | Fixed |\n| `refactor:`, `perf:` | Changed |\n| `docs:` | Documentation |\n| `build(deps*)` | Dependencies |\n| `chore:`, `ci:`, `test:`, `style:` | Skipped |\n\nTo get clean changelogs, write commits in [conventional commit](https://www.conventionalcommits.org/) format — which this template already encourages via ESLint and Husky.\n\n### Creating a Release\n\n1. Go to **Actions** tab in your GitHub repository\n2. Select **Version Bump** workflow\n3. Click **Run workflow**\n4. Choose the version bump type:\n   - **patch**: 1.0.0 → 1.0.1 (bug fixes, minor updates)\n   - **minor**: 1.0.0 → 1.1.0 (new features)\n   - **major**: 1.0.0 → 2.0.0 (breaking changes)\n5. Click **Run workflow**\n\nThis automatically:\n- Validates your `repository.url` is configured correctly\n- Detects template vs userscript mode\n- Updates `package.json` (and `meta.json` in userscript mode)\n- Auto-generates `CHANGELOG.md` from commit messages using `git-cliff`\n- Commits and pushes the version tag\n- Triggers the **Release** workflow, which builds and attaches the artifact (userscript mode only)\n\nUsers can then install directly from the release:\n```\nhttps://github.com/user/repo/releases/latest/download/userscript.user.js\n```\n\n### Re-releasing or recovering a failed release\n\nIf the release workflow fails (e.g. a flaky runner or build error), the tag is already in place from the bump — you don't need to bump again. Just go to **Actions → Release → Run workflow** and leave the tag field empty to retry against the latest tag, or type a specific tag if needed.\n\n**To remove CI/CD:** Simply delete the `.github/workflows/` folder if you don't need it.\n\n## Updating from Template\n\n**Note:** This template is a **starting point** - most users heavily customize it. Updates are **optional** and typically only needed if you want new features from the template.\n\n### When to Update\n\n✅ **Update if you want:**\n- New GitHub Actions workflows or improvements\n- Better build/test configurations\n- Security updates to tooling\n\n❌ **Don't update if:**\n- You've heavily customized configs\n- Everything works fine for you\n- You prefer stability over new features\n\n---\n\n### Manual Update\n\nCheck the [template repository](https://github.com/matthiasseghers/typescript-userscript-template) and [CHANGELOG.md](CHANGELOG.md) for changes, then manually update:\n- `.github/workflows/` - CI/CD workflows\n- `eslint.config.js`, `tsconfig.json`, `.prettierrc` - Linting/formatting\n- `rollup.config.js`, `vitest.config.ts` - Build/test config\n- `package.json` - Dependencies (or use Dependabot)\n\n### Dependency Updates\n\nUse Dependabot (included) for automatic dependency updates, or:\n```bash\nnpm update              # Update to latest compatible versions\nnpm outdated            # Check for major version updates\n```\n\n## Troubleshooting\n\n### Build fails with \"Cannot find module\"\n- Run `npm install` to ensure all dependencies are installed\n- Delete `node_modules` and `package-lock.json`, then run `npm install` again\n\n### Linting errors about GM_ functions\n- TypeScript handles GM_ type checking via `@types/tampermonkey`\n- Add GM functions you use to `meta.json` grants\n- Run `npm run check-grants` to validate\n\n### Userscript not working in browser\n- Check that all GM functions are listed in `meta.json` grants\n- Verify the `@match` pattern matches your target URLs\n- Check browser console for errors\n\n### TypeScript errors\n- Ensure `@types/tampermonkey` is installed: `npm install --save-dev @types/tampermonkey`\n- Run `npm run type-check` to see all type errors\n- Check that your tsconfig.json is properly configured\n\n### Format/lint errors before commit\n- Run `npm run validate` to check everything at once\n- Use `npm run lint:fix` and `npm run format` to auto-fix issues\n\n### Release workflow didn't trigger after version bump\n- Check that the tag was pushed successfully in the Version Bump workflow logs\n- You can trigger the Release workflow manually from the Actions tab — leave the tag field empty to use the latest tag\n\n## Scripts Reference\n\n**Setup (one-time):**\n- `npm run setup` - Interactive project setup wizard — configures all files and installs dependencies. Self-deletes after running.\n\n**Build:**\n- `npm run build` - Build the userscript for production (no sourcemaps)\n- `npm run dev` - Watch mode for development (with inline sourcemaps)\n\n**Testing:**\n- `npm test` - Run tests once\n- `npm run test:watch` - Watch mode for tests\n- `npm run test:ui` - Interactive test UI dashboard\n- `npm run test:coverage` - Generate coverage report\n\n**Code Quality:**\n- `npm run lint` - Check for linting errors\n- `npm run lint:fix` - Auto-fix linting errors\n- `npm run format` - Format code with Prettier\n- `npm run format:check` - Check if code is formatted\n- `npm run type-check` - Run TypeScript type checking\n\n**Validation:**\n- `npm run check-grants` - Validate GM API grants\n- `npm run check-links` - Check for broken links in markdown files\n- `npm run validate` - Run all checks including tests (recommended before committing)\n\n## License\n\nMIT\n\n## Contributing\n\nFeel free to customize this template for your needs!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthiasseghers%2Ftypescript-userscript-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatthiasseghers%2Ftypescript-userscript-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthiasseghers%2Ftypescript-userscript-template/lists"}