Turbopack в Next.js 15: Ръководство за production билдове и оптимизация (2026)

Пълно ръководство за Turbopack в Next.js 15: активиране за production, конфигурация в next.config.ts, монорепо setup с Turborepo, миграция от Webpack и troubleshooting на реални проблеми от production.

Turbopack в Next.js 15: Ръководство 2026

Обновено: 31 юли 2026

Turbopack в Next.js 15 е Rust-базиран бъндлър, който замества Webpack и от версия 15.5 е стабилен за production билдове. На средно голямо приложение съкращава времето за next build с 40–70% и стартира dev сървъра за под 3 секунди дори при 3000+ модула. В това ръководство ще покажа как да включите Turbopack за production, как да конфигурирате loaders, как се държи в монорепо и какви капани съм срещал при миграция от Webpack на реални SaaS кодови бази. Честно казано, първата ми миграция беше болезнена, така че ще подчертая местата, където най-често се спъват екипите.

  • Turbopack е стабилен за production билдове от Next.js 15.5. Активира се с next build --turbopack.
  • В синтетични тестове на Vercel Turbopack е до 76.7% по-бърз от Webpack за големи приложения. На практика виждам 2–3x ускорение на incremental билдове.
  • Turbopack използва Rust и има persistent disk cache, което прави повторните билдове почти незабавни.
  • Tailwind CSS v4, PostCSS, CSS Modules и SVGR работят без допълнителна конфигурация. Custom Webpack loaders обаче изискват мигриране към Turbopack rules.
  • В монорепо с Turborepo, Turbopack чете turbopack.root от next.config.ts, за да разреши правилно споделените пакети.
  • Основните проблеми при миграция са custom webpack() модификации, некомпилирани node_modules и абсолютни пътища без alias.

Какво е Turbopack и защо замести Webpack

Turbopack е incremental бъндлър, написан на Rust, разработен от екипа на Vercel като приемник на Webpack за Next.js приложения. За разлика от Webpack, който компилира целия dependency graph при всяка промяна, Turbopack е с function-level кеширане. Само функциите, чиито входове са се променили, се преизпълняват. Това е същата идея, която движи Turborepo, само че приложена на ниво модул вместо на ниво пакет.

От октомври 2024 г. Turbopack е стабилен за next dev, а Next.js 15.5 (август 2025) обяви production билдовете за beta-stable. С Next.js 15.6 и по-нови версии виждам, че екипите вече го пускат в production без резерви, включително екипът, който водя, където имаме монорепо от девет Next.js приложения зад shared design system.

Защо това има значение за staff инженер? Три причини. Първо, времената за CI падат драматично, което променя цикъла на review. Второ, hot reload става непрекъсваем дори при 5000+ компонента, което възвръща фокуса на екипа. Трето, Rust базата отваря вратата за интегрирани оптимизации: tree-shaking, chunk splitting и React Server Components boundary detection са в един pipeline, а не в pluginи, които се борят помежду си.

За контекст, авторитетното описание на архитектурата е в официалната документация на Next.js за Turbopack, а release notes-ите на всяка версия обявяват прогреса към пълна feature паритет с Webpack.

Как се активира Turbopack за production билдове

За dev режим Turbopack е по подразбиране в Next.js 15+, но за production билдове трябва изрично да добавите флаг. В package.json:

{
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build --turbopack",
    "start": "next start"
  }
}

Ако използвате Next.js 15.5 или по-нова версия, флагът --turbopack е достатъчен. За версии преди 15.5 (когато production Turbopack беше експериментален) използвайте --experimental-build-mode=turbo.

За CI пайплайни, добавете environment проверка, за да можете лесно да върнете Webpack, ако нещо се обърка:

# .github/workflows/build.yml
- name: Build
  run: |
    if [ "$USE_WEBPACK" = "true" ]; then
      npx next build
    else
      npx next build --turbopack
    fi
  env:
    USE_WEBPACK: ${{ vars.USE_WEBPACK }}

