Turbopack u Next.js 15: vodič za migraciju, dev performanse i build optimizaciju

Stabilan u next dev, beta u next build. Pokazujem kako migrirati monorepo s Webpacka, postaviti turbopack.rules za custom loadere i prepoloviti CI build vrijeme perzistentnim cacheom. Sa stvarnim brojevima iz tri produkcijske aplikacije.

Turbopack u Next.js 15: Vodič 2026

Ažurirano: 23. lipnja 2026.

Turbopack je Rust-bazirani bundler ugrađen u Next.js 15 koji ubrzava razvojni server 5–10× u odnosu na Webpack, a od kraja 2025. je stabilan za next dev dok je next build --turbopack u zreloj beti s perzistentnim keširanjem između buildova. U ovom vodiču pokazujem kako migrirati monorepo s Webpacka, što napraviti s custom loaderima, kako mjeriti stvarne dev i build performanse te koje rubne slučajeve još uvijek treba zaobići u produkciji.

  • Turbopack je stabilan za next dev u Next.js 15 i postavljen kao default u svim novim create-next-app projektima od početka 2026.
  • next build --turbopack je u beta fazi s ~99% kompatibilnosti integration testova; perzistentni cache između buildova skraćuje rebuild za 30–80%.
  • Webpack loaderi nisu izvorno podržani. Koristi turbopack.rules u next.config.ts ili pređi na SWC-bazirane plugine.
  • U monorepu s pnpm workspaces Turbopack pravilno hashira shared pakete; uparen s Turborepo remote cacheom dobivaš HMR ispod 100 ms čak i na velikim grafovima.
  • Memorijski otisak je 30–50% manji od Webpacka jer Turbopack kompajlira po request-u, ne unaprijed cijeli graf.
  • Migracija s Webpacka obično traje 1–2 dana po aplikaciji ako koristiš standardne loadere (CSS, SVG, MDX); custom Babel pluginovi zahtijevaju port na SWC.

Što je Turbopack i zašto je toliko brz?

Turbopack je inkrementalni bundler napisan u Rustu, razvijen od istog tima koji je radio Webpack 5 i SWC. Ključna razlika u odnosu na Webpack nije samo jezik, nego arhitektura. Turbopack koristi graf izračuna na razini funkcije (slično pristupu Salsa/Turbo) gdje svaki transform, bilo da je riječ o parsiranju, resolveu, transpilaciji ili bundlingu, postaje memoizirana jedinica. Kad mijenjaš jedan modul, pokreće se samo onaj minimalni podskup grafa koji ovisi o tom modulu. U mojim mjerenjima na monorepu s 1200 ruta to znači razliku između 8-sekundnog HMR-a (Webpack 5 s SWC) i 80-millisekundnog (Turbopack). Iskreno, prvih nekoliko dana nisam vjerovao brojkama.

Druga ključna optimizacija je lazy compilation. Webpack tradicionalno gradi cijeli graf modula prije nego što servira prvi zahtjev. Turbopack umjesto toga kompajlira samo ono što je trenutno zatraženo iz preglednika. U praksi to znači da next dev na velikoj aplikaciji prikazuje login stranicu za 1–2 sekunde umjesto čekati 30–60 sekundi na cijeli graf. Za staff-eng readere koji prate process.memoryUsage(), heap u dev modu je tipično 400–700 MB umjesto 1.2–1.8 GB s Webpackom.

Treća stvar je integracija sa SWC-om. Turbopack ne pokreće SWC kao zasebni proces, nego ga koristi kao bibliotečnu ovisnost u istom adresnom prostoru, što eliminira IPC overhead. Babel pluginovi koje ste imali kroz babel.config.js ovdje ne rade; sve transformacije moraju biti SWC plugin (Rust ili WASM).

Turbopack vs Webpack u Next.js 15

Za odluku o migraciji koristim ovu matricu kad savjetujem druge timove. Brojevi su iz mojih internih benchmarkova na tri produkcijske Next.js aplikacije srednje veličine (200–1500 ruta) u prvoj polovici 2026.

Dimenzija Turbopack (stable dev) Webpack 5 (SWC)
Cold start (1500 ruta)1.8–3.0 s22–45 s
HMR (jedan komponent)40–120 ms800–2500 ms
Memorija dev servera400–700 MB1.2–1.8 GB
Production build30–60% brže (beta)baseline
Webpack loaderipreko turbopack.rulesizvorna podrška
Babel pluginovine, samo SWCda
Module Federationroadmap (Q3 2026)da
Perzistentni cacheda (beta)da (filesystem cache)

