OneApp Docs
PackagesCore

@repo/config

Shared ESLint, TypeScript, Prettier, Stylelint, and tsdown build configurations for the monorepo. One config, consistent code style and builds everywhere. Import once, never configure again. Works with Node.js, React, Next.js, and Expo.

Quick Start

Add shared configs in 2 minutes:

pnpm add -D @repo/config

Zero config linting, type-checking, and formatting. Skip to Quick Start →

Why @repo/config?

Every package has different ESLint rules. Developers argue about semicolons, quotes, and trailing commas. TypeScript strict mode varies by project. Prettier formats code differently across teams. New packages start from scratch with configuration. Updating lint rules requires changing 20 config files.

@repo/config solves this with shared, pre-configured linting, type-checking, and formatting rules for the entire monorepo.

Production-ready with ESLint 9 flat config, TypeScript 5 strict mode, Prettier 3 with Tailwind plugin, and Stylelint for CSS.

Use cases

  • Consistent code style — Same linting rules across all packages and apps
  • Zero config for new packages — Import preset, start coding immediately
  • Team-wide standards — Enforce best practices automatically
  • TypeScript strict mode — Type safety by default with strict compiler options
  • Auto-formatting — Prettier formats code on save with shared rules

How it works

@repo/config exports pre-configured presets for each stack:

// Next.js app
import nextConfig from "@repo/config/eslint/next";

export default [...nextConfig];

// TypeScript inherits strict mode, JSX settings
// Prettier auto-formats with 100-char line width
// No setup needed—just import and code

Uses ESLint 9 flat config with stack-specific plugins, TypeScript extends with strict mode enabled, and Prettier with Tailwind CSS class sorting.

Key features

Stack-specific configs — Optimized presets for Node.js, React, Next.js, Expo

ESLint 9 flat config — Modern configuration format with plugin support

TypeScript strict mode — Type safety with strict: true, noUncheckedIndexedAccess

Prettier with Tailwind — Auto-format code and sort Tailwind classes

Stylelint for CSS — Property order, color format, BEM naming conventions

Extensible — Override rules while maintaining base consistency

Quick Start

1. Install the package

pnpm add -D @repo/config

2. Import ESLint config for your stack

eslint.config.mjs
import nextConfig from "@repo/config/eslint/next";

export default [...nextConfig];
eslint.config.mjs
import reactConfig from "@repo/config/eslint/react";

export default [...reactConfig];
eslint.config.mjs
import nodeConfig from "@repo/config/eslint/node";

export default [...nodeConfig];

3. Extend TypeScript config

tsconfig.json
{
  "extends": "@repo/config/typescript/nextjs",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "#/*": ["./src/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"]
}
tsconfig.json
{
  "extends": "@repo/config/typescript/react",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "#/*": ["./src/*"]
    }
  },
  "include": ["src/**/*"]
}

4. Add Prettier config

prettier.config.mjs
import prettierConfig from "@repo/config/prettier";

export default prettierConfig;

That's it! Your package now has ESLint, TypeScript, and Prettier configured with monorepo standards.

Override rules when needed

Extend configs and add custom rules:

import nextConfig from "@repo/config/eslint/next";

export default [
  ...nextConfig,
  {
    rules: {
      "no-console": "warn" // Custom rule
    }
  }
];

Technical Details

For Developers: Technical implementation details

Overview

PropertyValue
Locationpackages/config
ContainsESLint, TypeScript, Prettier, Stylelint configs

Export Paths

PathDescription
@repo/config/eslint/nodeNode.js ESLint config
@repo/config/eslint/reactReact ESLint config
@repo/config/eslint/nextNext.js ESLint config
@repo/config/eslint/expoExpo ESLint config
@repo/config/typescript/baseBase TypeScript config
@repo/config/typescript/reactReact TypeScript config
@repo/config/typescript/nextjsNext.js TypeScript config
@repo/config/prettierPrettier config
@repo/config/stylelintStylelint config

ESLint Configurations

Node.js

// eslint.config.mjs
import nodeConfig from "@repo/config/eslint/node";

export default [...nodeConfig];

React

// eslint.config.mjs
import reactConfig from "@repo/config/eslint/react";

export default [...reactConfig];

Next.js

// eslint.config.mjs
import nextConfig from "@repo/config/eslint/next";

export default [...nextConfig];

Expo

