Project Bootstrap — Company Tooling Standards
Apply the Socially-Free standard toolchain to a Laravel + Inertia + React project.
Quick Start
- Bun — Delete
package-lock.json, runbun install. Update CI workflows to useoven-sh/setup-bun@v2andbun install/bun run <script>. - Biome — Replace ESLint deps with
@biomejs/biome: "2.4.13". Copyreferences/biome.jsoninto the project. Updatepackage.jsonscripts (lint,lint:check,format:check). Deleteeslint.config.js. Keep Prettier with its plugins — the existing.prettierrc(Tailwind class ordering + import organization) stays; Biome does not offer Tailwind class sorting. Runbun install. - Composer scripts — Replace the starter kit's scripts section with
references/composer-scripts.json. Keep the starter kit'spost-autoload-dump,post-update-cmd,post-root-package-installscripts intact — only replace the user-facing ones. Ensuretest:lint(pint --parallel --test) andlint(pint --parallel) exist. - Laravel Wayfinder — The
generate:routingcomposer script relies onphp artisan wayfinder:generate. Install the Laravel Wayfinder package so this command is available. Follow the Laravel Wayfinder installation instructions for your project. - CI workflows — Copy
references/lint.ymlandreferences/tests.ymlinto.github/workflows/. The lint workflow uses check-only commands (pint --test,biome ci) so it FAILS on formatting drift instead of silently fixing and discarding it. - Formatting enforcement (hooks) — Add
husky+lint-staged(mergereferences/package-json.snippets.jsoninto package.json, copyreferences/pre-commitinto.husky/pre-commit), runbun installto wire the hooks. Pre-commit runs pint / biome --write / prettier --write on staged files only — Biome first, Prettier last, so Prettier owns the final on-disk state (CSS quote style, import order, Tailwind class order). - .gitignore — Ensure
bun.lockis tracked (not gitignored).
Run bun run build, composer fix, and git commit (to confirm the pre-commit hook fires) to verify.
Verification
-
bun run buildpasses -
composer test:lintpasses (pint --test, exit 0 = no drift) -
bun run lint:checkpasses (biome ci, exit 0 = no drift) -
git config core.hooksPathoutputs.husky/_(hooks wired) - A deliberately misformatted staged file gets reformatted by the pre-commit hook on commit
-
eslint.config.jsis deleted;.prettierrcand.prettierignoreare kept (Prettier owns Tailwind class ordering + import organization) -
bun.lockis committed,package-lock.jsonis deleted - CI workflows reference Bun and Biome (check-only mode)
References
- Composer scripts — Standard scripts to merge into composer.json
- Biome config — Canonical Biome configuration (CSS quote style single; composer.json excluded from formatting — composer.json keeps its conventional key order)
- CI: Lint workflow — Check-only Pint + Biome in CI (fails on drift)
- CI: Tests workflow — Multi-PHP-version matrix with Bun build
- Pre-commit hook —
.husky/pre-commitcontents (barelint-staged— portable across npm and Bun) - package.json snippets — Scripts, lint-staged config, and devDependencies to merge
Notes
- If a project already exists in production with legacy tooling (npm, ESLint, Prettier, or an always-green lint CI), use the formatting-enforcement skill — it covers the retrofit runbook (chore-branch cleanup of accumulated drift + gate + hooks) that this bootstrap flow assumes is done at creation time.
- The pre-commit hook intentionally uses the bare
lint-stagedcommand (nonpx/bunxprefix) — the husky runner putsnode_modules/.binon PATH, so the same hook file works under both npm and Bun. - Hooks are per-worktree: each clone/worktree needs one
bun install(ornpm install) forcore.hooksPathto be set. CI is the enforcement backstop for anyone who skips installs.