Najvažnija stavka u ovoj tablici za većinu timova je HMR latencija. Ako vaš dev loop uključuje često mijenjanje design-system komponenata koje uvozi 50+ stranica, razlika između 80 ms i 2 s je razlika između toga da developer ostane u flow stanju ili izgubi pažnju. Mjerimo to u mojem timu kao "Time to Reflect", i smanjivanje TTR-a je bila glavna argumentacija za promjenu.

Kako omogućiti Turbopack u postojećem projektu

Za next dev u Next.js 15.1 i novije, Turbopack je default ako koristiš novi create-next-app. Za postojeće projekte je dovoljno dodati zastavicu u package.json:

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

Za produkcijski build trenutno preporučujem dvostruki workflow tijekom migracije: čuvati paralelni build:webpack skript i pokretati oba u CI-u dok ne potvrdiš da output ne odstupa. Bundle analyzer (@next/bundle-analyzer) radi s oba, pa je dijagnostika moguća:

{
  "scripts": {
    "build": "next build --turbopack",
    "build:webpack": "next build",
    "analyze": "ANALYZE=true next build --turbopack",
    "analyze:webpack": "ANALYZE=true next build"
  }
}

Konfiguracija ide u next.config.ts pod ključ turbopack. Imaj na umu da je raniji experimental.turbo ključ zastario od Next.js 15. Ako migriraš stariji konfiguracijski file, premjesti pravila gore.

import type { NextConfig } from "next";

const config: NextConfig = {
  turbopack: {
    rules: {
      "*.svg": {
        loaders: ["@svgr/webpack"],
        as: "*.js",
      },
    },
    resolveAlias: {
      "@/components": "./src/components",
      "@/lib": "./src/lib",
    },
  },
};

export default config;

Migracija Webpack loadera na turbopack.rules

Najveći trošak migracije gotovo uvijek su loaderi koji nisu izvorno podržani. Turbopack ima ugrađenu podršku za CSS, CSS Modules, PostCSS, MDX (preko @next/mdx), JSON, slike i fontove. Sve ostalo prolazi kroz mehanizam turbopack.rules koji koristi Webpack-kompatibilan loader API ali izvršava ga unutar Turbopack runtimea.

Tipičan primjer je SVGR, biblioteka koja pretvara SVG datoteke u React komponente. Webpack konfiguracija je obično ovakva:

// stari webpack pristup
module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      use: ["@svgr/webpack"],
    });
    return config;
  },
};

Ekvivalent u Turbopacku je deklarativan i ne zahtijeva funkcionalnu konfiguraciju:

// next.config.ts s Turbopackom
const config: NextConfig = {
  turbopack: {
    rules: {
      "*.svg": {
        loaders: [
          {
            loader: "@svgr/webpack",
            options: { icon: true, typescript: true },
          },
        ],
        as: "*.js",
      },
    },
  },
};

Polje as govori Turbopacku kako interpretirati izlaz loadera nakon transformacije, u ovom slučaju kao JavaScript modul. Bez te oznake Turbopack ostavlja datoteku kao asset i izvozi joj URL, što je pogrešno za SVGR.

Turbopack u monorepu s pnpm i Turborepo

Najveći dio onoga što radim svaki dan je arhitektura monorepa: pnpm workspaces, dijeljeni design system, više Next.js aplikacija s različitim rasporedima izdanja. Turbopack se ovdje pokazao iznenađujuće dobro, ali ima nekoliko specifičnosti koje treba znati.

Prva je resolve aliases. U pnpm workspaceu se shared paket obično referencira preko "@acme/ui": "workspace:*" u package.json. Turbopack to razumije izvan kutije ako je tsconfig.json pravilno postavljen s paths i baseUrl. Ako koristiš dodatne alias mape (npr. za @/components), navedi ih u turbopack.resolveAlias jer Turbopack ne čita Webpack resolve.alias konfiguraciju.

Druga je transpilacija paketa iz workspaca. Next.js 15 podrazumijevano transpilira sve workspace:* ovisnosti ako su definirane u transpilePackages:

const config: NextConfig = {
  transpilePackages: ["@acme/ui", "@acme/icons", "@acme/utils"],
  turbopack: {
    resolveAlias: {
      "@/lib": "./src/lib",
    },
  },
};

