👋
Shared configuration for Tilt/Shift TypeScript projects.
- Biome — lint + format
- TypeScript — shared base
tsconfig - Codebook — shared spelling dictionary
- Add this repo as a submodule:
git submodule add https://github.com/tiltshift/config.git packages/config- Add the workspace, resolution, and development dependency to the root
package.json:
{
"workspaces": [
"packages/*"
],
"resolutions": {
"@tiltshift/config": "workspace:*"
},
"devDependencies": {
"@tiltshift/config": "workspace:*"
}
}- Install dependencies:
yarn installAny repo that other repos add as a submodule, including this one and
tiltshift/schema, does three things:
- Sets
"root": falsein itsbiome.json. - Passes
--config-path=biome.jsonto everybiomecommand in itspackage.jsonscripts. - Commits
.zed/settings.jsonwithlsp.biome.settings.config_pathset tobiome.json.
Biome 2.5 exits with Found a nested root configuration when it finds a second
root config inside a consumer. It also ignores a nested config that has no root
above it unless the path is given explicitly. Consumers need no exclusion:
their biome.json is the single root, and the submodule's files are linted and
formatted under it in the editor and on the CLI.
Add git submodule updates to .github/dependabot.yml:
version: 2
updates:
- package-ecosystem: gitsubmodule
directory: "/"
schedule:
interval: weeklyEach submodule bump arrives as a PR, where yarn check shows the fallout.
Add a biome.json to your repo that extends the shared base:
{
"$schema": "https://biomejs.dev/schemas/2.5.13/schema.json",
"extends": ["@tiltshift/config/biome"]
}This package does not currently ship any Biome plugins. The submodule sits at a
fixed path, so a consumer registers a shared plugin as
./packages/config/lint/<name>.grit in its own plugins array. Extending the
base still cannot activate a plugin.
GritQL plugins cannot inspect comment trivia in Biome 2.5.12. Enforcing the ban
on Linear issue IDs such as TS-123 in source comments remains a CI script
item, not a Biome plugin.
Keep this maintenance workflow with the shared config it governs. A consumer template may direct contributors here, but it cannot own the Biome rule dry run or suppression policy for existing repositories.
- When a review catches something a machine could catch, file a TS issue with
the
configlabel. Link the review comment and include the code snippet and proposed rule. - Add the rule here and put Biome rule dry-run counts for each repo in the config PR.
- For a small count, set the rule to
errorand fix the hits in the consumer bump PR. For a large count, runbiome lint --suppress --reason "predates the rule"in the bump PR so new code is held to the rule and the suppressions form the backlog. - Merge the config PR. Dependabot's
gitsubmoduleupdates open the consumer bump PRs, whereyarn checkshows the fallout. - Revisit a rule that keeps getting suppressed. Do not accumulate suppressions for it.
A dry run counts what one Biome rule would flag in every Tilt/Shift repo that extends this config, before the rule ships. Put the counts in the config PR.
Set up once. List the checkouts in a gitignored .dry-run-repos file at
this repo's root, one path per line. Paths can be absolute, start with ~/,
or be relative to this repo. Blank lines and # comments are skipped.
../code-glue
/path/to/chat-builder
Count one rule:
yarn dry-run correctness/noUnusedVariablesCount every rule in this package's biome.json, printed as a table for
the PR body:
yarn dry-run all --markdownBoth modes run this repo's pinned Biome, so counts match the base rather than
whatever each checkout resolves. The all mode honors each checkout's
.gitignore, so build output is not counted.
A run fails if a listed checkout is missing, Biome cannot produce a JSON report there, or Biome processes no files. Diagnostics alone do not fail the run; they are the count.
Extend the shared base from your root tsconfig.json:
{
"extends": "@tiltshift/config/tsconfig"
}Each app or package extends the repo root and overrides only what its platform needs — JSX for web, module settings for React Native/Expo, node types for servers. Overrides are the exception.
Spell checking in Zed uses Codebook.
Point Codebook at the shared Tilt/Shift word list in the submodule from the
project's .zed/settings.json:
{
"lsp": {
"codebook": {
"initialization_options": {
"globalConfigPath": "packages/config/codebook.toml"
}
}
}
}