JavaScript and TypeScript
gspot checks JavaScript and TypeScript with ESLint, the TypeScript compiler, and Knip, which finds code that nothing
uses. These checks run for the javascript and typescript configurations:
| Check | Stage | What it does |
|---|---|---|
javascript/eslint | commit | Runs the shipped ESLint rules on JavaScript, TypeScript, component files, and package.json. |
javascript/tsc | push | Type-checks plain JavaScript through its JSDoc comments. |
javascript/knip | push | Finds files, exports, and dependencies nothing uses. |
typescript/tsc | push | Runs tsc with the strict compiler options over every TypeScript file. |
typescript/tsconfig | commit | Requires strict in every tsconfig you write. Level all also requires noUncheckedIndexedAccess, exactOptionalPropertyTypes, noImplicitOverride, noFallthroughCasesInSwitch, noImplicitReturns, and noPropertyAccessFromIndexSignature. |
Framework configurations, such as react, nextjs, and react-native, add their own lint rules. A React project that
depends on react-dom also gets the react-dom configuration and its DOM accessibility lint rules. The
configuration reference lists every framework.
JavaScript runtimes
Section titled “JavaScript runtimes”Each file gets one ESLint runtime:
| Files | Runtime |
|---|---|
| Ordinary modules and build scripts | Node.js built-ins |
.cjs and .cts files |
Node.js built-ins and CommonJS globals |
| React, Vue, and Svelte application sources | Browser globals |
| React Native sources | Native globals |
| Next.js sources | Node.js built-ins, since server components can use them |
To give some files another runtime, add a [[tools.eslint.override]] record. Write paths relative to the repository
root. When records overlap, the later one counts.
[[tools.eslint.override]]paths = ["src/client/**"]runtime = "browser"
[[tools.eslint.override]]paths = ["src/workers/**"]runtime = "worker"
[[tools.eslint.override]]paths = ["src/serviceworker.js"]runtime = "serviceworker"Use an explicit node runtime for server code inside a browser or React Native project. Runtime names follow the
pinned globals package. Use serviceworker for service workers, which have
other APIs than Web Workers. An unknown runtime name stops gspot before it writes tool files.
Browser and native files get no Node.js lint rules. React Native files keep the process and require globals, but
get no other Node.js globals, such as Buffer and __dirname.
TypeScript compiler
Section titled “TypeScript compiler”TypeScript source files or your own tsconfig.json select the TypeScript checks. A TypeScript tool dependency or
declaration files alone do not.
The checks use the TypeScript compiler of your project. Without one, gspot uses its pinned compiler from the tool
project before any global compiler. gspot install installs the pinned compiler.
Your own tsconfig.json keeps its compiler options and gets the strict ones that the selected level requires. When a
scope has no tsconfig.json of your own, gspot writes a standalone compiler project for its source files and
declarations. That project leaves out generator output, vendored files, and child scopes.
JavaScript checks extend your own jsconfig.json, or your tsconfig.json when no jsconfig.json exists. From a
tsconfig.json, they keep the compiler options and declarations but select only JavaScript sources.
Your own JSX setting stays; without one, the generated project uses jsx: "preserve". A scope with neither file uses
Bundler resolution when imports without extensions name JavaScript source files. Ambient types come from the source
project, including your own type roots.
Next.js
Section titled “Next.js”The Next.js configuration runs nextjs/tsc instead of typescript/tsc, at level recommended and stage push. The
check has Next.js write its types, then type-checks the app with the strict compiler options. The project must provide
Next.js 15.5 or later. The Next.js Semgrep rules run in security/semgrep.
React Native
Section titled “React Native”gspot init selects react-native and expo from their dependencies. The Expo configuration requires React Native and
adds Expo lint rules and expo/expo-doctor. A bare React Native project needs no Expo tool. Native sources keep the
React hooks and component lint rules.
If a component wraps the React Native Text, add its name to the skip option of the lint rule:
gspot set tools.eslint.rules '{ "react-native/no-raw-text" = [{ skip = ["ThemedText"] }] }'This allows text inside ThemedText. The lint rule still reports bare text inside a View. When other projects use
other components, set the option in the scope of the native project.
Settings that change lint rule options
Section titled “Settings that change lint rule options”| Setting | What it sets |
|---|---|
structure.environment_readers |
The files that may read environment variables, for n/no-process-env, no-restricted-properties, and no-restricted-syntax |
tools.eslint.import_extension |
The import extension option of n/file-extension-in-import |
limits.index_exports |
amountOfExportsToConsiderModuleAsBarrel of barrel-files/avoid-barrel-files |
structure.reexports = "index-only" |
Lets index files re-export; ESLint re-export rules and gspot/no-trivial-files skip them |
The environment reader checks run at level all. The limits on index files that re-export other files run at level
all too, and only when you allow re-exports. The ESLint plugin page lists the options of
its lint rules.