Treća stvar, i ovdje sam izgubio dva cijela dana, je Turborepo cache kompatibilnost. Turborepo hashira ulaze taska prije pokretanja; ako Turbopack producira različite outpute za isti ulaz (npr. zbog različitog stanja perzistentnog cachea), Turborepo cache će biti invalidiran. Rješenje je u turbo.json dodati Turbopack cache direktorij kao outputs:

{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": ["src/**", "next.config.ts", "package.json"],
      "outputs": [".next/**", "!.next/cache/**", ".turbo/turbopack/**"],
      "env": ["NEXT_PUBLIC_*"]
    }
  }
}

Za detaljniji obrazac dijeljenja stanja između ruta pogledaj naš vodič kroz React Server Components i dohvaćanje podataka u App Routeru. Keširanje na bundler i React layeru komuniciraju indirektno preko ID-ova modula.

Optimizacija build vremena s perzistentnim cacheom

Najveća praktična novost u next build --turbopack kroz 2026. je perzistentni cache između buildova. U Webpacku je cache: { type: "filesystem" } davao slično ponašanje, ali je u CI okruženjima često bio nepouzdan zbog hashinga node_modules-a. Turbopack koristi sadržajni hash svakog ulaza i pohranjuje rezultate u .next/cache/turbopack, pa svaki CI runner može sigurno restorirati tu mapu i preskočiti rad koji je već napravljen.

Konkretan GitHub Actions snippet koji koristim:

- name: Restore Turbopack cache
  uses: actions/cache@v4
  with:
    path: |
      .next/cache/turbopack
      .next/cache/swc
    key: turbopack-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'next.config.ts') }}-${{ github.sha }}
    restore-keys: |
      turbopack-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'next.config.ts') }}-

- name: Build
  run: pnpm next build --turbopack

Bitno je odvojiti .next/cache/turbopack od ostatka .next/ jer ostatak je build output (koji se ne smije keširati između buildova), dok je cache mapa ulaz u sljedeći build. Na našem najvećem repu (4 aplikacije, ~3500 ruta ukupno) ovo je smanjilo CI build vrijeme s 14 min na 3.2 min u prosjeku. Vrijedilo je.

Za uparenu strategiju s rutama koje se mogu prerenderirati statički, kombiniraj ovo s Partial Prerendering pristupom u Next.js 15. Turbopack ne mijenja runtime ponašanje PPR-a, ali ubrzava prerender korak koji se izvršava tijekom builda.

Kako mjeriti stvarne performanse u svom projektu

Generičke izjave o brzini su beskorisne za argumentaciju pred staff-eng kolegama. Evo skripte koju koristim za hladne start benchmarkove:

#!/usr/bin/env bash
# bench-dev.sh: mjeri cold start time za next dev
set -euo pipefail

BUNDLER="${1:-turbopack}"
RUNS=5
TOTAL=0

for i in $(seq 1 $RUNS); do
  rm -rf .next
  START=$(node -e 'console.log(Date.now())')

  if [ "$BUNDLER" = "turbopack" ]; then
    pnpm next dev --turbopack --port 3000 &
  else
    pnpm next dev --port 3000 &
  fi
  PID=$!

  # čekaj na prvi 200 OK na root URL-u
  until curl -sf http://localhost:3000 > /dev/null; do sleep 0.1; done

  END=$(node -e 'console.log(Date.now())')
  ELAPSED=$((END - START))
  TOTAL=$((TOTAL + ELAPSED))
  echo "Run $i: ${ELAPSED}ms"

  kill $PID
  wait $PID 2> /dev/null || true
done

echo "Prosjek: $((TOTAL / RUNS))ms"

Pokreni ovo dvaput. Jednom s ./bench-dev.sh turbopack, jednom s ./bench-dev.sh webpack, i imat ćeš stvarne brojeve za svoj repo, ne moje. HMR mjerimo na malo drugačiji način, kroz Chrome DevTools Performance tab uz custom performance.mark() u našem React DevTools profileru, ali to je tema za zaseban članak.

Je li Turbopack spreman za produkciju?

Za next dev, bez dvojbe da. Stabilan je od Next.js 15 i koristi ga Vercel interno na cjelokupnoj infrastrukturi vlastitog dashboarda. Za next build --turbopack situacija je nijansiranija. Prema posljednjim podacima koje je Vercel objavio uz Next.js 15.4, beta build prolazi oko 99% integration testova samog Next.js framework-a, ali rubni slučajevi s custom Webpack pluginovima i Module Federation još uvijek nisu pokriveni.

Moja preporuka za produkcijske timove je sljedeća:

  1. Faza 1 (1–2 tjedna): Omogući Turbopack u next dev za sve developere. Ovo je zero-risk i daje najveću dnevnu vrijednost.
  2. Faza 2 (1 sprint): Pokreni next build --turbopack paralelno u CI-u uz next build, ali deployaj Webpack output. Usporedi bundle veličinu, hash konzistentnost i runtime greške.
  3. Faza 3: Prebaci produkcijski deploy na Turbopack build kad imaš dva tjedna paralelnih izvršavanja bez razlika.

Za autentifikaciju i runtime obrasce ne mijenja se ništa. Turbopack ne dira način na koji se kompajliraju middleware ili API route handleri. Ako još uvijek arhitektiraš sloj za sigurnost, naš vodič kroz Next.js middleware i dalje vrijedi 1:1.

Rubni slučajevi i ograničenja

Kroz tri produkcijske migracije naišao sam na sljedeće stvari koje nisu u službenoj dokumentaciji ili su lako previđene. Pišem ih ovdje da ti ne potrate dan:

  • Custom Webpack pluginovi nisu podržani. Ako si imao BundleAnalyzerPlugin, SentryWebpackPlugin ili sličnu funkcionalnost, mora se zamijeniti s ekvivalentom (@next/bundle-analyzer radi, Sentry ima @sentry/nextjs wrapper koji koristi SWC plugin).
  • Module Federation. Trenutno nije podržan. Ako imaš mikrofrontend arhitekturu s remote modulima, ostani na Webpacku barem do Q3 2026.
  • Babel pluginovi za internacionalizaciju, posebno babel-plugin-formatjs, moraju se zamijeniti s @formatjs/swc-plugin. Sintaksa konfiguracije je drugačija.
  • CSS-in-JS biblioteke. Emotion i styled-components rade preko SWC plugina, ali styled-jsx je izvorno podržan i preporučen za nove projekte.
  • Source mapovi u produkciji su uključeni po defaultu u beta verziji --turbopack builda. Provjeri productionBrowserSourceMaps postavku ako želiš isključiti.

Za detalje i službenu listu poznatih razlika pogledaj Next.js Turbopack API referencu i aktivnu raspravu o status migracije na GitHubu koja se ažurira sa svakim izdanjem. Za dublje arhitektonsko razumijevanje samog bundlera službena Turbopack dokumentacija opisuje memoizacijski sloj i lazy compilation strategiju.

Često postavljana pitanja

Je li Turbopack brži od Vite-a?

Za Next.js aplikacije Turbopack je obično brži jer je izgrađen specifično za React Server Components i App Router; cold start i HMR su mjerljivo niži. Vite je brz u Vue/Svelte/vanilla React kontekstu, ali za Next.js radi preko vite-plugin-react što ne dobiva istu razinu integracije sa SWC-om i Next.js cacheom.

Mogu li koristiti Tailwind CSS s Turbopackom?

Da, Tailwind CSS 4 (s vlastitim Rust enginom) radi besprijekorno preko ugrađene PostCSS podrške u Turbopacku. Konfiguracija je identična kao u Webpacku, samo standardna postcss.config.mjs datoteka s @tailwindcss/postcss pluginom.

Što ako moj projekt još koristi pages router?

Turbopack podržava i pages i app router u istom projektu, što je važno tijekom postupne migracije. Sav routing kod prolazi kroz isti bundler, bez posebnih flagova ili konfiguracije.

Treba li mi Node.js 22+ za Turbopack?

Ne, Turbopack je nativni Rust binary i ne ovisi o Node verziji za sami bundling, ali Next.js 15+ zahtijeva minimalno Node 18.18. Preporučujem Node 20 LTS za sve produkcijske workloads.

Hoće li Webpack biti uklonjen iz Next.js-a?

Vercel je naznačio da Webpack ostaje podržan kao fallback dok Turbopack ne dosegne 100% feature parity, što uključuje Module Federation. Realan vremenski okvir za uklanjanje je 2027. ili kasnije; nema razloga za žurbu ako tvoja arhitektura ovisi o Webpack-specific funkcionalnostima.

Mei-Lin Wu
O Autoru Mei-Lin Wu

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