Strongtie Design System
Getting StartedComponents

Command Palette

Search for a command to run...

Getting Started
  • Introduction
  • Setup Guide
  • Package Installation
  • Code Quality Setup
  • Migration Guide
  • Resources
Registry
  • Getting Started
  • Combobox
  • Datepicker
  • MultiSelect
  • Tab Nav
  • Tree
Guides
  • Framework Recommendations
Foundations
  • States
  • Variables
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Avatar
  • Badge
  • Breadcrumb
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Command
  • Combobox
  • Context Menu
  • Date Picker
  • Dialog
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Item
  • Kbd
  • Label
  • Menubar
  • Multi Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Radio Group
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Switch
  • Table
  • Tabs
  • Tab Nav
  • Textarea
  • Toaster
  • Toggle
  • Toggle Group
  • Tooltip
  • Tree
2026 Simpson Strong-Tie
  1. Docs
  2. Getting Started
  3. Code Quality Setup

Code Quality Setup

PreviousNext

ESLint, Prettier, and Stylelint configuration for Simpson Strong-Tie projects using Ultracite.

The @strongtie code quality packages provide pre-configured linting and formatting for Simpson Strong-Tie projects. They extend Ultracite with company-specific rule overrides.

ESLint 9 Required: Due to compatibility issues with eslint-plugin-react and other plugins, ESLint 10 is not yet supported. These packages require ESLint 9.x.

What's Included

PackageDescription
@strongtie/eslintESLint rules for TypeScript, React, and accessibility
@strongtie/prettierPrettier config (re-exports Ultracite)
@strongtie/stylelintStylelint config with Tailwind CSS support

Prerequisites

  • Node.js >= 20.0.0
  • npm >= 10.0.0
  • TypeScript project with tsconfig.json

Installation

Configure Azure Artifacts

The packages are hosted on Azure Artifacts (Simpson feed). Create a .npmrc file in your project root:

.npmrc
@strongtie:registry=https://pkgs.dev.azure.com/StrongTie/_packaging/Simpson/npm/registry/
@strongtie:always-auth=true
registry=https://registry.npmjs.org/

Important: Use @strongtie:registry (scoped) to ensure only @strongtie/* packages use Azure Artifacts authentication.

Install Core Dependencies

First, install Ultracite and pin ESLint to version 9:

npm install -D ultracite@^7.2.4 eslint@^9 prettier@^3 stylelint@^17

Critical: You must use ESLint 9.x (^9), not ESLint 10. The eslint-plugin-react package does not yet support ESLint 10, which will cause runtime errors.

Install @strongtie Packages

npm install -D @strongtie/eslint @strongtie/prettier @strongtie/stylelint

Install ESLint Peer Dependencies

npm install -D \
  @typescript-eslint/eslint-plugin@^8 \
  @typescript-eslint/parser@^8 \
  eslint-config-prettier@^10 \
  eslint-import-resolver-typescript@^4 \
  eslint-plugin-compat@^7 \
  eslint-plugin-cypress@^6 \
  eslint-plugin-github@^6 \
  eslint-plugin-html@^8 \
  eslint-plugin-import@^2 \
  eslint-plugin-jest@^29 \
  eslint-plugin-jsx-a11y@^6 \
  eslint-plugin-n@^17 \
  eslint-plugin-prettier@^5 \
  eslint-plugin-promise@^7 \
  eslint-plugin-react@^7 \
  eslint-plugin-react-hooks@^7 \
  eslint-plugin-sonarjs@^4 \
  eslint-plugin-storybook@^10 \
  eslint-plugin-unicorn@^63 \
  eslint-plugin-unused-imports@^4 \
  globals@^17

Install Stylelint Peer Dependencies

npm install -D \
  stylelint-config-standard@^37 \
  stylelint-config-idiomatic-order@^10 \
  stylelint-prettier@^5

Create Configuration Files

Create the following configuration files in your project root:

ESLint Configuration:

eslint.config.mjs
import base from "@strongtie/eslint/base"
import react from "@strongtie/eslint/react"
import { defineConfig } from "eslint/config"
 
export default defineConfig([
  // Global ignores
  {
    ignores: [
      "**/dist/",
      "**/build/",
      "**/.next/",
      "**/.turbo/",
      "**/node_modules/",
      "**/*.config.ts",
      "**/*.config.mjs",
      "**/*.d.ts",
      "**/*.json",
      "components/ui/**/*",
    ],
  },
 
  // Base TypeScript config (auto-detects ./tsconfig.json)
  ...base(),
 
  // React/JSX config
  ...react,
])