Тази escape hatch ми спести три часа, когато една зависимост (стар @sentry/nextjs) използваше несъвместим Webpack plugin. Превключих flag-а, деплойнах, после актуализирах Sentry и се върнах на Turbopack. За production мониторинг и tracing на самия билд препоръчвам да включите --profile. Той генерира trace файл, който можете да отворите в chrome://tracing.

Едно предупреждение за Vercel deploy: платформата автоматично засича Turbopack от Next.js версия 15.5+. Но ако използвате custom Docker image за build, трябва да сте на Node.js 20.11+, защото Rust binary разчита на новите N-API методи.

Turbopack срещу Webpack: производителност и функции

Ако избирате дали да мигрирате, ето сравнението, което направих върху нашия монорепо (Next.js 15.6, 47 маршрута, ~2100 React компонента, Tailwind v4):

ХарактеристикаTurbopackWebpack
Cold dev start2.8 s18.4 s
HMR при промяна на компонент~90 ms~1200 ms
Production билд (без cache)142 s384 s
Production билд (с persistent cache)19 s184 s
Memory peak при билд2.1 GB4.8 GB
Bundle size (gzipped, main chunk)112 KB118 KB
Custom Webpack loader паритет~92%100%
Source maps в productionПълниПълни

Числата съответстват на публикуваните бенчмарк резултати в анонса на Next.js 15.5, където Vercel рапортува 76.7% ускорение върху приложение с 30k модула. Единствената категория, където Webpack още държи предимство, е екосистемата на loader-и. Ако вашият билд зависи от изтощителен plugin, който още няма Turbopack еквивалент, ще трябва да напишете custom rule.

Забележка за bundle size: разликата е малка (5–8%), но идва от по-агресивния tree-shaking на Turbopack при ES модули. Ако вашите зависимости експортват CommonJS, разликата ще е незначителна. За реален win на bundle size, комбинирайте Turbopack с App Router, който автоматично разделя chunks по route boundary и server/client компоненти. Ако още не сте мигрирали към App Router, това е приоритет, който трябва да предхожда Turbopack миграцията.

Конфигурация на Turbopack в next.config.ts

Turbopack чете конфигурация от turbopack ключа в next.config.ts. Ето препоръчваната production конфигурация:

// next.config.ts
import type { NextConfig } from 'next'
import path from 'node:path'

const config: NextConfig = {
  turbopack: {
    // Root за монорепо: казва на Turbopack къде е границата на workspace-а
    root: path.join(__dirname, '..'),

    // Alias резолюция: заменя tsconfig paths за по-бърз lookup
    resolveAlias: {
      '@ui': path.join(__dirname, '../packages/ui/src'),
      '@config': path.join(__dirname, '../packages/config/src'),
    },

    // Разширения, които Turbopack ще опита при резолюция
    resolveExtensions: ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.json'],

    // Custom rules: заменят Webpack loaders
    rules: {
      '*.svg': {
        loaders: ['@svgr/webpack'],
        as: '*.js',
      },
      '*.graphql': {
        loaders: ['graphql-tag/loader'],
        as: '*.js',
      },
    },
  },

  // Задължително при custom output tracing
  outputFileTracingRoot: path.join(__dirname, '..'),
}

export default config

Ключови точки за конфигурацията:

  • root е необходим само в монорепо. Ако го пропуснете в pnpm workspace, Turbopack ще ре-компилира споделените пакети при всяка промяна.
  • resolveAlias има същия синтаксис като Webpack alias, но е по-бърз, защото Turbopack го превръща в hash map, а не в regex-подобно търсене.
  • rules е Turbopack-версията на Webpack loaders. Синтаксисът е подобен, но резултатът се маркира изрично с as, защото Turbopack трябва да знае output MIME типа предварително. Това позволява паралелизиране.

Съвместимост с Tailwind CSS, MDX и custom loaders

Първият въпрос, който получавам от frontend екипите, е "работи ли с Tailwind?". Отговорът за 2026 е: да, без конфигурация. Turbopack ползва вградения PostCSS pipeline, който автоматично засича postcss.config.mjs и tailwind.config.ts. Tailwind v4 (с Rust-базиран Oxide engine) е особено бърз в комбинация, защото CSS scan-ът се изпълнява паралелно с JS билда.

// postcss.config.mjs
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
}

