Upgrade Biome dari 2.3 ke 2.6 bisa gagal dengan dua cara. Config tidak mau dibaca karena dua key sudah dihapus, atau biome check tiba-tiba melaporkan banyak error baru di kode yang kemarin masih lolos. Berikut apa saja yang rusak saat upgrade Biome 2.6 di codebase Next.js 16 + Tailwind 4 + Playwright + Vitest yang nyata (codebase blog ini), dari 2.3.8 ke 2.6.6, dan cara memperbaiki masing-masing.
Jawaban cepat
Jalankan migrasi dulu, baru check:
pnpm add -D -E @biomejs/biome@2.6.6
pnpm biome migrate --write
pnpm biome check .
biome migrate menangani sebagian besar perubahan config. Dia mengganti nama useSortedClasses, memindahkan option-nya ke blok tailwind yang baru, dan mengganti "recommended": true jadi "preset": "recommended". Dia tidak menghapus javascript.parser.gritMetavariables, jadi hapus key itu manual kalau kamu punya.
Error lint yang baru kebanyakan bisa diperbaiki otomatis dengan aman:
pnpm biome check --write .
Error config yang muncul duluan
Kalau biome.json kamu masih memakai rule sorting Tailwind yang lama atau flag parser GritQL, Biome 2.6 langsung menolak jalan:
biome.json:8:9 deserialize
× Found an unknown key `useSortedClasses`.
> 8 │ "useSortedClasses": {
biome.json:20:7 deserialize
× Found an unknown key `gritMetavariables`.
> 20 │ "gritMetavariables": true
configuration
× Biome exited because the configuration resulted in errors. Please fix them.
Dua key itu sudah tidak ada di 2.6. Rule nursery useSortedClasses sekarang bernama useTailwindSortedClasses, dan option-nya pindah dari rule ke section tailwind di level atas. gritMetavariables dihapus tanpa pengganti.
Perbaiki useSortedClasses
Sebelum (jalan di 2.3):
{
"linter": {
"rules": {
"nursery": {
"useSortedClasses": {
"level": "warn",
"options": {
"attributes": ["className", "classList"],
"functions": ["clsx", "cn"]
}
}
}
}
}
}
Sesudah (2.6):
{
"linter": {
"rules": {
"nursery": {
"useTailwindSortedClasses": "warn"
}
}
},
"tailwind": {
"attributes": ["class", "className", "classList"],
"mergeFunctions": ["clsx", "cn"],
"variantFunctions": ["cva"]
}
}
Option functions yang lama sekarang jadi mergeFunctions. useTailwindSortedClasses sendiri tidak menerima option lagi. Kalau tailwind.attributes tidak diisi, default-nya class dan className. Daftar default mergeFunctions sudah berisi clsx, cn, tw, twMerge, dan twJoin, jadi baris itu mungkin tidak perlu sama sekali.
biome migrate --write menghasilkan config ini untuk kamu, dan sekalian menambahkan "class" ke attributes.
Urutan class di project Tailwind v4 hasilnya sama dengan 2.3:
-<div className="p-4 flex text-sm bg-white mt-2 rounded-lg">
+<div className="mt-2 flex rounded-lg bg-white p-4 text-sm">
Fix itu ditandai unsafe, jadi baru diterapkan dengan biome lint --write --unsafe.
Perbaiki gritMetavariables
Hapus saja:
"javascript": {
- "parser": { "gritMetavariables": true }
}
biome migrate bilang "configuration successfully migrated" tapi key ini tetap ditinggal. Jalankan sekali lagi dan dia bilang "no migration needed", padahal biome check masih gagal dengan unknown key yang sama.
Deprecation recommended
Yang ini belum merusak apa-apa. Sejak 2.5, Biome menampilkan baris info untuk "recommended": true:
The use of the recommended field has been deprecated, and will removed in the next major version of Biome. Use preset instead.
Ganti dengan:
"rules": { "preset": "recommended" }
Di repo blog ini, itu satu-satunya perubahan config yang dibuat migrate, selain menaikkan $schema.
Error lint baru setelah upgrade
Setelah config beres, biome check . di 387 file naik dari 94 error dan 153 warning di 2.3.8 jadi 136 error dan 155 warning di 2.6.6. Dengan meng-install tiap versi di antaranya, kelihatan asal error-nya, dan tidak ada satu pun yang datang dari 2.6:
assist/source/organizeImports, 38 error baru, mulai 2.4.7. Biome sekarang juga mengurutkan nama di dalam listexport { ... }, bukan cuma import. Hampir semua file komponen shadcn/ui diakhiri list seperti itu, jadi hampir semuanya muncul.lint/suspicious/noArrayIndexKey, 4 error baru, mulai 2.4.5. Rule ini sekarang menangkap index di dalam key template literal sepertikey={`${item.url}-${i}`}.lint/complexity/useOptionalChain, 2 warning baru, mulai 2.4.9. Sekarang dia menandai!post || !post.title.
Diagnostic organizeImports bentuknya seperti ini:
src/components/ui/card.tsx:84:1 assist/source/organizeImports FIXABLE
× Sort the exported names.
> 84 │ export {
> 85 │ Card,
Ini safe fix, jadi biome check --write . membereskan ke-38 error itu. Yang noArrayIndexKey butuh key yang benar. Pakai id atau url item tanpa index, kalau itu sudah unik.
Kalau kamu datang dari 2.3, sebagian besar error baru akan berasal dari patch 2.4.
Rule yang dipromosikan 2.6 dari nursery
Biome 2.6 memindahkan 59 rule dari nursery ke grup stabil. Sebagian termasuk recommended, jadi langsung aktif begitu kamu upgrade, selama dependency yang cocok ada di package.json (@playwright/test, react, vitest, atau jest). Biome menyalakan rule per domain berdasarkan dependency itu.
Tidak ada yang muncul di kode blog ini, tapi rule-nya aktif. File percobaan dengan await yang hilang langsung gagal:
e2e/probe.spec.ts:6:5 lint/correctness/noPlaywrightMissingAwait FIXABLE
× Async matcher toBeVisible must be awaited or returned.
> 6 │ expect(page.getByRole('heading')).toBeVisible();
i Unsafe fix: Add await before the call.
Rule hasil promosi ini dilaporkan sebagai error:
correctness/noPlaywrightMissingAwait: async matcher sepertitoBeVisible()yang tidak di-awaitcorrectness/usePlaywrightValidDescribeCallback:test.describe(async () => ...)correctness/noComponentHookFactories: komponen yang didefinisikan di dalam function laincorrectness/noJsxNamespace: JSX gaya<svg:rect>correctness/useReactAsyncServerFunction: export non-async di file"use server"
Yang ini dilaporkan sebagai warning:
suspicious/noReactStringRefs:ref="input"suspicious/noIdenticalTestTitle: dua test dengan judul sama di satu scope
await yang hilang di matcher Playwright artinya assertion-nya tidak pernah dicek, jadi test bisa lolos walaupun halamannya rusak. Karena itu noPlaywrightMissingAwait sebaiknya jangan di-off.
biome explain <rule> menampilkan versi saat rule pertama kali muncul di nursery (2.4.2 untuk noPlaywrightMissingAwait), bukan 2.6. Jangan pakai itu untuk mencari tahu apakah 2.6 mengubah sesuatu.
Matikan rule hasil promosi
Set ke off di grup barunya, bukan di nursery:
"linter": {
"rules": {
"preset": "recommended",
"suspicious": { "noIdenticalTestTitle": "off" }
}
}
Kalau di 2.3 kamu sudah menyalakan salah satu rule ini di nursery, itu juga error Found an unknown key. biome migrate memindahkannya ke grup yang benar dan meninggalkan "nursery": {} kosong.
Untuk mematikan satu domain sekaligus:
"linter": { "domains": { "playwright": "none" } }
Untuk melewati satu rule di satu kali run, misalnya sambil membereskan sisa error:
pnpm biome check --skip=correctness/usePlaywrightValidDescribeCallback .
Sorting Tailwind masih harus dinyalakan sendiri
Release notes 2.6 bilang domain Tailwind otomatis aktif untuk tailwindcss v4+. Kenyataannya tidak ada yang berubah. Semua rule Tailwind masih di nursery, dan domain tidak pernah menyalakan rule nursery. Dengan Tailwind 4.1, preset recommended, bahkan "domains": { "tailwind": "all" }, Biome melaporkan nol diagnostic Tailwind.
Kalau mau class sorting, nyalakan useTailwindSortedClasses sendiri seperti config di atas. Rule ini juga jalan di Tailwind 3. Severity default-nya info, jadi set "warn" atau "error" kalau mau CI ikut menangkap.
Cek hasilnya
pnpm biome --version
pnpm biome check .
Harusnya muncul Version: 2.6.6 dan tidak ada error deserialize di awal output. Kalau check masih exit 1, lihat nama rule-nya. organizeImports dan format aman di---write. Yang ada di correctness sebaiknya dibaca dulu.
Kesimpulan
Untuk upgrade Biome 2.6 dari 2.3, jalankan biome migrate --write, hapus gritMetavariables manual, lalu biome check --write . untuk membereskan error sorting export dari 2.4. Rule Playwright dan React hasil promosi cuma muncul di kesalahan beneran, jadi baca dulu sebelum dimatikan.