// eslint.config.mjs
import expoConfig from "@repo/config/eslint/expo";

export default [...expoConfig];

With Custom Rules

Extending Configs

You can extend any configuration and add your own custom rules while maintaining consistency.

// eslint.config.mjs
import reactConfig from "@repo/config/eslint/react";

export default [
  ...reactConfig,
  {
    rules: {
      // highlight-start
      // Override or add rules
      "no-console": "warn"
      // highlight-end
    }
  }
];

TypeScript Configurations

Base

// tsconfig.json
{
  "extends": "@repo/config/typescript/base"
}

React

// tsconfig.json
{
  "extends": "@repo/config/typescript/react",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "#/*": ["./src/*"]
    }
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Next.js

// tsconfig.json
{
  "extends": "@repo/config/typescript/nextjs",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "#/*": ["./src/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

Prettier Configuration

// prettier.config.mjs
import prettierConfig from "@repo/config/prettier";

export default prettierConfig;

Default Settings

{
  printWidth: 100,
  tabWidth: 2,
  useTabs: false,
  semi: true,
  singleQuote: false,
  quoteProps: "as-needed",
  jsxSingleQuote: false,
  trailingComma: "es5",
  bracketSpacing: true,
  bracketSameLine: false,
  arrowParens: "always",
  endOfLine: "lf",
  plugins: ["prettier-plugin-tailwindcss"],
}

Stylelint Configuration

// stylelint.config.mjs
import stylelintConfig from "@repo/config/stylelint";

export default stylelintConfig;

Default Rules

  • CSS property order
  • Color format consistency
  • No invalid hex colors
  • No duplicate selectors
  • BEM naming convention support

TypeScript Base Configuration

Strict Mode

All TypeScript configs enable strict mode by default. This ensures maximum type safety across the monorepo.

The base configuration includes:

{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022"],
    "module": "ESNext",
    "moduleResolution": "bundler",
    // highlight-start
    "strict": true,
    "noUncheckedIndexedAccess": true,
    // highlight-end
    "noEmit": true,
    "declaration": true,
    "declarationMap": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "isolatedModules": true
  }
}

React Configuration Additions

{
  "compilerOptions": {
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "jsx": "react-jsx",
    "moduleResolution": "bundler"
  }
}

Next.js Configuration Additions

{
  "compilerOptions": {
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "jsx": "preserve",
    "moduleResolution": "bundler",
    "plugins": [{ "name": "next" }]
  }
}

tsdown Build Configurations

tsdown presets provide pre-configured build settings for different platforms. Uses tsdown (powered by Rolldown) for fast, modern bundling.

Platform Presets

PresetTargetUse Case
nodeNode.js 20Server-side packages, CLI tools
browserES2022Browser libraries
reactES2022 + JSXReact component libraries
clientES2022 + JSXClient-side React with browser APIs

Basic Usage

tsdown.config.mjs
import { node } from "@repo/config/tsdown";

export default {
  ...node,
  entry: { index: "src/index.ts" }
};

Distribution Builds (@oneapp/*)

For packages published to GitHub Packages as @oneapp/*, use createDistConfig:

tsdown.config.mjs
import { createDistConfig } from "@repo/config/tsdown";

export default createDistConfig(
  "react",
  {
    index: "src/index.ts",
    client: "src/client.ts",
    server: "src/server.ts"
  },
  {
    external: ["better-auth", "zod"]
  }
);

Key features of distribution builds:

  • Bundles @repo/* dependencies — Internal workspace packages are inlined
  • Rewrites imports@repo/*@oneapp/* for unresolved externals
  • Externalizes frameworks — React, Next.js, Prisma remain peer dependencies
  • Generates .d.ts — TypeScript declarations for consumers

Export Paths

PathDescription
@repo/config/tsdownAll presets + createDistConfig
@repo/config/tsdown/baseBase preset only

Platform Preset Details

Node.js

import { node } from "@repo/config/tsdown";
// Target: node20, Format: ESM, Externals: node: builtins

Browser

import { browser } from "@repo/config/tsdown";
// Target: es2022, Format: ESM, No Node.js APIs

React

import { react } from "@repo/config/tsdown";
// Target: es2022, Format: ESM, JSX support, React externalized

Client (React + Browser)

import { client } from "@repo/config/tsdown";
// Target: es2022, Format: ESM, JSX + Browser APIs, React externalized

On this page