tanstack-config

Opinionated toolkit for building, versioning, and publishing high-quality JavaScript/TypeScript packages.

INSTALLATION
npx skills add https://github.com/tanstack-skills/tanstack-skills --skill tanstack-config
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

Overview

TanStack Config provides an opinionated, minimal-configuration toolkit for JavaScript/TypeScript package development. It includes Vite-powered build configuration, ESLint presets, publish automation with semantic versioning, and integrations with TypeScript, Prettier, Changesets, and GitHub Actions. Designed for monorepo workflows with pnpm and Nx.

Package: @tanstack/config

Status: Stable

Installation

npm install @tanstack/config --save-dev

# or

pnpm add @tanstack/config -D

Vite Build Configuration

Basic Setup

// vite.config.ts

import { defineConfig, mergeConfig } from 'vitest/config'

import { tanstackViteConfig } from '@tanstack/config/vite'

const config = defineConfig({

  // Your custom Vite config

})

export default mergeConfig(

  config,

  tanstackViteConfig({

    entry: './src/index.ts',

    srcDir: './src',

    exclude: ['./src/__tests__'],

  })

)

Multiple Entry Points

import { tanstackViteConfig } from '@tanstack/config/vite'

export default tanstackViteConfig({

  entry: [

    './src/index.ts',

    './src/adapters.ts',

    './src/utils.ts',

  ],

  srcDir: './src',

})

Build Options

tanstackViteConfig({

  entry: './src/index.ts',

  srcDir: './src',

  exclude: ['./src/__tests__', './src/**/*.test.ts'],

  // Generates ESM and CJS outputs

  // Generates .d.ts declaration files

  // Handles tree-shaking configuration

})

ESLint Configuration

Basic Setup

// eslint.config.js

import { tanstackEslintConfig } from '@tanstack/config/eslint'

export default tanstackEslintConfig

Extending the Config

// eslint.config.js

import { tanstackEslintConfig } from '@tanstack/config/eslint'

export default [

  ...tanstackEslintConfig,

  {

    rules: {

      // Custom overrides

      '@typescript-eslint/no-explicit-any': 'warn',

    },

  },

]

Publishing

Publish Configuration

// publish.config.ts or used via CLI

import { tanstackPublishConfig } from '@tanstack/config/publish'

export default tanstackPublishConfig({

  // Publint-compliant defaults

  // Semantic versioning automation

  // Changelog generation

})

Package.json Setup

{

  "name": "@myorg/my-package",

  "version": "0.0.0",

  "type": "module",

  "main": "dist/cjs/index.cjs",

  "module": "dist/esm/index.js",

  "types": "dist/esm/index.d.ts",

  "exports": {

    ".": {

      "import": {

        "types": "./dist/esm/index.d.ts",

        "default": "./dist/esm/index.js"

      },

      "require": {

        "types": "./dist/cjs/index.d.cts",

        "default": "./dist/cjs/index.cjs"

      }

    }

  },

  "files": ["dist", "src"],

  "scripts": {

    "build": "vite build",

    "lint": "eslint .",

    "test": "vitest"

  }

}

TypeScript Configuration

tsconfig.json

{

  "compilerOptions": {

    "strict": true,

    "target": "ES2020",

    "module": "ESNext",

    "moduleResolution": "bundler",

    "declaration": true,

    "declarationMap": true,

    "sourceMap": true,

    "outDir": "./dist",

    "rootDir": "./src",

    "esModuleInterop": true,

    "skipLibCheck": true,

    "forceConsistentCasingInFileNames": true

  },

  "include": ["src"],

  "exclude": ["node_modules", "dist"]

}

Changesets Integration

Setup

npx changeset init

Creating a Changeset

npx changeset

# Interactive prompt: select packages, bump type, summary

Changeset Config

// .changeset/config.json

{

  "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",

  "changelog": "@changesets/cli/changelog",

  "commit": false,

  "fixed": [],

  "linked": [],

  "access": "public",

  "baseBranch": "main",

  "updateInternalDependencies": "patch"

}

GitHub Actions Workflow

CI/CD Pipeline

# .github/workflows/ci.yml

name: CI

on:

  push:

    branches: [main]

  pull_request:

    branches: [main]

jobs:

  build:

    runs-on: ubuntu-latest

    steps:

      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v2

      - uses: actions/setup-node@v4

        with:

          node-version: 20

          cache: 'pnpm'

      - run: pnpm install

      - run: pnpm build

      - run: pnpm lint

      - run: pnpm test

Publish Workflow

# .github/workflows/publish.yml

name: Publish

on:

  push:

    branches: [main]

jobs:

  publish:

    runs-on: ubuntu-latest

    steps:

      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v2

      - uses: actions/setup-node@v4

        with:

          node-version: 20

          registry-url: 'https://registry.npmjs.org'

      - run: pnpm install

      - run: pnpm build

      - name: Create Release Pull Request or Publish

        uses: changesets/action@v1

        with:

          publish: pnpm publish -r

        env:

          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Monorepo Setup (pnpm + Nx)

Workspace Configuration

# pnpm-workspace.yaml

packages:

  - 'packages/*'

  - 'examples/*'

Nx Configuration

// nx.json

{

  "tasksRunnerOptions": {

    "default": {

      "runner": "nx/tasks-runners/default",

      "options": {

        "cacheableOperations": ["build", "lint", "test"]

      }

    }

  },

  "targetDefaults": {

    "build": {

      "dependsOn": ["^build"]

    }

  }

}

Prettier Configuration

// .prettierrc

{

  "semi": false,

  "singleQuote": true,

  "trailingComma": "all",

  "printWidth": 80

}

EditorConfig

# .editorconfig

root = true

[*]

indent_style = space

indent_size = 2

end_of_line = lf

charset = utf-8

trim_trailing_whitespace = true

insert_final_newline = true

Best Practices

  • Use the Vite config for builds - handles ESM/CJS dual output and declarations
  • Use publint-compliant exports in package.json for compatibility
  • Use Changesets for version management in monorepos
  • **Set "type": "module"** in package.json for ESM-first packages
  • **Include both src and dist** in files for source map debugging
  • Use Nx caching for faster builds in monorepos
  • Always generate declaration files (.d.ts) for TypeScript consumers
  • Use the ESLint config as a consistent baseline across packages
  • Automate publishing with GitHub Actions and Changesets

Common Pitfalls

  • Missing exports field in package.json (breaks modern bundlers)
  • Not setting "type": "module" (causes ESM import issues)
  • Forgetting declaration files in build output
  • Not excluding test files from the build
  • Publishing without running publint validation first
  • Not configuring moduleResolution: "bundler" in tsconfig
  • Inconsistent versioning across monorepo packages (use Changesets linked)
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card