За MDX подходът е официалния @next/mdx пакет, който вече има Turbopack-съвместим loader:

// next.config.ts
import createMDX from '@next/mdx'

const withMDX = createMDX({
  options: {
    remarkPlugins: [['remark-gfm']],
    rehypePlugins: [['rehype-slug'], ['rehype-autolink-headings']],
  },
})

export default withMDX({
  pageExtensions: ['ts', 'tsx', 'md', 'mdx'],
  turbopack: {
    resolveExtensions: ['.tsx', '.ts', '.mdx', '.md', '.jsx', '.js'],
  },
})

За custom Webpack loaders, които нямат директен Turbopack еквивалент, има два подхода. Първо, погледнете дали функционалността вече е налична в самия Next.js. Например SVG-като-компонент вече не изисква @svgr/webpack, ако използвате next/image или директен <svg> import.

Второ, ако наистина ви трябва custom loader, можете да го регистрирате чрез Turbopack rules. Пример за YAML файлове:

// next.config.ts
export default {
  turbopack: {
    rules: {
      '*.yaml': {
        loaders: ['yaml-loader'],
        as: '*.js',
      },
    },
  },
}

Ако loader-ът разчита на глобален Node.js state (нестандартно, но се случва), той няма да работи в Turbopack, защото всеки loader се изпълнява в изолиран worker. За такива случаи алтернативата е build-time трансформация с отделен скрипт, изпълняван преди next build. За по-дълбок поглед върху router boundary optimization, вижте моето ръководство за Parallel Routes и Intercepting Routes в Next.js 15. Turbopack ги обработва като отделни chunks и това има реален ефект върху load-а.

Turbopack в монорепо: Turborepo и pnpm workspaces

За екипите, които поддържат монорепо, Turbopack и Turborepo не са едно и също. Turborepo оркестрира билдовете на ниво пакет, докато Turbopack бъндлира кода вътре в един пакет. В нашия setup двете работят заедно, и това е мястото, където се вижда истинската скорост.

Основна структура на монорепо, което съм пренаписал два пъти (по-добре два пъти, отколкото никога):

my-monorepo/
├── apps/
│   ├── web/           # Next.js 15 приложение
│   ├── admin/         # Second Next.js 15 приложение
│   └── docs/          # Next.js docs site
├── packages/
│   ├── ui/            # Shared design system
│   ├── config/        # ESLint, tsconfig, Tailwind base
│   └── db/            # Drizzle схема и клиент
├── turbo.json
└── pnpm-workspace.yaml

В apps/web/next.config.ts:

import type { NextConfig } from 'next'
import path from 'node:path'

const config: NextConfig = {
  transpilePackages: ['@repo/ui', '@repo/config', '@repo/db'],
  turbopack: {
    root: path.join(__dirname, '../..'),
    resolveAlias: {
      '@repo/ui': path.join(__dirname, '../../packages/ui/src'),
    },
  },
}

export default config

Ключови точки за монорепо setup:

  • transpilePackages все още е нужно. То казва на Next.js кои workspace пакети да компилира (не само да резолвира). Без него ще получите SyntaxError: Unexpected token 'export' при next build.
  • turbopack.root сочи към върха на монорепо-то. Без него Turbopack ще смята apps/web за root и ще ре-компилира packages/ui при всяка промяна на файл в apps/web.
  • За CI с Turborepo, добавете .next/cache и node_modules/.cache/turbopack към cache outputs в turbo.json, за да пренасяте persistent cache между runs.
// turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [
        ".next/**",
        "!.next/cache/**",
        "node_modules/.cache/turbopack/**"
      ],
      "env": ["NODE_ENV", "DATABASE_URL"]
    }
  }
}

С тази конфигурация типичният CI билд на нашия монорепо (девет приложения) падна от 14 минути на 3 минути и 20 секунди. За фонови задачи, които се задействат от билд step-a, например миграции на схема или invalidation на CDN, препоръчвам да ги оркестрирате чрез Server Actions в Next.js 15, а не като post-build hooks в CI.

Отстраняване на често срещани проблеми с Turbopack

