{"id":35514346,"url":"https://github.com/neg4n/good-typescript-libraries-template","last_synced_at":"2026-01-03T22:03:49.333Z","repository":{"id":330644129,"uuid":"1111965653","full_name":"neg4n/good-typescript-libraries-template","owner":"neg4n","description":"Production ready NX monorepo template for developing and releasing TypeScript libraries, including automated GitHub repository setup. And believe me, it is good.","archived":false,"fork":false,"pushed_at":"2025-12-26T23:05:36.000Z","size":116,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-28T13:53:45.769Z","etag":null,"topics":["biomejs","github","github-actions","husky-hooks","javascript-template","nx","nx-workspace","pnpm","project-template","rollup","template","typescript","typescript-library","typescript-template"],"latest_commit_sha":null,"homepage":"","language":"Shell","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/neg4n.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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-08T00:30:34.000Z","updated_at":"2025-12-26T23:05:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/neg4n/good-typescript-libraries-template","commit_stats":null,"previous_names":["neg4n/good-typescript-libraries-template"],"tags_count":null,"template":true,"template_full_name":null,"purl":"pkg:github/neg4n/good-typescript-libraries-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fgood-typescript-libraries-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fgood-typescript-libraries-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fgood-typescript-libraries-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fgood-typescript-libraries-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neg4n","download_url":"https://codeload.github.com/neg4n/good-typescript-libraries-template/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neg4n%2Fgood-typescript-libraries-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28194898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2026-01-03T02:00:06.471Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["biomejs","github","github-actions","husky-hooks","javascript-template","nx","nx-workspace","pnpm","project-template","rollup","template","typescript","typescript-library","typescript-template"],"created_at":"2026-01-03T22:03:19.883Z","updated_at":"2026-01-03T22:03:49.328Z","avatar_url":"https://github.com/neg4n.png","language":"Shell","readme":"# Good TypeScript Libraries Template\n\nAn opinionated production-ready TypeScript **monorepo** template with automated builds, testing, and releases powered by Nx.\n\nAnd believe me. **It is good.**\n\n\u003e [!IMPORTANT]\n\u003e Looking for a simpler, non-monorepo template without **nx** but same features?  \n\u003e [Check out `good-typescript-library-template`!](https://github.com/neg4n/good-typescript-library-template)\n\n\u003cimg width=\"380\" src=\"https://github.com/user-attachments/assets/e3ecf54c-13c4-4baa-a253-d2861d4bf4e9\" /\u003e\n\n\n\n## Features\n\n- 🧭 **Nx-powered Monorepo** – multiple libraries under `packages/*` with intelligent task orchestration\n    - ⚡ **Affected-only CI** – lint, typecheck, test, build run only for changed packages\n    - 💾 **Local \u0026 remote caching** – skip redundant work across runs\n    - 🚀 **Independent releases** – per-package versioning with conventional commits\n    - 📊 **Project graph awareness** – understands package dependencies\n- 📦 **Dual Package Support** – Rollup outputs CommonJS and ESM builds per package\n- 🛡️ **Type Safety** – Extremely strict TypeScript configuration (shared `tsconfig.base.json`)\n- 🔐 **Always up-to-date deps** – [Renovate](https://github.com/renovatebot/renovate) bot for CVE-aware automatic dependency updates\n- ✅ **Build Validation** – Uses `@arethetypeswrong/cli` to check package exports\n- 🧪 **Automated Testing** – Vitest workspace with per-package coverage PR comments\n- 🎨 **Code Quality** – Biome linting/formatting with pre-commit hooks\n- ⚙️ **CI/CD Pipeline** – GitHub Actions with workflow chaining (CI → Version → Publish)\n- 🔧 **One-Click Setup** – Automated repository configuration with `init.sh` script\n    - 🏛️ **Repository rulesets** - Branch protection with linear history and PR reviews\n    - 🚷 **Feature cleanup** - Disable wikis, projects, squash/merge commits\n    - 🔄 **Merge restrictions** - Rebase-only workflow at repository and ruleset levels\n    - 👑 **Admin bypass** - Repository administrators can bypass protection rules\n    - 🔍 **Actions verification** - Ensure GitHub Actions are enabled\n    - 🗝️ **Secrets validation** - Check and guide setup of required secrets\n\n## Tech Stack\n\n- **Nx** - Orchestrates tasks, caching, and releases across packages\n- **TypeScript** - Strict configuration for type safety\n- **Rollup** - Builds both CommonJS and ESM formats per package\n- **Biome** - Fast linting and formatting\n- **Vitest** - Testing with coverage reports (workspace config)\n- **Husky** - Pre-commit hooks for code quality\n- **Nx Release** - Automated versioning/changelog + npm publishing\n- **pnpm** - Fast package management with Corepack\n- **GitHub Actions** - CI/CD pipeline (validation, versioning, publishing)\n\n\n## Setup\n\n### 1. Use the template\n\nRun this in your terminal _[GitHub CLI](https://cli.github.com) required_\n\n```bash\ngh repo create my-typescript-libraries --clone --template neg4n/good-typescript-libraries-template --private \u0026\u0026 cd my-typescript-libraries\n```\n\n\u003e [!NOTE]\n\u003e Replace `my-typescript-libraries` with your new library name, you can also change the visibility of the newly created repo by passing `--public` instead of `--private`! Read more about possible options in [GitHub CLI documentation](https://cli.github.com/manual/gh_repo_create)\n\n#### Setup via GitHub web interface\n\nIf for some reason you can't run the mentioned commands in your terminal, click the \"Use this template ▾\" button below (or in the top right corner of the repository page)\n\n\u003ca href=\"https://github.com/new?template_name=good-typescript-libraries-template\u0026template_owner=neg4n\"\u003e\n\u003cimg src=\"https://github.com/user-attachments/assets/784be0dd-530f-4135-b042-ab59dc9124a6\" width=\"200\" /\u003e\n\u003c/a\u003e\n\n### 2. Minimal Setup\n\nRun the initialization script to automatically configure your repository:\n\n```bash\n# One-command setup\n./init.sh\n```\n\nThis script will:\n- 🔒 **Create repository rulesets** for branch protection (linear history, PR reviews)\n- 🚫 **Disable unnecessary features** (wikis, projects, squash/merge commits)\n- ⚙️ **Configure merge settings** (rebase-only workflow at repository and ruleset levels)\n- 👤 **Grant admin bypass** permissions for repository administrators\n- 🔧 **Verify GitHub Actions** and validate repository configuration\n- 🔑 **Check required secrets** and provide setup instructions\n\n### 3. Required Secrets\n\nThe script will guide you to set up these secrets if missing:\n\n**NPM_TOKEN** (for publishing):\n```bash\n# Generate NPM token with OTP for enhanced security\npnpm token create --otp=\u003cYOUR_OTP\u003e --registry=https://registry.npmjs.org/\n\n# Set the token as repository secret\ngh secret set NPM_TOKEN --body \"your-npm-token-here\"\n```\n\n**ACTIONS_BRANCH_PROTECTION_BYPASS** (for automated pushes from versioning workflow):\n```bash\n# Create Personal Access Token with 'repo' permissions\n# Visit: https://github.com/settings/personal-access-tokens/new\n\n# Set the PAT as repository secret\ngh secret set ACTIONS_BRANCH_PROTECTION_BYPASS --body \"your-pat-token-here\"\n```\n\n## Scripts\n\n| Command | Description |\n|---------|-------------|\n| `pnpm lint` | Biome lint across all packages |\n| `pnpm lint:fix` | Auto-fix lint issues |\n| `pnpm test` | Run Vitest across the workspace |\n| `pnpm test:coverage` | Vitest with coverage |\n| `pnpm typecheck` | TypeScript `--noEmit` across packages |\n| `pnpm build` | Rollup builds for every package |\n| `pnpm attw` | Run AreTheTypesWrong for all packages |\n| `pnpm release:dry` | Nx Release dry run |\n| `pnpm release:version` | Bump versions \u0026 changelogs, create tags |\n| `pnpm release:publish` | Publish tagged packages to npm |\n\nPer-package targets are also available, e.g. `pnpm nx run core:build`.\n\n## Adding a new package\n\nUse the built-in generator to scaffold a new package with all the template's features:\n\n```bash\npnpm nx g @good-typescript-libraries/tools:library --name=my-utils\n```\n\n### What the generator does\n\n1. **Creates package** at `packages/\u003cname\u003e/` with:\n   - `project.json` with Nx targets (build, lint, test, typecheck, attw)\n   - `package.json` with dual CJS/ESM exports and publishConfig\n   - `rollup.config.js` producing ESM, CJS, minified ESM, and bundled types\n   - `tsconfig.json` and `tsconfig.build.json`\n   - Placeholder `src/index.ts` and `test/index.test.ts`\n\n2. **Updates `vitest.config.ts`** — adds workspace entry with test config and alias\n\n3. **Updates CI workflow** — adds coverage report step to `.github/workflows/ci.yml`\n\n### Generator options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `name` | string | — | Package name (required) |\n| `--description` | string | `\"\"` | Package description for package.json |\n| `--skipCoverage` | boolean | `false` | Skip adding coverage report to CI |\n\n### Examples\n\n```bash\npnpm nx g @good-typescript-libraries/tools:library --name=utils --description=\"Utility functions\"\n\npnpm nx g @good-typescript-libraries/tools:library --name=internal-tools --skipCoverage\n```\n\nAfter generating, add your exports to `packages/\u003cname\u003e/src/index.ts` and run `pnpm nx build \u003cname\u003e` to verify.\n\n## Changing the npm scope\nThe default scope is `@good-typescript-libraries`. To rename it (e.g. to `@my-libraries`), update these places:\n1. **nx.json** – set `\"npmScope\": \"my-libraries\"`.\n2. **tsconfig.base.json** – change the path alias to `\"@my-libraries/*\": [\"packages/*/src/index.ts\"]`.\n3. **Package names/import paths** – in each `packages/*/package.json` update `\"name\"` and `importPath` (if present) to the new scope; adjust any imports in code/tests (e.g. `import {...} from '@my-libraries/core'`).\n4. **Vitest aliases** – in `vitest.config.ts` update the alias map to the new scope.\n5. **Tools package** – in `tools/package.json` update `\"name\"` to the new scope (e.g. `@my-libraries/tools`).\n6. **Docs \u0026 examples** – replace `@my-libraries/` occurrences in README/CONTRIBUTING and commands.\n\n\u003e [!NOTE]\n\u003e After changing the scope, generator commands will also change. For example:\n\u003e ```bash\n\u003e pnpm nx g @my-libraries/tools:library --name=utils\n\u003e ```\n\nAfter those edits, run `pnpm install`, then `pnpm lint \u0026\u0026 pnpm test \u0026\u0026 pnpm build` to ensure everything resolves correctly.\n\n## Release model (Nx Release)\n- Conventional commits determine bumps; packages release **independently**.\n- Version workflow (triggered after CI succeeds on `main`) runs `nx release version --yes` to update versions/changelogs and create tags (`{projectName}@{version}`).\n- Publish workflow (tag push) runs `nx release publish --projects \u003cname\u003e` with npm provenance.\n- Required secret: `NPM_TOKEN`; optional `ACTIONS_BRANCH_PROTECTION_BYPASS` if your repo blocks CI pushes.\n\n## CI/CD (GitHub Actions)\n- `CI` (push/PR): runs `nx affected` for lint → typecheck → tests + coverage → build on Node 20 \u0026 22.\n- `Release Version` (after CI succeeds on `main`): bumps versions/changelogs, creates tags, pushes back.\n- `Release Publish` (tag push): rebuilds tagged package(s) and publishes to npm with provenance.\n\n## Renovate\n\n`renovate.json5` already turns onboarding off, so Renovate will start opening update PRs as soon as the GitHub App is installed. Enable it like this:\n\n1. Visit https://github.com/apps/renovate and click **Install**.\n2. Choose your personal account or organization, then pick **All repos** or **Only select repos** (include this one).\n3. Approve the requested permissions to finish installation. Renovate will run shortly after and open PRs based on `renovate.json5`.\n\nNotes:\n- Want to stop it? Uninstall the app or set `\"enabled\": false` in `renovate.json5`.\n- Need custom rules (schedules, groups, automerge)? Extend `renovate.json5` - no extra onboarding PR is required.\n\n## FAQ\n\n#### How do I modify the merging methods?\n\n`good-typescript-libraries-template` sets **rebase-only** at both repository and main branch levels. Here's how to modify this:\n\n##### **Current Setup**\n- **Repository**: Rebase merging only (squash/merge disabled)\n- **Main branch ruleset**: Requires rebase merging\n\n##### **To Change Merge Methods**\n\n**For repository-wide changes:**\n- **Settings \u003e General \u003e Pull Requests** - toggle merge methods\n\n**For branch-specific changes:**\n- **Settings \u003e Rules** - edit the main branch ruleset's \"Require merge type\"\n\n##### **Precedence Rules**\n1. Repository settings define what's **available**\n2. Rulesets add **restrictions** on top  \n3. **Most restrictive wins** - if repository disallows a method but ruleset requires it, merging is **blocked**\n\n##### **Common Modifications**\n- **Allow all methods**: Enable squash/merge in repo settings + remove \"Require merge type\" from ruleset\n- **Squash-only**: Change repo settings to squash-only OR keep current repo settings + change ruleset to require squash\n- **Different rules per branch**: Create additional rulesets for other branch patterns\n\n\u003e [!TIP]\n\u003e Since `good-typescript-libraries-template` is rebase-only, you must enable other methods in repository settings before rulesets can use them.\n\n#### How to solve pnpm lockfile error on my CI/CD?\n\nIf you're seeing this error in your CI/CD (GitHub Actions) pipeline:\n\n```\nERR_PNPM_OUTDATED_LOCKFILE  Cannot install with \"frozen-lockfile\" because pnpm-lock.yaml is not up to date with \u003cROOT\u003e/package.json\n```\n\n##### **Why This Happens**\nThis template uses `--frozen-lockfile` to ensure consistent installations in CI/CD. The error occurs when your `package.json` has been modified but the `pnpm-lock.yaml` hasn't been updated to match.\n\n##### **Solution**\nRun the following command locally:\n```bash\npnpm install\n```\n\nThen commit the updated lockfile:\n```bash\ngit add pnpm-lock.yaml\ngit commit -m \"chore: update pnpm lockfile\"\n```\n\n#### Why Linear History?\n\nLinear history provides several benefits for library releases:\n\n- **Clean commit history** - Easy to track changes and debug issues\n- **Simplified releases** - Nx Release and conventional commits work best with linear commits\n- **Clear changelog** - Each commit represents a complete change\n- **Better debugging** - `git bisect` works more effectively\n- **Consistent workflow** - Forces proper PR review process\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneg4n%2Fgood-typescript-libraries-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneg4n%2Fgood-typescript-libraries-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneg4n%2Fgood-typescript-libraries-template/lists"}