Prettier Configuration:

prettier.config.mjs
export { default } from "@strongtie/prettier"

Stylelint Configuration:

stylelint.config.mjs
export { default } from "@strongtie/stylelint"

Create Ignore Files

Create .prettierignore in your project root:

.prettierignore
# Build outputs
dist/
build/
 
# Test coverage
coverage/
 
# Dependencies
node_modules/
.yalc/
 
# Config files
*.config.ts
*.config.mjs
*.config.js
 
# Type definitions
**/*.d.ts
 
# JSON files
**/*.json
 
# UI components (shadcn/ui)
components/ui/

Create .stylelintignore in your project root:

.stylelintignore
# Build outputs
dist/
build/
 
# Coverage
coverage/
 
# Dependencies
node_modules/
.yalc/
 
# Non-CSS files
**/*.ts
**/*.tsx
**/*.js
**/*.jsx
**/*.mjs
**/*.cjs
**/*.json
**/*.md
 
# Config files
*.config.*
 
# UI components (shadcn/ui)
components/ui/

Add Scripts to package.json

package.json
{
  "scripts": {
    "check": "ultracite check",
    "fix": "ultracite fix",
    "lint": "eslint .",
    "lint:fix": "eslint --fix .",
    "lint:css": "stylelint '**/*.css'",
    "lint:css:fix": "stylelint '**/*.css' --fix",
    "format": "prettier --check .",
    "format:fix": "prettier --write ."
  }
}

Verify Installation

# Check for issues without fixing
npm run check
 
# Auto-fix issues
npm run fix
 
# Run ESLint
npm run lint
 
# Run Stylelint
npm run lint:css
 
# Check formatting
npm run format

Configuration Options

Custom TypeScript Project Paths

For monorepos or custom tsconfig locations, pass the project option:

eslint.config.mjs
import base from "@strongtie/eslint/base"
import react from "@strongtie/eslint/react"
 
export default [
  { ignores: ["**/dist/", "**/node_modules/"] },
 
  // Monorepo with multiple tsconfig files
  ...base({
    project: ["./apps/*/tsconfig.json", "./packages/*/tsconfig.json"],
  }),
 
  ...react,
]

Node.js Scripts Config

For build scripts and tooling that run in Node.js:

eslint.config.mjs
import base from "@strongtie/eslint/base"
import react from "@strongtie/eslint/react"
import scripts from "@strongtie/eslint/scripts"
 
export default [
  { ignores: ["**/dist/"] },
  ...base(),
  ...react,
  ...scripts, // Relaxes rules for scripts/**/*.{js,mjs,ts}
]

Vite Projects (React Refresh)

For Vite projects, add the react-refresh plugin:

npm install -D eslint-plugin-react-refresh
eslint.config.mjs
import base from "@strongtie/eslint/base"
import react from "@strongtie/eslint/react"
import reactRefresh from "eslint-plugin-react-refresh"
import { defineConfig } from "eslint/config"
 
export default defineConfig([
  { ignores: ["**/dist/"] },
  ...base(),
  ...react,
  {
    plugins: {
      "react-refresh": reactRefresh,
    },
    rules: {
      "react-refresh/only-export-components": [
        "warn",
        { allowConstantExport: true },
      ],
    },
  },
])

Named Imports

You can also use named imports:

eslint.config.mjs
import { base, react, scripts } from "@strongtie/eslint"
 
export default [...base(), ...react, ...scripts]

What Rules Are Configured

TypeScript Rules (Relaxed)

The package relaxes several strict TypeScript rules for practical development:

RuleSettingReason
@typescript-eslint/no-unsafe-*offToo strict for real-world code
@typescript-eslint/no-floating-promisesoffCommon in React Query callbacks
@typescript-eslint/no-non-null-assertionwarnCan cause runtime errors
@typescript-eslint/no-shadowwarnVariable shadowing causes confusion
@typescript-eslint/prefer-nullish-coalescingoff|| is often intentional for falsy coalescing
@typescript-eslint/use-unknown-in-catch-callback-variableoffToo strict for practical catch handling

React Rules

RuleSettingReason
react/jsx-indent*offHandled by Prettier/Biome
react/jsx-no-constructed-context-valuesoffReact 19 Compiler handles memoization
react/function-component-definitionoffNext.js uses export default function
react-hooks/purityoffToo strict for practical use
react-hooks/todooffReact Compiler not yet adopted
react-hooks/immutabilityoffReact Compiler not yet adopted

Accessibility Rules

RuleSettingReason
jsx-a11y/prefer-tag-over-rolewarnEncourages semantic HTML over ARIA

Code Style

RuleSettingReason
no-consolewarnAllowed in development
no-nested-ternaryoffSometimes clearer than if/else
unicorn/filename-caseoffExisting codebase conventions
unicorn/number-literal-caseoffConflicts with Prettier
unicorn/no-await-expression-memberoff(await foo).bar is valid
sonarjs/cognitive-complexityoffHandled elsewhere
sonarjs/different-types-comparisonoffSSR check pattern is valid
logical-assignment-operatorsoffStylistic preference
no-await-in-loopoffSometimes necessary

Custom Rules

The @strongtie/eslint package includes custom ESLint rules:

RuleSettingReason
@strongtie/no-static-inline-styleerrorUse Tailwind or CSS modules instead of inline styles
// ❌ Bad - static inline styles
<div style={{ color: "red" }} />
<div style={{ margin: 0, padding: 10 }} />
 
// ✅ OK - dynamic content (allowed)
<div style={{ color: dynamicColor }} />
<div style={{ width: `${size}px` }} />
<div style={styleObject} />

Stylelint Rules

RuleSettingReason
at-rule-no-unknownAllows TailwindSupports @tailwind, @apply, @layer, etc.

Monorepo Setup

For monorepos using Turbo:

turbo.json
{
  "tasks": {
    "lint": {
      "dependsOn": ["^lint"],
      "outputs": []
    },
    "check": {
      "outputs": []
    },
    "fix": {
      "outputs": []
    }
  }
}

Each workspace package should have its own config files or inherit from the root.

Troubleshooting

ESLint 10 Compatibility Error

If you see this error:

TypeError: Error while loading rule 'react/boolean-prop-naming': contextOrFilename.getFilename is not a function

You're using ESLint 10. Downgrade to ESLint 9:

npm install -D eslint@^9

Missing Peer Dependencies

If you see Cannot find package 'eslint-plugin-*' errors, install the missing peer dependencies from Step 4 above.

TypeScript Parser Errors

Ensure your tsconfig.json includes all files being linted:

tsconfig.json
{
  "include": ["src/**/*", "**/*.ts", "**/*.tsx"]
}

ESLint Binary Not Found

If npm run lint fails with "command not found":

npm install -D eslint@^9

Stylelint CSS Parsing Errors

If Stylelint reports errors on non-CSS files, ensure your .stylelintignore excludes them (see Step 7 above).

Next Steps

Design Standards

Learn the design patterns and best practices for React applications.

AGENTS.md Template

Get the AGENTS.md template for AI-assisted development.

Getting StartedInstalling the @strongtie/design-system Package

On This Page

What's IncludedPrerequisitesInstallationConfiguration OptionsCustom TypeScript Project PathsNode.js Scripts ConfigVite Projects (React Refresh)Named ImportsWhat Rules Are ConfiguredTypeScript Rules (Relaxed)React RulesAccessibility RulesCode StyleCustom RulesStylelint RulesMonorepo SetupTroubleshootingESLint 10 Compatibility ErrorMissing Peer DependenciesTypeScript Parser ErrorsESLint Binary Not FoundStylelint CSS Parsing ErrorsNext Steps

Contribute

  • Report an issue
  • Request a feature
  • Edit this page