Biome: استبدال ESLint و Prettier بأداة واحدة فائقة السرعة

خط أنابيب ESLint + Prettier يستغرق 45 ثانية؟ Biome ينجز نفس المهمة في أقل من ثانيتين. Biome هو أداة تنسيق وفحص شاملة مكتوبة بلغة Rust تستبدل ESLint و Prettier وعشرات الإضافات المرتبطة بهما. في هذا الدليل، ستنقل مشروع Next.js كاملاً إلى Biome وستكتشف لماذا آلاف المشاريع قامت بالتحول في 2026.
ما ستتعلمه
بنهاية هذا الدليل، ستكون قادراً على:
- فهم ما يفعله Biome ولماذا يستبدل ESLint + Prettier
- تثبيت وإعداد Biome في مشروع JavaScript/TypeScript موجود
- الترحيل التلقائي لقواعد ESLint و Prettier إلى Biome
- إعداد قواعد فحص مخصصة حسب الملف والمجلد
- دمج Biome في VS Code مع التنسيق التلقائي
- إضافة Biome إلى خط أنابيب CI/CD (GitHub Actions و GitLab CI)
- استخدام تنظيم الاستيرادات والترتيب التلقائي
- إعداد Biome لـ monorepo مع قواعد مشتركة
المتطلبات الأساسية
قبل البدء، تأكد من توفر:
- Node.js 18+ مثبّت (
node --version) - مشروع JavaScript أو TypeScript موجود (يفضل مع ESLint/Prettier)
- معرفة بـ سطر الأوامر
- VS Code أو محرر يدعم LSP
- معرفة أساسية بـ ملفات الإعداد (JSON)
لماذا Biome؟
في 2026، أغلب مشاريع JavaScript تستخدم ESLint للفحص و Prettier للتنسيق. هذه التركيبة تعمل، لكن لها مشاكل حقيقية:
- البطء: ESLint يحلل كل ملف بـ JavaScript، وهذا بطيء بطبيعته في المشاريع الكبيرة
- تعقيد الإعداد: بين
.eslintrcو.prettierrcوeslint-config-*والإضافات والمحللات وتعارضات ESLint/Prettier، يصبح الإعداد صداعاً - التعارضات: ESLint و Prettier قد يتناقضان — تحتاج
eslint-config-prettierلتعطيل القواعد المتعارضة - الصيانة: كل أداة لها دورة تحديثاتها وتغييراتها الجذرية وإضافاتها
Biome يحل كل هذا بنهج مختلف:
| الجانب | ESLint + Prettier | Biome |
|---|---|---|
| اللغة | JavaScript (بطيء) | Rust (سريع) |
| الأدوات | أداتان + إضافات | أداة واحدة |
| الإعداد | 2-4 ملفات | ملف واحد biome.json |
| السرعة | ~45 ثانية لـ 1000 ملف | ~1.5 ثانية لـ 1000 ملف |
| التعارضات | متكررة | مستحيلة |
الخطوة 1: تثبيت Biome
لننشئ مشروعاً جديداً للتوضيح، أو استخدم مشروعك الموجود:
# إنشاء مشروع Next.js للاختبار
npx create-next-app@latest biome-demo --typescript --tailwind --app --src-dir
cd biome-demoثبّت Biome كاعتماد تطوير:
npm install --save-dev --save-exact @biomejs/biomeالإصدار المحدد موصى به (--save-exact) لأن Biome يتبع الإصدار الدلالي والتحديثات الفرعية قد تضيف قواعد جديدة تولّد أخطاء في CI الخاص بك.
أعدّ ملف الإعداد:
npx @biomejs/biome initهذا ينشئ ملف biome.json في جذر المشروع:
{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"ignore": []
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
}
}الخطوة 2: إعداد المنسّق
Biome يستخدم التبويب افتراضياً، لكن معظم مشاريع JavaScript تستخدم مسافتين. لنعدّ المنسّق ليتوافق مع الأعراف الشائعة:
{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"semicolons": "always",
"trailingCommas": "all",
"arrowParentheses": "always",
"bracketSpacing": true,
"jsxQuoteStyle": "double"
}
}
}المقارنة مع Prettier
إذا كنت قادماً من Prettier، إليك تطابق الخيارات:
| Prettier | Biome | القيمة الافتراضية |
|---|---|---|
tabWidth | indentWidth | 2 |
useTabs | indentStyle: "tab" | "space" |
printWidth | lineWidth | 80 |
singleQuote | quoteStyle: "single" | "double" |
semi | semicolons | "always" |
trailingComma | trailingCommas | "all" |
endOfLine | lineEnding | "lf" |
اختبر المنسّق على مشروعك:
# التنسيق مع كتابة التغييرات
npx @biomejs/biome format --write .
# الفحص دون تعديل
npx @biomejs/biome format .الخطوة 3: إعداد الفاحص
فاحص Biome يتضمن أكثر من 300 قاعدة، تغطي معظم القواعد الشائعة من eslint و typescript-eslint و eslint-plugin-react و eslint-plugin-react-hooks و eslint-plugin-jsx-a11y.
القواعد الموصى بها
افتراضياً، "recommended": true يفعّل مجموعة من القواعد الآمنة والمتفق عليها:
{
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
}
}تخصيص القواعد
يمكنك تعديل كل قاعدة على حدة:
{
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "warn",
"options": {
"maxAllowedComplexity": 20
}
}
},
"style": {
"noNonNullAssertion": "warn",
"useConst": "error",
"useImportType": "error",
"noParameterAssign": "error"
},
"suspicious": {
"noExplicitAny": "warn",
"noConsoleLog": "warn"
},
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error",
"useExhaustiveDependencies": "warn"
},
"nursery": {
"useSortedClasses": {
"level": "warn",
"options": {
"attributes": ["className"],
"functions": ["clsx", "cn", "cva"]
}
}
}
}
}
}القواعد في فئة nursery تجريبية وقد تتغير بين الإصدارات الفرعية. استخدمها في وضع warn بدلاً من error في CI الخاص بك.
فئات القواعد
Biome ينظم قواعده في فئات واضحة:
| الفئة | الوصف | أمثلة |
|---|---|---|
correctness | أخطاء محتملة | noUnusedVariables, useExhaustiveDependencies |
suspicious | كود مشبوه | noExplicitAny, noConsoleLog |
style | أعراف الكود | useConst, useImportType |
complexity | كود معقد جداً | noExcessiveCognitiveComplexity |
performance | تحسينات | noAccumulatingSpread, noDelete |
security | ثغرات أمنية | noDangerouslySetInnerHtml |
a11y | إمكانية الوصول | useAltText, useAriaProps |
nursery | تجريبية | useSortedClasses |
شغّل الفاحص:
# الفحص فقط
npx @biomejs/biome lint .
# الفحص مع الإصلاح التلقائي
npx @biomejs/biome lint --write .
# فحص + تنسيق + استيرادات في أمر واحد
npx @biomejs/biome check --write .الخطوة 4: الترحيل من ESLint و Prettier
إذا كان لديك مشروع موجود مع ESLint و Prettier، يوفر Biome أداة ترحيل تلقائية.
الترحيل التلقائي
# ترحيل إعداد ESLint إلى Biome
npx @biomejs/biome migrate eslint --write
# ترحيل إعداد Prettier إلى Biome
npx @biomejs/biome migrate prettier --writeهذا يقرأ ملفات .eslintrc.* و .prettierrc.*، ثم يحدّث biome.json بالقواعد المكافئة.
مثال عملي
لنفترض هذا الإعداد لـ ESLint:
// .eslintrc.json (قبل)
{
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
"prettier"
],
"rules": {
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-explicit-any": "warn",
"react-hooks/exhaustive-deps": "warn",
"no-console": "warn"
}
}بعد الترحيل، ينتج Biome:
// biome.json (بعد الترحيل)
{
"linter": {
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error",
"useExhaustiveDependencies": "warn"
},
"suspicious": {
"noExplicitAny": "warn",
"noConsoleLog": "warn"
}
}
}
}تنظيف الملفات القديمة
بمجرد التحقق من الترحيل، احذف الملفات القديمة:
# حذف ملفات ESLint
rm -f .eslintrc .eslintrc.js .eslintrc.json .eslintrc.yml .eslintignore
# حذف ملفات Prettier
rm -f .prettierrc .prettierrc.js .prettierrc.json .prettierrc.yml .prettierignore
# إلغاء تثبيت الاعتمادات
npm uninstall eslint prettier eslint-config-prettier \
eslint-plugin-react eslint-plugin-react-hooks \
@typescript-eslint/eslint-plugin @typescript-eslint/parser \
eslint-config-nextتحديث سكربتات npm
{
"scripts": {
"lint": "biome check .",
"lint:fix": "biome check --write .",
"format": "biome format --write ."
}
}الخطوة 5: تنظيم الاستيرادات
Biome يرتب استيراداتك تلقائياً وفق أعراف واضحة. فعّل هذه الميزة:
{
"organizeImports": {
"enabled": true
}
}قبل / بعد
// قبل — استيرادات غير مرتبة
import { useState, useEffect } from "react";
import axios from "axios";
import styles from "./page.module.css";
import { Button } from "@/components/ui/button";
import type { User } from "@/types";
import { z } from "zod";
import Link from "next/link";// بعد — مرتبة تلقائياً
import { useEffect, useState } from "react";
import Link from "next/link";
import axios from "axios";
import { z } from "zod";
import type { User } from "@/types";
import { Button } from "@/components/ui/button";
import styles from "./page.module.css";Biome يجمع الاستيرادات بهذا الترتيب:
- وحدات Node.js الأصلية (
node:fs,node:path) - الحزم الخارجية (
react,next,zod) - الاستيرادات الداخلية (الاسم المستعار
@/، المسارات النسبية) - استيرادات الأنواع (
type { ... })
أمر biome check --write يطبق الترتيب مع الفحص والتنسيق.
الخطوة 6: تكامل VS Code
تثبيت الإضافة
ابحث عن "Biome" في سوق VS Code أو ثبّتها من الطرفية:
code --install-extension biomejs.biomeإعداد VS Code
أضف هذه الإعدادات في .vscode/settings.json:
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit",
"quickfix.biome": "explicit"
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[javascriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[jsonc]": {
"editor.defaultFormatter": "biomejs.biome"
}
}عطّل إضافتي ESLint و Prettier لتجنب التعارضات. Biome يستبدل كليهما.
ميزات المحرر
مع إضافة Biome، تحصل على:
- التنسيق عند الحفظ: الكود يُنسَّق تلقائياً عند كل حفظ
- تشخيصات فورية: أخطاء الفحص تظهر مباشرة في المحرر
- إصلاحات سريعة:
Ctrl+.يقترح تصحيحات تلقائية - ترتيب الاستيرادات: الاستيرادات تُعاد تنظيمها عند الحفظ
- إعادة الهيكلة: إعادة التسمية، الاستخراج، وإجراءات الكود الأخرى
الخطوة 7: تكامل CI/CD
GitHub Actions
أنشئ .github/workflows/lint.yml:
name: Lint & Format
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
biome:
name: Biome Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
version: latest
- name: Run Biome
run: biome ci .أمر biome ci مُحسَّن لخطوط أنابيب CI: لا يكتب ملفات، ينتج تقرير تشخيصات، ويعيد رمز خطأ غير صفري إذا وُجدت مشاكل.
GitLab CI
أضف في .gitlab-ci.yml:
biome:
stage: validate
image: node:20-slim
before_script:
- npm ci
script:
- npx @biomejs/biome ci .
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"خطاف Pre-commit مع Husky
# تثبيت Husky
npm install --save-dev husky
npx husky init
# إضافة خطاف pre-commit
echo "npx @biomejs/biome check --staged --no-errors-on-unmatched" > .husky/pre-commitعلم --staged يفحص فقط الملفات في منطقة التجهيز، مما يجعل الخطاف شبه فوري.
الخطوة 8: إعداد متقدم
تجاوزات حسب المجلد
Biome يسمح بإعدادات مختلفة حسب المجلدات أو أنماط الملفات:
{
"overrides": [
{
"include": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
}
}
}
},
{
"include": ["scripts/**"],
"linter": {
"rules": {
"suspicious": {
"noConsoleLog": "off"
}
}
}
},
{
"include": ["**/*.config.ts", "**/*.config.js"],
"formatter": {
"lineWidth": 120
}
}
]
}تجاهل الملفات
{
"files": {
"ignore": [
"node_modules",
".next",
"dist",
"build",
"coverage",
"*.min.js",
"generated/**"
]
},
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
}
}مع "useIgnoreFile": true، يحترم Biome تلقائياً ملف .gitignore.
إعداد Monorepo
لـ monorepo، ضع biome.json في الجذر واستخدم extends في الحزم:
my-monorepo/
├── biome.json # الإعداد الأساسي
├── packages/
│ ├── web/
│ │ └── biome.json # يمتد من إعداد الجذر
│ ├── api/
│ │ └── biome.json # يمتد من إعداد الجذر
│ └── shared/
│ └── biome.json # يمتد من إعداد الجذر
// packages/web/biome.json
{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"extends": ["../../biome.json"],
"linter": {
"rules": {
"a11y": {
"recommended": true
}
}
}
}الخطوة 9: إعداد كامل لـ Next.js
إليك إعداد biome.json كامل وجاهز للإنتاج مع Next.js:
{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": true,
"ignore": [
".next/**",
"node_modules/**",
"public/**",
".contentlayer/**"
]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
},
"organizeImports": {
"enabled": true
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"semicolons": "always",
"trailingCommas": "all",
"arrowParentheses": "always",
"bracketSpacing": true
}
},
"json": {
"formatter": {
"trailingCommas": "none"
}
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error",
"useExhaustiveDependencies": "warn"
},
"style": {
"useConst": "error",
"useImportType": "error",
"noNonNullAssertion": "warn"
},
"suspicious": {
"noExplicitAny": "warn",
"noConsoleLog": "warn"
},
"nursery": {
"useSortedClasses": {
"level": "warn",
"options": {
"attributes": ["className"],
"functions": ["clsx", "cn", "cva"]
}
}
}
}
},
"overrides": [
{
"include": ["**/*.test.ts", "**/*.test.tsx"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off",
"noConsoleLog": "off"
}
}
}
}
]
}الخطوة 10: قياس الأداء — ESLint + Prettier مقابل Biome
لنقس فرق الأداء على مشروع حقيقي. أنشئ سكربت قياس أداء:
#!/bin/bash
# benchmark.sh
echo "=== قياس الأداء: 500 ملف TypeScript ==="
echo ""
# إنشاء ملفات اختبار
mkdir -p bench-files
for i in $(seq 1 500); do
cat > "bench-files/file-$i.tsx" << 'CONTENT'
import { useState, useEffect, useCallback } from "react";
import Link from "next/link";
import { z } from "zod";
const schema = z.object({
name: z.string().min(1),
email: z.string().email(),
age: z.number().min(0).max(150),
});
type FormData = z.infer<typeof schema>;
export function UserForm({ onSubmit }: { onSubmit: (data: FormData) => void }) {
const [data, setData] = useState<FormData>({ name: "", email: "", age: 0 });
const [errors, setErrors] = useState<string[]>([]);
const validate = useCallback(() => {
const result = schema.safeParse(data);
if (!result.success) {
setErrors(result.error.errors.map((e) => e.message));
return false;
}
setErrors([]);
return true;
}, [data]);
useEffect(() => {
validate();
}, [validate]);
return (
<form
onSubmit={(e) => {
e.preventDefault();
if (validate()) onSubmit(data);
}}
>
<input
type="text"
value={data.name}
onChange={(e) => setData({ ...data, name: e.target.value })}
/>
<input
type="email"
value={data.email}
onChange={(e) => setData({ ...data, email: e.target.value })}
/>
<Link href="/users">رجوع</Link>
{errors.map((err) => (
<p key={err}>{err}</p>
))}
</form>
);
}
CONTENT
done
echo "--- ESLint + Prettier ---"
time npx eslint bench-files/ 2>/dev/null
time npx prettier --check bench-files/ 2>/dev/null
echo ""
echo "--- Biome ---"
time npx @biomejs/biome check bench-files/
# تنظيف
rm -rf bench-filesالنتائج النموذجية
| الأداة | 500 ملف | 1000 ملف | 5000 ملف |
|---|---|---|---|
| ESLint | ~8 ثوانٍ | ~18 ثانية | ~95 ثانية |
| Prettier | ~3 ثوانٍ | ~7 ثوانٍ | ~35 ثانية |
| ESLint + Prettier | ~11 ثانية | ~25 ثانية | ~130 ثانية |
| Biome | ~0.4 ثانية | ~0.8 ثانية | ~3.5 ثانية |
Biome أسرع بحوالي 25 إلى 35 مرة بفضل بنيته المكتوبة بـ Rust والتحليل المتوازي.
استكشاف الأخطاء
المشاكل الشائعة
التنسيق يختلف عن Prettier
Biome يستهدف التوافق مع Prettier لكن بعض الحالات الحدية تختلف. إذا أعاقك اختلاف محدد:
{
"formatter": {
"attributePosition": "multiline"
}
}تعارض مع إضافة Prettier في VS Code
عطّل إضافة Prettier أو اقصرها على اللغات غير المدعومة من Biome:
{
"prettier.disableLanguages": [
"javascript",
"typescript",
"javascriptreact",
"typescriptreact",
"json"
]
}قواعد ESLint المخصصة لم تُرحَّل
بعض القواعد الخاصة بإضافات ESLint من أطراف ثالثة ليست مدعومة بعد من Biome. راجع مصفوفة التوافق على الموقع الرسمي للتحقق من دعم قواعدك.
خطأ "file too large"
افتراضياً، Biome يتجاهل الملفات الأكبر من 1 ميجابايت. عدّل إذا لزم الأمر:
{
"files": {
"maxSize": 2097152
}
}الخطوات التالية
الآن بعد إعداد Biome في مشروعك:
- استكشف قواعد nursery: قواعد جديدة تُضاف مع كل إصدار، مثل
useSortedClassesلترتيب فئات Tailwind - أعدّ خطافات Git ليتم فحص كل commit تلقائياً
- أضف دعم CSS: Biome يدعم الآن فحص وتنسيق CSS/SCSS (تجريبي)
- جرّب
biome search: بحث هيكلي في الكود بأنماط GritQL - ساهم: Biome مفتوح المصدر ويرحب بالمساهمات على GitHub
الخلاصة
Biome يمثل تحولاً جذرياً في أدوات JavaScript. باستبدال ESLint و Prettier بأداة واحدة مكتوبة بـ Rust، تحصل على:
- سرعة أعلى بـ 25 إلى 35 مرة في الفحص والتنسيق
- إعداد مبسّط بملف
biome.jsonواحد - صفر تعارضات بين الفاحص والمنسّق
- تشخيصات أوضح مع اقتراحات إصلاح مدمجة
- نظام بيئي موحّد يتوسع ليشمل CSS و GraphQL وقريباً HTML
الترحيل من ESLint + Prettier تدريجي ومدعوم بأدوات ترحيل تلقائية. في 2026، أصبح Biome الخيار الافتراضي للمشاريع الجديدة وترقية موصى بها للمشاريع الموجودة.
ناقش مشروعك معنا
نحن هنا للمساعدة في احتياجات تطوير الويب الخاصة بك. حدد موعدًا لمناقشة مشروعك وكيف يمكننا مساعدتك.
دعنا نجد أفضل الحلول لاحتياجاتك.
مقالات ذات صلة

بناء وكيل ذكاء اصطناعي مستقل باستخدام Agentic RAG و Next.js
تعلم كيف تبني وكيل ذكاء اصطناعي يقرر بشكل مستقل متى وكيف يسترجع المعلومات من قواعد البيانات المتجهية. دليل عملي شامل باستخدام Vercel AI SDK و Next.js مع أمثلة قابلة للتنفيذ.

بناء وكلاء الذكاء الاصطناعي من الصفر باستخدام TypeScript: إتقان نمط ReAct مع Vercel AI SDK
تعلّم كيفية بناء وكلاء الذكاء الاصطناعي من الأساس باستخدام TypeScript. يغطي هذا الدليل التعليمي نمط ReAct، واستدعاء الأدوات، والاستدلال متعدد الخطوات، وحلقات الوكلاء الجاهزة للإنتاج مع Vercel AI SDK.

Better Auth مع Next.js 15: الدليل الشامل للمصادقة في 2026
تعلم كيفية تنفيذ نظام مصادقة متكامل في Next.js 15 باستخدام Better Auth. يغطي هذا الدليل تسجيل الدخول بالبريد الإلكتروني وOAuth والجلسات وحماية المسارات والتحكم بالأدوار.