A monorepo containing coding style related packages for Lyra apps (primarily Expo React Native). This coding style includes linting and formatting rules.
To use this coding style, we assume that your technical stack contains:
- expo / react-native
- typescript
- eslint for linting — ESLint 9 flat config for Expo apps (
@lyracom/eslint-config-expo), legacy ESLint 8.eslintrcconfigs for other project types (see ESLint below) - prettier for formatting
- jest for testing
| Package | Description | Version |
|---|---|---|
@lyracom/eslint-config |
ESLint config for pure JavaScript or TypeScript projects | |
@lyracom/eslint-config-expo |
ESLint config for Expo React Native apps (flat config) | |
@lyracom/eslint-config-node |
ESLint config for Node.js applications | |
@lyracom/eslint-config-react |
ESLint config for React applications | |
@lyracom/prettier-config |
Prettier config for TypeScript projects |
pnpm add -D \
"typescript@~5.5.4" \
"@lyracom/tsconfig@^1"Look at all the configurations available in the package (base/node/dom/jsx) and chose the one you want to use in your project. Then create a tsconfig.json file and add the following lines:
{
// always try to use strict TypeScript config
"extends": ["@lyracom/tsconfig/tsconfig-strict.json", "@lyracom/tsconfig/tsconfig-[CONFIG].json"],
// or, if you work on a legacy/poc project or do not want to use strict config
"extends": "@lyracom/tsconfig/tsconfig-[CONFIG].json"
}pnpm add -D \
"prettier@^3" \
"@lyracom/prettier-config@^6" \
"@trivago/prettier-plugin-sort-imports@^6"The prettier config uses the package @trivago/prettier-plugin-sort-imports to sort imports. You can customize this
config if you need a specific order in your imports, if you have import aliases for example.
Check available options on their website: https://github.com/trivago/prettier-plugin-sort-imports
For Expo React Native apps (flat config, ESLint 9+) — recommended
pnpm add -D \
"eslint@^9" \
"typescript@^5" \
"@lyracom/eslint-config-expo"Create an eslint.config.js at the project root:
const { lyraExpoConfig } = require('@lyracom/eslint-config-expo')
module.exports = [
...lyraExpoConfig,
{
// anchor type-aware linting to this project
languageOptions: { parserOptions: { tsconfigRootDir: __dirname } },
},
{
ignores: ['dist/*', '.expo/*'],
},
]This config enables the type-aware @typescript-eslint/no-deprecated rule, so every .ts/.tsx file must be covered
by your tsconfig.json. Promise safety rules (no-floating-promises and no-misused-promises) are explicitly
disabled:
runtime monitoring handles unhandled failures, and intentional fire-and-forget calls use void where appropriate. If
ESLint reports "file was not found by the project service", add the file to your tsconfig include (or ignore it in
eslint.config.js).
The React Compiler-oriented Hooks rules are enabled by the Expo preset as errors. During migration, projects can downgrade them all to warnings with one additional config spread:
const { lyraExpoConfig, reactCompilerRecommendedWarn } = require('@lyracom/eslint-config-expo')
module.exports = [...lyraExpoConfig, ...reactCompilerRecommendedWarn]Migrating from @lyracom/eslint-config-react (legacy .eslintrc):
- Convert your
.eslintrc.jstoeslint.config.js(flat config). - Delete any
promise/*andsonarjs/*overrides — those plugins are no longer bundled, and referencing an unregistered rule is a hard error in flat config. - Delete the
eslint-plugin-deprecationplugin +deprecation/deprecationoverride; it is replaced by the shared, type-aware@typescript-eslint/no-deprecated. - Drop overrides now handled by the shared config:
@typescript-eslint/no-empty-function,@typescript-eslint/ban-ts-comment,react/display-name,react/prop-types. - Keep only genuinely app-specific rules (e.g.
react-hooks/exhaustive-depsadditionalHooks).
Legacy configs (deprecated, ESLint 8 / .eslintrc)
pnpm add -D \
"eslint@^8" \
"@typescript-eslint/eslint-plugin@^5" \
"eslint-plugin-import@^2" \
"eslint-plugin-jest@^27" \
"eslint-plugin-n@^15" \
"eslint-plugin-promise@^6" \
"eslint-plugin-sonarjs@^0.19"Depending the nature of your project, you should also add the following plugins:
For pure JavaScript / TypeScript projects
pnpm add -D \
"@lyracom/eslint-config"For Node.js projects
pnpm add -D \
"@lyracom/eslint-config-node"For React projects
pnpm add -D \
"@lyracom/eslint-config-react" \
"eslint-plugin-react@^7" \
"eslint-plugin-react-hooks@^4"Now install husky:
npx husky-init && pnpm installpnpm add -D lint-stagedFor an Expo app, create the eslint.config.js shown above, then add the shared Prettier config and a lint-stagedsetup
to your package.json:
{
"prettier": "@lyracom/prettier-config",
"lint-staged": {
"*.{js,jsx,ts,tsx}": "eslint",
"*": "prettier -w -u"
}
}The shared ESLint config reports most rules as
warnduring migration, so keepeslint(noteslint --max-warnings 0) inlint-stagedfor now. Switch toeslint --max-warnings 0once your app is clean to make warnings blocking.
Legacy configs (.eslintrc)
{
"eslintConfig": {
// For pure JS / TS projects
"extends": "@lyracom/eslint-config",
// For Node.js projects
"extends": "@lyracom/eslint-config-node",
// For React projects
"extends": "@lyracom/eslint-config-react"
}
}In .husky/pre-commit, add the following lines:
pnpm test
npx lint-stagedOptionally, here are some package.json scripts you can inspire from:
{
"scripts": {
"tsc": "tsc -p tsconfig.json",
"lint": "eslint .",
"format": "prettier -w -u ."
}
}Do not forget to use .prettierignore to exclude files you don't want to format, and the ignores key in
eslint.config.js to exclude files from linting.
All major IDE have integration for ESLint and Prettier, check your settings to enable them.
To contribute at this repo, set up your development environment with this command:
pnpm installDo not push directly on main but submit a pull request instead, thanks :)
All changes are managed with changesets. Whenever you commit a change who
deserves to appear in the changelog, you need to include a change using the command: pnpm changeset.
Continuous integration is handled by GitHub Actions. Workflows are defined in .github folder.
First, launch the version GitHub action. It will create a release pull request.
Once accepted, you can launch the publish GitHub action to publish packages to npm.