| name | tanstack-config |
| description | Opinionated toolkit for building, versioning, and publishing high-quality JavaScript/TypeScript packages. |
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
pnpm add @tanstack/config -D
Vite Build Configuration
Basic Setup
import { defineConfig, mergeConfig } from "vitest/config";
import { tanstackViteConfig } from "@tanstack/config/vite";
const config = defineConfig({
});
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"],
});
ESLint Configuration
Basic Setup
import { tanstackEslintConfig } from "@tanstack/config/eslint";
export default tanstackEslintConfig;
Extending the Config
import { tanstackEslintConfig } from "@tanstack/config/eslint";
export default [
...tanstackEslintConfig,
{
rules: {
"@typescript-eslint/no-explicit-any": "warn",
},
},
];
Publishing
Publish Configuration
import { tanstackPublishConfig } from "@tanstack/config/publish";
export default tanstackPublishConfig({
});
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
Changeset Config
{
"$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
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
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
packages:
- "packages/*"
- "examples/*"
Nx Configuration
{
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": ["build", "lint", "test"]
}
}
},
"targetDefaults": {
"build": {
"dependsOn": ["^build"]
}
}
}
Prettier Configuration
{
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80
}
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)