Roll in style.
Highly opinionated configuration files for typescript projects. Inspired by @vercel/style-guide
Warning
Make sure to first commit your code before running the following commands. To allow you to easily revert the changes.
npm i -D @timobechtel/style prettier "eslint@^9" typescriptcurl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/.prettierrcExtend / customize config
Need to extend the config, e.g. adding plugins?
curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/.prettierrc.mjsCreate a .prettierrc.mjs file and import the config, like this:
import config from '@timobechtel/style/prettier/index.mjs';
/**
* @type {import("prettier").Config}
*/
export default {
...config,
// your config
}For existing projects or templates, I recomment leaving the config as-is and adding this preset to the extends array.
{
"extends": ["@timobechtel/style/tsconfig/core"]
}curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/tsconfig/core/tsconfig.jsonWith expo make sure to add "moduleResolution": "bundler" to the compilerOptions, otherwise certain routing types might break.
Example
Copy to tsconfig.json:
{
"extends": ["expo/tsconfig.base", "@timobechtel/style/tsconfig/core"],
"compilerOptions": {
"moduleResolution": "bundler", // <-- this is important
"strict": true,
"paths": {
"@/*": [
"./*"
]
}
},
"include": [
"**/*.ts",
"**/*.tsx",
".expo/types/**/*.ts",
"expo-env.d.ts"
]
}curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/tsconfig/react/tsconfig.jsonOr manually
Copy to tsconfig.json:
{
"extends": "@timobechtel/style/tsconfig/react"
}curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/eslint/core/eslint.config.jsNote: If your project is not ESM (no "type": "module" in package.json), rename the file to eslint.config.mjs.
Or manually
Copy the following to an eslint.config.js:
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { defineConfig } from 'eslint/config';
import styleCore from '@timobechtel/style/eslint/core.js';
import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
import { createNodeResolver } from 'eslint-plugin-import-x';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default defineConfig([
...styleCore,
{
languageOptions: {
parserOptions: {
tsconfigRootDir: __dirname,
},
},
settings: {
'import-x/resolver-next': [
createTypeScriptImportResolver({
project: path.resolve(__dirname, 'tsconfig.json'),
}),
createNodeResolver(),
],
},
},
]);curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/eslint/react/eslint.config.jsOr manually
Also spread styleReact from @timobechtel/style/eslint/react.js:
import styleCore from '@timobechtel/style/eslint/core.js';
import styleReact from '@timobechtel/style/eslint/react.js';
import { defineConfig } from 'eslint/config';
export default defineConfig([
...styleCore,
...styleReact,
// ... your config
]);Example config: https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/eslint/react/eslint.config.js
If you're upgrading from v1.x, you'll need to:
- Upgrade to ESLint v9+
- Replace
.eslintrc.cjswitheslint.config.js - Update imports to use
.jsextension (e.g.,@timobechtel/style/eslint/core.js) - Note: Import plugin rules now use
import-x/prefix instead ofimport/
Note: You should disable source.organizeImports in your VSCode config, as this collides with the import-x/order rule.
Add the following to your VSCode config, e.g. .vscode/settings.json
{
"editor.codeActionsOnSave": {
// use eslint import-x/order instead
"source.sortImports": "never"
}
}This repo also contains a semantic-release configuration.
npm i -D semantic-release @semantic-release/changelog @semantic-release/gitecho '{ "extends": "@timobechtel/style/semantic-release/index.cjs" }' > .releaserc.json