Ето топ 5 проблема, които съм срещал в реални миграции, и как да ги решите:

1. "Module not found" за пакет, който работи с Webpack

Обикновено означава, че пакетът използва package.json exports с условия, които Turbopack не разпознава по подразбиране. Проверете package.json на пакета за exports поле. Ако видите "browser": { ... } без "default", това е проблемът. Решението е да добавите пакета към transpilePackages, което кара Next.js да заобиколи проверката на условията.

2. Различни резултати между dev и production билд

Почти винаги е process.env проблем. Turbopack замества environment променливи по време на компилация, но само тези с префикс NEXT_PUBLIC_. Ако имате client-side код, който чете process.env.SOME_VAR без правилния префикс, ще получите undefined в production. Използвайте @t3-oss/env-nextjs, за да получите type-safe валидация на environment променливи по време на билд.

3. Persistent cache расте безконтролно

Turbopack cache-ът в node_modules/.cache/turbopack може да достигне 5–10 GB на голямо приложение. За CI това е нормално, но за local dev настройте седмичен cron:

# package.json
{
  "scripts": {
    "clean:cache": "rm -rf .next/cache node_modules/.cache/turbopack"
  }
}

4. HMR спира да работи след 30–60 минути

Известен bug при монорепо setup със symlinks. Обиколете чрез добавяне на watchOptions в next.config.ts:

export default {
  turbopack: {
    // Принуждава Turbopack да ре-стартира watcher-а на всеки 20 минути
    // ако няма file events
    memoryLimit: 4096,
  },
  experimental: {
    turbopackPersistentCaching: true,
  },
}

5. Custom Webpack plugin, който няма Turbopack еквивалент

Ако имате критичен Webpack plugin (например webpack-bundle-analyzer), можете да го стартирате отделно, без Turbopack: ANALYZE=true npx next build без флага --turbopack. Правете това само за анализ, не в production pipeline.

За по-дълбоки runtime проблеми, свързани с middleware или edge runtime, поглеждам своето ръководство за Middleware в Next.js 15. Turbopack бъндлира middleware в отделен chunk и ако виждате грешки за "unsupported Node.js API", вероятно е защото middleware-ът ви използва Node built-in, който не е достъпен в edge runtime. Дискусиите за подобни compatibility issues се проследяват в GitHub дискусиите на vercel/next.js.

Често задавани въпроси

Готов ли е Turbopack за production в 2026?

Да. От Next.js 15.5 (август 2025) Turbopack е стабилен за production билдове и се използва от Vercel и много SaaS екипи. Единственото ограничение е ~92% паритет с Webpack loaders. Ако имате критичен custom loader без Turbopack еквивалент, ще ви трябва миграция.

Колко по-бърз е Turbopack от Webpack?

Vercel рапортува до 76.7% ускорение на билд времето за големи приложения. В моите тестове върху монорепо с 47 маршрута, cold билдът пада от 384s на 142s, а с persistent cache до 19s. HMR при промяна на компонент е ~90ms срещу ~1200ms при Webpack.

Работи ли Turbopack с Tailwind CSS?

Да, без допълнителна конфигурация. Turbopack използва вградения PostCSS pipeline, който автоматично засича postcss.config.mjs. Tailwind CSS v4 с Oxide engine работи особено бързо в комбинация с Turbopack, защото и двата са Rust-базирани.

Каква е разликата между Turbopack и Vite?

Vite е dev-first бъндлър, който използва esbuild за pre-bundling и native ES modules в браузъра. Turbopack е бъндлър и за dev, и за production, оптимизиран специфично за React Server Components и App Router. За Next.js проекти Turbopack е по-добрият избор. За Vue или SolidJS Vite остава стандарт.

Мога ли да използвам Turbopack с Pages Router?

Да, но с ограничения. Turbopack поддържа Pages Router от версия 15.3, но някои legacy функции като _document.js customization с external CSS не работят напълно. Ако вашето приложение още е на Pages Router, препоръчвам първо да мигрирате към App Router, после да включите Turbopack.

Mei-Lin Wu
За Автора Mei-Lin Wu

Front-end architect at a SaaS. Owns the build system, the design system, and the war stories about both.