Shared ESLint, Prettier, TypeScript, Vitest, and lint-staged configs for my projects.
Install from GitHub:
npm install --save-dev github:DavidTeju/dev-config| Export path | Description |
|---|---|
./eslint/base |
Base ESLint flat config + strict rules + file overrides |
./eslint/svelte |
Pre-composed ESLint config for SvelteKit |
./eslint/nextjs |
ESLint config pieces for Next.js (compose yourself) |
./prettier/base |
Base Prettier config (tabs, single quotes, no framework plugins) |
./prettier/svelte |
Prettier config with svelte + tailwind plugins |
./prettier/nextjs |
Prettier config with tailwind plugin |
./tsconfig/node |
TypeScript config for plain Node/backend services (NodeNext, ESM, strict) |
./tsconfig/node-native |
node preset for TypeScript that Node runs directly with type stripping (no build step) |
./tsconfig/svelte |
TypeScript config for SvelteKit |
./tsconfig/nextjs |
TypeScript config for Next.js |
./vitest/node |
Vitest config factory for plain Node/TS services (node env + optional @ alias) |
./vitest/nextjs |
Vitest config factory for Next.js (jsdom + React + @ alias) |
./lint-staged/node |
lint-staged config for Node/TS services |
./lint-staged/svelte |
lint-staged config for SvelteKit |
./lint-staged/nextjs |
lint-staged config for Next.js |
For plain Node + TypeScript services (no framework), compose the base pieces:
// eslint.config.mjs — the base factory is framework-less; omit `framework`.
import { createConfig } from '@davidteju/dev-config/eslint';
export default await createConfig({ typeChecked: true });// .prettierrc.mjs
export { default } from '@davidteju/dev-config/prettier/base';// vitest.config.mjs
import { createVitestConfig } from '@davidteju/dev-config/vitest/node';
export default createVitestConfig({ rootDir: import.meta.dirname });// lint-staged.config.mjs
export { default } from '@davidteju/dev-config/lint-staged/node';The
nodetsconfig assumes ESM (verbatimModuleSyntax) — set"type": "module"inpackage.json. It intentionally omitsoutDir/rootDir(paths in an extended base resolve relative to the base file, not your project) so set those in your own tsconfig.
For scripts and CLIs that Node runs as .ts with its built-in type stripping (Node 23.6+,
no tsc build), extend node-native instead. It adds noEmit, allowImportingTsExtensions
(so imports name the real .ts file) and erasableSyntaxOnly (rejects enums, namespaces and
parameter properties, which type stripping cannot run), and turns off emit-only options.
tsc becomes a type checker only.
// tsconfig.json
{
"extends": "@davidteju/dev-config/tsconfig/node-native",
"include": ["*.ts"]
}Keep projects that compile with tsc and an outDir on node:
allowImportingTsExtensions requires noEmit.
All ESLint configs use the flat config format (ESLint 9+).
svelteConfig() returns a complete, ready-to-use config array:
// eslint.config.js
import { svelteConfig } from '@davidteju/dev-config/eslint/svelte';
import svelteConf from './svelte.config.js';
export default svelteConfig({ svelteConfig: svelteConf });Next.js re-exports individual config pieces for you to compose with eslint-config-next:
// eslint.config.mjs
import { defineConfig, globalIgnores } from 'eslint/config';
import nextVitals from 'eslint-config-next/core-web-vitals';
import nextTs from 'eslint-config-next/typescript';
import {
strictRules,
testFileOverrides,
vitestTestOverrides,
scriptFileOverrides,
} from '@davidteju/dev-config/eslint/nextjs';
export default defineConfig([
...nextVitals,
...nextTs,
strictRules,
testFileOverrides,
vitestTestOverrides,
scriptFileOverrides,
globalIgnores(['.next/**', 'out/**', 'build/**', 'next-env.d.ts']),
]);strictRules -- applied to all source files:
- Prettier as an ESLint rule (
prettier/prettier: error) - TypeScript strictness: no
any, consistent type imports, no non-null assertions - Bans
as anyandas unknown as Xdouble casts via AST selectors - Code quality: complexity cap (15), no nested ternaries, no param reassignment
- Security: no
eval/implied-eval
testFileOverrides -- relaxes strict rules for test files (**/*.{test,spec}.{ts,tsx}, **/__tests__/**, **/benchmark/**):
- Allows
any, type casts, non-null assertions,console, and rawDateusage
vitestTestOverrides -- adds Vitest-specific lint rules (requires @vitest/eslint-plugin):
vitest/no-conditional-in-test: bansifstatements inside test bodiesvitest/no-conditional-expect: bans conditionalexpect()calls
Gracefully degrades to a no-op {} if @vitest/eslint-plugin is not installed.
scriptFileOverrides -- relaxes rules for scripts/**/*.ts (CLI tooling, build scripts).
// prettier.config.mjs (Next.js)
export { default } from '@davidteju/dev-config/prettier/nextjs';
// prettier.config.mjs (SvelteKit)
export { default } from '@davidteju/dev-config/prettier/svelte';Both configs use tabs, single quotes, 100-char print width, and prettier-plugin-tailwindcss. The Svelte config additionally includes prettier-plugin-svelte and sets trailingComma: 'none'.
// tsconfig.json (Next.js)
{
"extends": "@davidteju/dev-config/tsconfig/nextjs",
"compilerOptions": {
"paths": { "@/*": ["./src/*"] }
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}// tsconfig.json (SvelteKit)
{
"extends": "@davidteju/dev-config/tsconfig/svelte"
}Note:
pathsmust be defined in the consuming project's tsconfig, not the shared one, because TypeScript resolves paths relative to the tsconfig file location.
// vitest.config.mts
import { defineConfig } from 'vitest/config';
import { createVitestConfig } from '@davidteju/dev-config/vitest/nextjs';
export default defineConfig(
createVitestConfig({
rootDir: import.meta.dirname,
setupFiles: ['./src/test/setup.ts'],
env: { DATABASE_URL: 'postgres://localhost/test' },
})
);The factory sets up jsdom, @vitejs/plugin-react, @ path alias to src/, v8 coverage, and scopes test discovery to src/**/*.{test,spec}.{ts,tsx}.
// lint-staged.config.mjs (Next.js)
export { default } from '@davidteju/dev-config/lint-staged/nextjs';
// lint-staged.config.mjs (SvelteKit)
export { default } from '@davidteju/dev-config/lint-staged/svelte';Required: eslint, prettier, typescript
Optional (install only what your framework needs):
| Peer | Used by |
|---|---|
eslint-config-next |
eslint/nextjs |
prettier-plugin-svelte |
prettier/svelte |
prettier-plugin-tailwindcss |
prettier/svelte, prettier/nextjs |
vitest |
vitest/nextjs |
@vitest/eslint-plugin |
vitestTestOverrides in eslint/base |
MIT