Why this matters
Turborepo is the canonical “modern, well-tooled, dual-language
Rust+TS monorepo” — exactly the audience alint’s monorepo bundles
target. A Rust workspace (crates/turbo*, 61 crates) plus a
pnpm workspace (packages/*, apps/*, examples/*, 17
first-party packages plus 30 examples), with all language-level
lints delegated to the canonical per-ecosystem tools — cargo fmt
/ cargo clippy / cargo deny for Rust, oxlint / oxfmt /
taplo / attw for TS — and turborepo itself + a husky pre-push
hook orchestrating them. There is no xtask/ crate, no
.changeset/ directory, no hack/verify-*.sh pipeline.
That means the structural-validation surface area is small and almost entirely about monorepo conventions rather than language semantics — exactly the layer where alint adds a structural floor that doesn’t exist in the existing tooling stack.
Headline catch
Kubernetes has 50 hand-rolled verify scripts → alint replaces 17. Turborepo has zero hand-rolled verify scripts (everything delegated to per-language tools) → alint adds ~22 structural gates that don’t exist today at all.
Even a project with Vercel-grade tooling has structural drift that no per-language linter catches.
The findings on the actual repo are real and actionable:
- 60 of 61 crates are missing the
publish = falseguard — onecargo publish --workspacefrom a maintainer’s machine would otherwise leak internal-only crates to crates.io - 8 of 17 packages lack a per-package LICENSE (problematic
for
npm packsince the repo-root LICENSE doesn’t auto-include in tarballs) - 9 of 52 crates are missing READMEs
- 7 crates have a directory name that doesn’t match the published
crate name (
crates/turborepo-globwalkis published asglobwalk,crates/turborepo-pathsasturbopath, etc.) — intentional namespacing drift, but new drift is almost always a mistake - One example (
with-microfrontends) is silently skipped from thecheck-examples.tssandbox runs because it lacksmeta.json;with-nextjsis missingturbo.json
These are conventions enforced today only by package.json /
Cargo.toml review etiquette. None of them surface from running
cargo clippy, oxlint, taplo, or attw.
Where alint earns its keep here
- One declarative file (~22 structural gates) replaces what’s
currently spread across
pre-pushshell +lint.ymljobs + a TypeScript runner.for_each_dirover the 61 crates + 17 packages + 30 examples covers the per-package layout, manifest fields, license presence, and meta.json/turbo.json shape in tens of milliseconds. - 7
command:rule shell-outs to the canonical per-language tools (cargo fmt / cargo clippy / cargo deny / oxlint / oxfmt / taplo / shellcheck) — alint isn’t faster than the underlying tools, but running them all in parallel under onealint checkshaves wall time vs. the sequential pre-push chain. dir_name_matches_fieldis the v0.10+ headline demand-driver here. Both Cargo and npm let the directory name diverge from the published name; turbo has 7 such crates and 7 such packages that are intentional, but new drift is almost always a mistake. The v0.10+ design needs apaths.exclude:orallow_drift:knob — turbo is the canonical “expected drift, allowlist 7” demonstration.json_schema_passesis the v0.10+ second-most-load-bearing missing primitive. Turborepo ships its own schema (docs/public/schema.json) and expects users to validateturbo.jsonagainst it via the$schemafield. tsconfig.json, oxlint configs, etc. all publishing schemas — broad demand even if per-repo confirmations are modest.- The
alint pr-diff-checksibling-mode candidate — Turborepo has a hand-rolled “release PRs may only touch version.txt / package.json / Cargo.toml / Cargo.lock / CHANGELOG / pnpm-lock.yaml” guard viagh api repos/.../pulls/N/files. A separate-binaryalint pr-diff-checkmode is a v0.10+ design candidate; doesn’t fit thealint check(repo-state-only) model.
Future story angles
- The kubernetes ↔ turbo contrast is the launch hook — 50 hand- rolled scripts to alint replacing 17 on one end; zero hand-rolled scripts to alint adding 22 structural gates that don’t exist on the other. Use this on alint.org/examples as evidence that monorepo conventions are under-checked even at top-tier-tooling repos.
- Hybrid-monorepo launch narrative — pair turbo with next.js (the dual pnpm + Cargo mega-monorepo) for a “modern monorepo tier” launch tile pair. Same Vercel ecosystem; very different scales (turbo: 17 packages + 61 crates; next.js: 19 packages + 63 crates + 30 workflows); both have structural drift no per-language linter catches.
dir_name_matches_fieldv0.10+ design narrative — turbo is the demand source AND the expected-drift example. When the rule kind ships, the launch-post writes itself: “turbo has 7 crates with intentional name/dir drift; alint catches the new drift while letting the historical drift be allow-listed.”scope_filterevolution refactor —crates//packages//examples/triad as named scopes; cuts ~20 lines and clarifies per-example rule intent. Canonical demonstration of the v0.9.17 named-scope payoff for triple-subtree monorepos.