Turbopack Samples
Turbopack bundler examples including configuration, performance optimization, and integration with modern web frameworks
Key Facts
- Category
- Build Tools
- Items
- 3
- Format Families
- image
Sample Overview
Turbopack bundler examples including configuration, performance optimization, and integration with modern web frameworks This sample set belongs to Build Tools and can be used to test related workflows inside Elysia Tools.
💻 Turbopack Basic Setup typescript
🟢 simple
⭐
Fundamental Turbopack configuration and basic usage patterns for web applications
⏱️ 15 min
🏷️ turbopack, nextjs, setup, development
Prerequisites:
Node.js, npm/yarn, Basic React knowledge
// Turbopack Basic Setup Examples
// Turbopack is an incremental bundler written in Rust for the web
// 1. Next.js with Turbopack
// package.json
{
"name": "my-turbopack-app",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev --turbo",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^14.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"eslint": "^8.0.0",
"eslint-config-next": "^14.0.0",
"typescript": "^5.0.0"
}
}
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
turbo: {
// Turbopack configuration
loaders: {
'.svg': ['@svgr/webpack'],
},
},
},
// Enable Turbopack for development
turbo: {
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
}
module.exports = nextConfig
// 2. Basic TypeScript Configuration
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"lib": ["dom", "dom.iterable", "ES2020"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"],
"@/components/*": ["./src/components/*"],
"@/lib/*": ["./src/lib/*"],
"@/styles/*": ["./src/styles/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
// 3. Basic App Structure
// src/app/layout.tsx
import './globals.css'
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export const metadata = {
title: 'Turbopack App',
description: 'A Next.js app powered by Turbopack',
}
function RootLayoutBasic({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={inter.className}>
<main className="min-h-screen bg-gray-50">
<nav className="bg-white shadow-sm border-b">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16">
<div className="flex items-center">
<h1 className="text-xl font-bold">Turbopack App</h1>
</div>
<div className="flex items-center space-x-4">
<a href="/" className="text-gray-600 hover:text-gray-900">
Home
</a>
<a href="/about" className="text-gray-600 hover:text-gray-900">
About
</a>
</div>
</div>
</div>
</nav>
{children}
</main>
</body>
</html>
)
}
// src/app/page.tsx
function HomePageBasic() {
return (
<div className="py-12">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center">
<h1 className="text-4xl font-bold text-gray-900 sm:text-5xl">
Welcome to Turbopack
</h1>
<p className="mt-6 text-xl text-gray-600 max-w-3xl mx-auto">
Experience lightning-fast builds with Turbopack, the incremental bundler
built for modern web development.
</p>
<div className="mt-10 flex justify-center space-x-4">
<button className="bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700">
Get Started
</button>
<button className="border border-gray-300 text-gray-700 px-6 py-3 rounded-lg hover:bg-gray-50">
Learn More
</button>
</div>
</div>
<div className="mt-16 grid grid-cols-1 md:grid-cols-3 gap-8">
<div className="text-center">
<div className="text-3xl font-bold text-blue-600">10x</div>
<div className="mt-2 text-lg text-gray-600">Faster Builds</div>
</div>
<div className="text-center">
<div className="text-3xl font-bold text-green-600">99%</div>
<div className="mt-2 text-lg text-gray-600">Reliability</div>
</div>
<div className="text-center">
<div className="text-3xl font-bold text-purple-600">5x</div>
<div className="mt-2 text-lg text-gray-600">Better DX</div>
</div>
</div>
</div>
</div>
)
}
// src/app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Custom CSS for Turbopack app */
.gradient-bg {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.turbopack-animations {
animation: fadeInUp 0.6s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
// 4. Component Examples
// src/components/TurbopackFeatures.tsx
import { useState } from 'react'
interface Feature {
title: string
description: string
icon: string
benefits: string[]
}
const features: Feature[] = [
{
title: 'Incremental Builds',
description: 'Only rebuild what changed with Turbopack's intelligent dependency tracking',
icon: '⚡',
benefits: ['10-100x faster builds', 'Minimal rebuilds', 'Smart caching']
},
{
title: 'Rust Performance',
description: 'Built with Rust for maximum performance and memory efficiency',
icon: '🦀',
benefits: ['Blazing fast', 'Memory efficient', 'Reliable']
},
{
title: 'Modern ESM Support',
description: 'First-class support for ES modules and modern JavaScript features',
icon: '📦',
benefits: ['Tree shaking', 'Code splitting', 'Modern syntax']
},
{
title: 'TypeScript Integration',
description: 'Deep TypeScript integration with zero-config setup',
icon: '📘',
benefits: ['Type checking', 'IntelliSense', 'Error reporting']
},
{
title: 'CSS Modules',
description: 'Built-in support for CSS modules and CSS-in-JS',
icon: '🎨',
benefits: ['Scoped styles', 'CSS-in-JS', 'PostCSS support']
},
{
title: 'Hot Module Replacement',
description: 'Lightning-fast HMR for instant development feedback',
icon: '🔄',
benefits: ['State preservation', 'Instant updates', 'Dev tooling']
}
]
function TurbopackFeatures() {
const [selectedFeature, setSelectedFeature] = useState<number | null>(null)
return (
<div className="py-16 bg-gray-50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h2 className="text-3xl font-bold text-center text-gray-900 mb-12">
Turbopack Features
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{features.map((feature, index) => (
<div
key={index}
className={`bg-white rounded-lg shadow-lg p-6 cursor-pointer transition-all duration-300 hover:shadow-xl ${
selectedFeature === index ? 'ring-2 ring-blue-500' : ''
}`}
onClick={() => setSelectedFeature(selectedFeature === index ? null : index)}
>
<div className="text-4xl mb-4">{feature.icon}</div>
<h3 className="text-xl font-semibold text-gray-900 mb-2">
{feature.title}
</h3>
<p className="text-gray-600 mb-4">{feature.description}</p>
{selectedFeature === index && (
<div className="mt-4 pt-4 border-t">
<h4 className="font-semibold text-gray-900 mb-2">Benefits:</h4>
<ul className="space-y-1">
{feature.benefits.map((benefit, idx) => (
<li key={idx} className="flex items-center text-sm text-gray-600">
<span className="w-1.5 h-1.5 bg-green-500 rounded-full mr-2"></span>
{benefit}
</li>
))}
</ul>
</div>
)}
</div>
))}
</div>
</div>
</div>
)
}
// src/components/PerformanceComparison.tsx
function PerformanceComparison() {
const benchmarks = [
{ metric: 'Cold Start', webpack: '2.3s', turbopack: '0.4s', improvement: '5.8x' },
{ metric: 'Hot Reload', webpack: '1.8s', turbopack: '0.1s', improvement: '18x' },
{ metric: 'Build Size', webpack: '245KB', turbopack: '210KB', improvement: '14%' },
{ metric: 'Memory Usage', webpack: '512MB', turbopack: '180MB', improvement: '65%' },
]
return (
<div className="py-16 bg-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h2 className="text-3xl font-bold text-center text-gray-900 mb-12">
Performance Comparison
</h2>
<div className="bg-gray-50 rounded-lg p-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{benchmarks.map((benchmark, index) => (
<div key={index} className="text-center">
<div className="text-2xl font-bold text-gray-900 mb-2">
{benchmark.metric}
</div>
<div className="space-y-2 mb-4">
<div className="flex justify-between text-sm">
<span className="text-gray-600">Webpack:</span>
<span className="font-medium">{benchmark.webpack}</span>
</div>
<div className="flex justify-between text-sm">
<span className="text-gray-600">Turbopack:</span>
<span className="font-medium text-green-600">{benchmark.turbopack}</span>
</div>
</div>
<div className="bg-green-100 text-green-800 rounded-lg px-3 py-2">
<div className="text-lg font-bold">{benchmark.improvement}</div>
<div className="text-xs">faster</div>
</div>
</div>
))}
</div>
<div className="mt-8 text-center">
<p className="text-gray-600">
Benchmarks based on typical Next.js applications. Results may vary based on
project complexity and configuration.
</p>
</div>
</div>
</div>
</div>
)
}
// 5. API Routes with Turbopack
// src/app/api/hello/route.ts
import { NextResponse } from 'next/server'
export async function GET(request: Request) {
const searchParams = request.nextUrl.searchParams
const name = searchParams.get('name') || 'World'
return NextResponse.json({
message: `Hello, ${name}!`,
timestamp: new Date().toISOString(),
bundler: 'Turbopack'
})
}
export async function POST(request: Request) {
try {
const body = await request.json()
const { name } = body
return NextResponse.json({
message: `Hello, ${name}!`,
received: body,
timestamp: new Date().toISOString()
})
} catch (error) {
return NextResponse.json(
{ error: 'Invalid JSON data' },
{ status: 400 }
)
}
}
// src/app/api/users/route.ts
import { NextResponse } from 'next/server'
// Mock user data
const users = [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Smith', email: '[email protected]' },
{ id: 3, name: 'Bob Johnson', email: '[email protected]' },
]
export async function GET() {
return NextResponse.json({
users,
count: users.length,
bundler: 'Turbopack'
})
}
export async function POST(request: Request) {
try {
const body = await request.json()
const newUser = {
id: users.length + 1,
...body
}
users.push(newUser)
return NextResponse.json({
message: 'User created successfully',
user: newUser
}, { status: 201 })
} catch (error) {
return NextResponse.json(
{ error: 'Failed to create user' },
{ status: 500 }
)
}
}
// 6. Development Scripts
// scripts/dev.js
const { execSync } = require('child_process')
const fs = require('fs')
const path = require('path')
// Check if Turbopack is available
function checkTurbopack() {
try {
execSync('npx next --version', { stdio: 'pipe' })
return true
} catch {
console.log('❌ Next.js not found. Installing...')
execSync('npm install next@latest react@latest react-dom@latest', { stdio: 'inherit' })
return true
}
}
// Start development server with Turbopack
function startDevServer() {
console.log('🚀 Starting development server with Turbopack...')
console.log('📦 This will use Turbopack for lightning-fast builds!')
console.log('🌐 Visit http://localhost:3000 to see your app')
try {
execSync('npm run dev', { stdio: 'inherit' })
} catch (error) {
console.error('❌ Failed to start development server:', error.message)
process.exit(1)
}
}
// Main execution
if (require.main === module) {
if (checkTurbopack()) {
startDevServer()
}
}
// 7. Environment Configuration
// .env.local
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:3000/api
TURBOPACK=1
NODE_ENV=development
// .env.production.local
NEXT_PUBLIC_APP_URL=https://your-app-domain.com
NEXT_PUBLIC_API_URL=https://your-api-domain.com/api
NODE_ENV=production
const exportedTurbopackFeatures = TurbopackFeatures
💻 Turbopack Advanced Configuration typescript
🟡 intermediate
⭐⭐⭐⭐
Advanced Turbopack configuration including custom loaders, plugins, performance optimization, and build customization
⏱️ 45 min
🏷️ turbopack, advanced, configuration, optimization
Prerequisites:
Turbopack basics, Next.js, TypeScript, Build tools
// Turbopack Advanced Configuration
// Advanced patterns and customization for Turbopack
// 1. Advanced Next.js Configuration with Turbopack
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
turbo: {
// Enable Turbopack
turbo: {
// Custom loaders configuration
loaders: {
'.svg': [
{
loader: '@svgr/webpack',
options: {
icon: true,
svgo: true,
svgoConfig: {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false,
},
},
},
],
},
},
},
],
'.glsl': ['raw-loader'],
'.wgsl': ['raw-loader'],
'.mdx': ['@next/mdx'],
},
// Resolve aliases
resolveAlias: {
'@': './src',
'@/components': './src/components',
'@/lib': './src/lib',
'@/styles': './src/styles',
'@/assets': './src/assets',
'@/types': './src/types',
},
// External packages to skip transpilation
externals: ['sharp', 'canvas'],
// Custom transformations
transform: {
'^.+\\.(js|jsx|ts|tsx)$': ['swc-loader'],
},
// Source map configuration
sourceMap: {
production: true,
development: true,
},
// Minification
minify: process.env.NODE_ENV === 'production',
// Tree shaking
treeshake: true,
// Code splitting
splitChunks: {
chunks: 'all',
cacheGroups: {
default: false,
vendors: false,
framework: {
name: 'framework',
chunks: 'all',
test: /(?<!node_modules.*)[\\/]node_modules[\\/](react|react-dom|scheduler|prop-types|use-subscription)[\\/]/,
priority: 40,
enforce: true,
},
lib: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context
? module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)?.[1]
: null
return `npm.${packageName}`
},
priority: 30,
minChunks: 1,
reuseExistingChunk: true,
},
},
},
},
},
// Experimental features
appDir: true,
serverComponentsExternalPackages: ['@prisma/client'],
// Output configuration
output: 'standalone',
// Compression
compress: true,
// Powered-by header removal
poweredByHeader: false,
// React strict mode
reactStrictMode: true,
// SWC minification
swcMinify: true,
// Image optimization
images: {
domains: ['example.com', 'cdn.example.com'],
formats: ['image/webp', 'image/avif'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
// Rewrites for API routes
async rewrites() {
return [
{
source: '/api/external/:path*',
destination: 'https://external-api.com/:path*',
},
]
},
// Redirects
async redirects() {
return [
{
source: '/home',
destination: '/',
permanent: true,
},
]
},
// Headers
async headers() {
return [
{
source: '/api/:path*',
headers: [
{ key: 'Access-Control-Allow-Credentials', value: 'true' },
{ key: 'Access-Control-Allow-Origin', value: '*' },
{ key: 'Access-Control-Allow-Methods', value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT' },
],
},
]
},
},
// Webpack configuration fallback (for when Turbopack is not used)
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// Custom webpack rules
config.module.rules.push({
test: /\\.glsl$/,
use: 'raw-loader',
})
// Performance optimizations
if (!dev && !isServer) {
config.optimization.splitChunks = {
chunks: 'all',
cacheGroups: {
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: -10,
chunks: 'all',
},
},
}
}
return config
},
}
module.exports = nextConfig
// 2. Custom Turbopack Loader
// loaders/custom-loader.ts
import type { LoaderContext } from '@next/swc'
function customLoader(
this: LoaderContext,
source: string
): string {
const { resourcePath, options } = this
// Custom transformation logic
if (resourcePath.endsWith('.custom')) {
// Process custom file format
const processed = source
.replace(/\/\* CUSTOM_START \*\//g, '')
.replace(/\/\* CUSTOM_END \*\//g, '')
.trim()
return `export default ${JSON.stringify(processed)};`
}
// TypeScript file processing
if (resourcePath.endsWith('.ts') || resourcePath.endsWith('.tsx')) {
// Add custom TypeScript transformations
return source
.replace(/console\.log/g, '// console.log') // Remove console.logs
.replace(/debugger;/g, '// debugger;') // Remove debuggers
}
return source
}
// 3. Turbopack Plugin System
// plugins/turbopack-plugin.ts
import type { Plugin } from '@next/swc'
interface PluginOptions {
enabled?: boolean
analyze?: boolean
}
export function turbopackPlugin(options: PluginOptions = {}): Plugin {
const { enabled = true, analyze = false } = options
return {
name: 'custom-turbopack-plugin',
apply(compiler) {
if (!enabled) return
compiler.hooks.beforeCompile.tap('CustomPlugin', (params) => {
console.log('🔧 Turbopack compilation starting...')
})
compiler.hooks.afterCompile.tap('CustomPlugin', (stats) => {
console.log('✅ Turbopack compilation completed!')
if (analyze) {
console.log('📊 Build stats:', {
time: stats.endTime - stats.startTime,
assets: stats.assets?.length || 0,
chunks: stats.chunks?.length || 0
})
}
})
// Custom optimization hooks
compiler.hooks.optimize.tap('CustomPlugin', (compilation) => {
// Add custom optimizations
compilation.modules.forEach(module => {
// Module-specific optimizations
})
})
},
}
}
// 4. Environment-specific Configuration
// config/turbo.config.development.ts
import type { TurboConfig } from 'turbo'
const devConfig: TurboConfig = {
pipeline: {
build: {
dependsOn: ['^build'],
cache: false,
},
dev: {
cache: false,
persistent: true,
},
lint: {
outputs: [],
},
test: {
dependsOn: ['build'],
cache: false,
},
},
env: {
NEXT_PUBLIC_DEV_MODE: 'true',
TURBOPACK_DEV: 'true',
},
}
const exportedDevConfig = devConfig
// config/turbo.config.production.ts
import type { TurboConfig } from 'turbo'
const prodConfig: TurboConfig = {
pipeline: {
build: {
dependsOn: ['^build', 'lint', 'test'],
cache: true,
},
lint: {
outputs: [],
},
test: {
dependsOn: ['build'],
cache: true,
},
deploy: {
dependsOn: ['build'],
cache: false,
},
},
env: {
NEXT_PUBLIC_DEV_MODE: 'false',
TURBOPACK_PROD: 'true',
},
}
const exportedProdConfig = prodConfig
// 5. Performance Monitoring
// utils/performance-monitor.ts
interface BuildMetrics {
startTime: number
endTime?: number
duration?: number
fileSize?: number
chunks?: number
assets?: string[]
}
class TurbopackPerformanceMonitor {
private metrics: Map<string, BuildMetrics> = new Map()
startBuild(buildName: string) {
this.metrics.set(buildName, {
startTime: Date.now(),
})
}
endBuild(buildName: string, additionalMetrics?: Partial<BuildMetrics>) {
const metric = this.metrics.get(buildName)
if (metric) {
metric.endTime = Date.now()
metric.duration = metric.endTime - metric.startTime
if (additionalMetrics) {
Object.assign(metric, additionalMetrics)
}
console.log(`📈 Build Performance (${buildName}):`, {
duration: `${metric.duration}ms`,
fileSize: metric.fileSize ? `${(metric.fileSize / 1024 / 1024).toFixed(2)}MB` : 'N/A',
chunks: metric.chunks || 'N/A'
})
}
}
getReport(): string {
const report = ['📊 Turbopack Performance Report\n']
for (const [name, metric] of this.metrics) {
report.push(`🔹 ${name}:`)
if (metric.duration) {
report.push(` Duration: ${metric.duration}ms`)
}
if (metric.fileSize) {
report.push(` Size: ${(metric.fileSize / 1024 / 1024).toFixed(2)}MB`)
}
report.push('')
}
return report.join('\n')
}
}
export const performanceMonitor = new TurbopackPerformanceMonitor()
// 6. Build Optimization Scripts
// scripts/optimize-build.js
const { execSync } = require('child_process')
const fs = require('fs')
const path = require('path')
class BuildOptimizer {
constructor() {
this.projectRoot = process.cwd()
this.nextConfigPath = path.join(this.projectRoot, 'next.config.js')
this.packageJsonPath = path.join(this.projectRoot, 'package.json')
}
async optimizeForProduction() {
console.log('🚀 Optimizing build for production...')
// 1. Analyze bundle size
await this.analyzeBundleSize()
// 2. Optimize dependencies
await this.optimizeDependencies()
// 3. Configure Turbopack for production
await this.configureTurbopackProduction()
// 4. Run production build
await this.runProductionBuild()
}
async analyzeBundleSize() {
console.log('📦 Analyzing bundle size...')
try {
const result = execSync('npm run build -- --analyze', {
encoding: 'utf8',
stdio: 'pipe'
})
console.log('Bundle analysis completed.')
} catch (error) {
console.warn('Bundle analysis failed, continuing...')
}
}
async optimizeDependencies() {
console.log('🔧 Optimizing dependencies...')
// Remove unused dependencies
const packageJson = JSON.parse(fs.readFileSync(this.packageJsonPath, 'utf8'))
// Add production-specific optimizations
if (!packageJson.browser) {
packageJson.browser = {
"fs": false,
"path": false,
"os": false
}
}
fs.writeFileSync(this.packageJsonPath, JSON.stringify(packageJson, null, 2))
console.log('✅ Dependencies optimized')
}
async configureTurbopackProduction() {
console.log('⚙️ Configuring Turbopack for production...')
const configContent = `
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
turbo: {
loaders: {
'.svg': ['@svgr/webpack'],
},
resolveAlias: {
'@': './src',
},
minify: true,
treeshake: true,
sourceMap: false,
},
},
swcMinify: true,
compress: true,
poweredByHeader: false,
output: 'standalone',
}
module.exports = nextConfig
`
fs.writeFileSync(this.nextConfigPath, configContent)
console.log('✅ Turbopack configured for production')
}
async runProductionBuild() {
console.log('🏗️ Running production build...')
try {
execSync('npm run build', { stdio: 'inherit' })
console.log('✅ Production build completed successfully!')
} catch (error) {
console.error('❌ Production build failed:', error.message)
process.exit(1)
}
}
}
// CLI execution
if (require.main === module) {
const optimizer = new BuildOptimizer()
optimizer.optimizeForProduction().catch(console.error)
}
// 7. Custom Turbopack Presets
// presets/react-library-preset.ts
import type { TurboConfig } from 'turbo'
export function reactLibraryPreset(): TurboConfig {
return {
pipeline: {
build: {
dependsOn: ['^build'],
outputs: ['dist/**'],
},
dev: {
cache: false,
persistent: true,
},
test: {
dependsOn: ['build'],
cache: true,
},
lint: {
outputs: [],
},
typecheck: {
dependsOn: ['build'],
cache: true,
},
},
globalEnv: {
NODE_ENV: 'development',
TURBOPACK: '1',
},
env: {
NEXT_PUBLIC_APP_NAME: 'React Library',
},
}
}
// presets/monorepo-preset.ts
export function monorepoPreset(): TurboConfig {
return {
pipeline: {
build: {
dependsOn: ['^build'],
outputs: ['dist/**', '.next/**'],
},
dev: {
cache: false,
persistent: true,
},
lint: {
outputs: [],
},
test: {
dependsOn: ['build'],
cache: true,
},
clean: {
cache: false,
},
},
globalDependencies: ['**/.env.*local'],
globalEnv: {
NODE_ENV: 'development',
TURBOPACK: '1',
},
}
}
// 8. Development Utilities
// utils/turbo-dev-utils.ts
export class TurboDevUtils {
static async reloadConfig() {
// Clear require cache for config files
Object.keys(require.cache).forEach(key => {
if (key.includes('next.config') || key.includes('turbo.config')) {
delete require.cache[key]
}
})
console.log('🔄 Configuration reloaded')
}
static async invalidateCache(pattern: string) {
// Invalidate Turbopack cache for specific patterns
console.log(`🗑️ Invalidating cache for pattern: ${pattern}`)
}
static measureBuildPerformance() {
const startTime = performance.now()
return {
end: () => {
const endTime = performance.now()
const duration = endTime - startTime
return {
duration,
formatted: `${duration.toFixed(2)}ms`,
performanceLevel: duration < 1000 ? 'excellent' :
duration < 3000 ? 'good' : 'needs-improvement'
}
}
}
}
static getBuildStats() {
return {
memoryUsage: process.memoryUsage(),
platform: process.platform,
nodeVersion: process.version,
turbopackVersion: '1.0.0', // Get from package.json
}
}
}
// Usage examples
export function startOptimizedDevServer() {
const perf = TurboDevUtils.measureBuildPerformance()
console.log('🚀 Starting optimized dev server...')
console.log('📊 Current system stats:', TurboDevUtils.getBuildStats())
// Simulate dev server start
setTimeout(() => {
const stats = perf.end()
console.log(`⚡ Dev server ready! (${stats.formatted})`)
console.log(`🎯 Performance: ${stats.performanceLevel}`)
}, 100)
}
const exportedBuildOptimizer = BuildOptimizer
💻 Turbopack Migration Guide typescript
🔴 complex
⭐⭐⭐⭐⭐
Complete migration guide from Webpack/Vite to Turbopack including step-by-step process and best practices
⏱️ 90 min
🏷️ turbopack, migration, automation, advanced
Prerequisites:
Advanced build tools knowledge, JavaScript/TypeScript, CLI usage
// Turbopack Migration Guide
// Complete guide for migrating from Webpack/Vite to Turbopack
// 1. Migration Assessment Script
// scripts/assess-migration.ts
import * as fs from 'fs'
import * as path from 'path'
import { execSync } from 'child_process'
interface ProjectAssessment {
projectName: string
packageManager: 'npm' | 'yarn' | 'pnpm'
buildTool: 'webpack' | 'vite' | 'rollup' | 'other'
framework: 'nextjs' | 'react' | 'vue' | 'angular' | 'other'
complexity: 'simple' | 'medium' | 'complex'
migrationComplexity: 'easy' | 'moderate' | 'challenging'
compatibility: Array<{
feature: string
status: 'supported' | 'partial' | 'unsupported'
notes: string
}>
recommendations: string[]
}
class MigrationAssessor {
private projectPath: string
constructor(projectPath: string = process.cwd()) {
this.projectPath = projectPath
}
assessProject(): ProjectAssessment {
const packageJson = this.readPackageJson()
const assessment: ProjectAssessment = {
projectName: packageJson.name || 'unknown',
packageManager: this.detectPackageManager(),
buildTool: this.detectBuildTool(packageJson),
framework: this.detectFramework(packageJson),
complexity: this.assessComplexity(),
migrationComplexity: 'moderate',
compatibility: [],
recommendations: []
}
this.assessCompatibility(assessment)
this.generateRecommendations(assessment)
return assessment
}
private readPackageJson(): any {
try {
const packageJsonPath = path.join(this.projectPath, 'package.json')
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
} catch {
return {}
}
}
private detectPackageManager(): 'npm' | 'yarn' | 'pnpm' {
if (fs.existsSync(path.join(this.projectPath, 'pnpm-lock.yaml'))) return 'pnpm'
if (fs.existsSync(path.join(this.projectPath, 'yarn.lock'))) return 'yarn'
return 'npm'
}
private detectBuildTool(packageJson: any): 'webpack' | 'vite' | 'rollup' | 'other' {
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies }
if (deps.vite) return 'vite'
if (deps.webpack || deps['webpack-cli'] || deps['webpack-dev-server']) return 'webpack'
if (deps.rollup) return 'rollup'
return 'other'
}
private detectFramework(packageJson: any): 'nextjs' | 'react' | 'vue' | 'angular' | 'other' {
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies }
if (deps.next) return 'nextjs'
if (deps.react && deps['react-dom']) return 'react'
if (deps.vue) return 'vue'
if (deps['@angular/core']) return 'angular'
return 'other'
}
private assessComplexity(): 'simple' | 'medium' | 'complex' {
let score = 0
// Check for custom configuration files
if (fs.existsSync(path.join(this.projectPath, 'webpack.config.js'))) score += 2
if (fs.existsSync(path.join(this.projectPath, 'vite.config.ts'))) score += 1
if (fs.existsSync(path.join(this.projectPath, 'postcss.config.js'))) score += 1
if (fs.existsSync(path.join(this.projectPath, 'tailwind.config.js'))) score += 1
// Check for number of dependencies
const packageJson = this.readPackageJson()
const depCount = Object.keys({
...packageJson.dependencies,
...packageJson.devDependencies
}).length
if (depCount > 50) score += 2
else if (depCount > 20) score += 1
if (score <= 2) return 'simple'
if (score <= 4) return 'medium'
return 'complex'
}
private assessCompatibility(assessment: ProjectAssessment) {
const features = [
{ feature: 'TypeScript Support', supported: true },
{ feature: 'ES Modules', supported: true },
{ feature: 'CSS Modules', supported: true },
{ feature: 'PostCSS', supported: true },
{ feature: 'Tailwind CSS', supported: true },
{ feature: 'Static Assets', supported: true },
{ feature: 'Code Splitting', supported: true },
{ feature: 'Tree Shaking', supported: true },
]
if (assessment.framework === 'nextjs') {
features.push(
{ feature: 'App Router', supported: true },
{ feature: 'Server Components', supported: true },
{ feature: 'API Routes', supported: true },
{ feature: 'Image Optimization', supported: true },
{ feature: 'Font Optimization', supported: true }
)
}
assessment.compatibility = features.map(feature => ({
...feature,
status: feature.supported ? 'supported' : 'partial',
notes: feature.supported ? 'Fully supported by Turbopack' : 'May require configuration'
}))
// Check for potentially incompatible features
const potentiallyIncompatible = [
'Custom Webpack Loaders',
'Complex Babel Configurations',
'Specific Webchain Plugins',
'Legacy Module Systems'
]
potentiallyIncompatible.forEach(feature => {
assessment.compatibility.push({
feature,
status: 'partial',
notes: 'May require custom loader or configuration'
})
})
}
private generateRecommendations(assessment: ProjectAssessment) {
const recommendations: string[] = []
if (assessment.framework === 'nextjs') {
recommendations.push('✅ Excellent choice! Turbopack is designed for Next.js')
recommendations.push('🚀 Simply add --turbo flag to your dev script')
} else {
recommendations.push('⚠️ Consider migrating to Next.js for best Turbopack experience')
}
if (assessment.complexity === 'simple') {
recommendations.push('🎯 Your project complexity is ideal for easy migration')
} else if (assessment.complexity === 'complex') {
recommendations.push('🔧 Consider simplifying configuration before migration')
recommendations.push('📋 Document current webpack/vite configuration')
}
recommendations.push('📦 Update to latest package versions')
recommendations.push('🧪 Test thoroughly after migration')
recommendations.push('👥 Consider gradual migration for large projects')
assessment.recommendations = recommendations
}
generateReport(): string {
const assessment = this.assessProject()
let report = `📊 Migration Assessment Report for ${assessment.projectName}
\n🔧 Build Tool: ${assessment.buildTool}
🎨 Framework: ${assessment.framework}
📦 Package Manager: ${assessment.packageManager}
🎯 Project Complexity: ${assessment.complexity}
🚀 Migration Complexity: ${assessment.migrationComplexity}
📋 Feature Compatibility:
\n`
assessment.compatibility.forEach(comp => {
const icon = comp.status === 'supported' ? '✅' : comp.status === 'partial' ? '⚠️' : '❌'
report += `${icon} ${comp.feature}: ${comp.notes}\n`
})
report += `
\n💡 Recommendations:
\n`
assessment.recommendations.forEach(rec => {
report += `${rec}\n`
})
return report
}
}
// CLI execution
if (require.main === module) {
const assessor = new MigrationAssessor()
console.log(assessor.generateReport())
}
export { MigrationAssessor, ProjectAssessment }
// 2. Webpack to Turbopack Migration Script
// scripts/migrate-webpack-to-turbopack.ts
import * as fs from 'fs'
import * as path from 'path'
interface WebpackConfig {
entry?: any
output?: any
module?: {
rules?: any[]
}
resolve?: {
alias?: Record<string, string>
extensions?: string[]
}
plugins?: any[]
optimization?: any
}
class WebpackToTurbopackMigrator {
private projectPath: string
private webpackConfig: WebpackConfig
constructor(projectPath: string = process.cwd()) {
this.projectPath = projectPath
this.webpackConfig = this.loadWebpackConfig()
}
private loadWebpackConfig(): WebpackConfig {
const configPath = path.join(this.projectPath, 'webpack.config.js')
if (!fs.existsSync(configPath)) {
throw new Error('webpack.config.js not found')
}
// Clear require cache to ensure fresh load
delete require.cache[require.resolve(configPath)]
try {
const config = require(configPath)
return typeof config === 'function' ? config() : config
} catch (error) {
console.warn('Failed to load webpack config:', error.message)
return {}
}
}
migrate(): void {
console.log('🔄 Starting migration from Webpack to Turbopack...')
// 1. Create Next.js project structure if it doesn't exist
this.createNextJsStructure()
// 2. Migrate entry points
this.migrateEntryPoints()
// 3. Migrate loaders
this.migrateLoaders()
// 4. Migrate resolve configuration
this.migrateResolveConfig()
// 5. Migrate plugins
this.migratePlugins()
// 6. Create Turbopack configuration
this.createTurbopackConfig()
// 7. Update package.json scripts
this.updatePackageJson()
// 8. Create migration report
this.createMigrationReport()
console.log('✅ Migration completed successfully!')
}
private createNextJsStructure() {
const appDir = path.join(this.projectPath, 'src', 'app')
if (!fs.existsSync(appDir)) {
fs.mkdirSync(appDir, { recursive: true })
// Create basic app structure
fs.writeFileSync(
path.join(appDir, 'layout.tsx'),
this.generateDefaultLayout()
)
fs.writeFileSync(
path.join(appDir, 'page.tsx'),
this.generateDefaultPage()
)
}
}
private migrateEntryPoints() {
if (this.webpackConfig.entry) {
console.log('📝 Migrating entry points...')
// Entry points are handled differently in Next.js
// Convert to pages or app router structure
}
}
private migrateLoaders() {
if (!this.webpackConfig.module?.rules) return
console.log('📦 Migrating loaders...')
const loaders: string[] = []
this.webpackConfig.module.rules.forEach(rule => {
// Handle different loader types
if (rule.test?.test(/\\.svg$/)) {
loaders.push("'.svg': ['@svgr/webpack']")
}
if (rule.test?.test(/\\.(css|scss|sass)$/)) {
// CSS is handled automatically by Turbopack
}
if (rule.test?.test(/\\.(ts|tsx|js|jsx)$/)) {
// TypeScript/JavaScript is handled automatically
}
})
this.turbopackLoaders = loaders
}
private migrateResolveConfig() {
if (!this.webpackConfig.resolve) return
console.log('🔍 Migrating resolve configuration...')
if (this.webpackConfig.resolve.alias) {
this.turbopackAliases = this.webpackConfig.resolve.alias
}
if (this.webpackConfig.resolve.extensions) {
// Extensions are handled automatically by Turbopack
}
}
private migratePlugins() {
if (!this.webpackConfig.plugins) return
console.log('🔌 Migrating plugins...')
this.webpackConfig.plugins.forEach(plugin => {
// Handle specific plugins
if (plugin.constructor.name === 'HtmlWebpackPlugin') {
// Handled automatically by Next.js
}
if (plugin.constructor.name === 'MiniCssExtractPlugin') {
// CSS extraction handled automatically
}
})
}
private turbopackLoaders: string[] = []
private turbopackAliases: Record<string, string> = {}
private createTurbopackConfig() {
const configContent = `/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
turbo: {
loaders: {
${this.turbopackLoaders.join(',\n ')}
},
resolveAlias: {
${Object.entries(this.turbopackAliases)
.map(([key, value]) => `'${key}': '${value}'`)
.join(',\n ')}
},
},
},
}
module.exports = nextConfig`
const configPath = path.join(this.projectPath, 'next.config.js')
fs.writeFileSync(configPath, configContent)
console.log('⚙️ Created next.config.js with Turbopack configuration')
}
private updatePackageJson() {
const packageJsonPath = path.join(this.projectPath, 'package.json')
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
// Update dependencies for Next.js
if (!packageJson.dependencies?.next) {
packageJson.dependencies = {
...packageJson.dependencies,
next: '^14.0.0',
react: '^18.0.0',
'react-dom': '^18.0.0'
}
}
// Update dev dependencies
packageJson.devDependencies = {
...packageJson.devDependencies,
'@types/node': '^20.0.0',
'@types/react': '^18.0.0',
'@types/react-dom': '^18.0.0',
typescript: '^5.0.0'
}
// Update scripts
packageJson.scripts = {
...packageJson.scripts,
dev: 'next dev --turbo',
build: 'next build',
start: 'next start',
lint: 'next lint'
}
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
console.log('📦 Updated package.json with Next.js scripts and dependencies')
}
private createMigrationReport() {
const report = {
migrationDate: new Date().toISOString(),
originalConfig: this.webpackConfig,
migratedFeatures: {
loaders: this.turbopackLoaders.length,
aliases: Object.keys(this.turbopackAliases).length,
},
nextSteps: [
'Install new dependencies: npm install',
'Test the development server: npm run dev',
'Check all pages and components work correctly',
'Update any custom webpack loaders not supported by Turbopack',
'Test build process: npm run build'
],
knownIssues: this.identifyKnownIssues()
}
fs.writeFileSync(
path.join(this.projectPath, 'migration-report.json'),
JSON.stringify(report, null, 2)
)
console.log('📋 Created migration-report.json')
}
private identifyKnownIssues(): string[] {
const issues: string[] = []
// Check for potentially problematic configurations
if (this.webpackConfig.plugins?.some(p => p.constructor.name === 'DefinePlugin')) {
issues.push('Webpack DefinePlugin needs to be converted to Next.js environment variables')
}
if (this.webpackConfig.optimization) {
issues.push('Custom webpack optimization may need manual migration')
}
return issues
}
private generateDefaultLayout(): string {
return `import './globals.css'
export const metadata = {
title: 'Migrated App',
description: 'Migrated from Webpack to Turbopack',
}
function RootLayoutFromWebpackMigration({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<main>{children}</main>
</body>
</html>
)
}`
}
private generateDefaultPage(): string {
return `function HomePage() {
return (
<div>
<h1>Welcome to Your Turbopack App!</h1>
<p>Successfully migrated from Webpack to Turbopack</p>
</div>
)
}`
}
}
// 3. Vite to Turbopack Migration
// scripts/migrate-vite-to-turbopack.ts
class ViteToTurbopackMigrator {
private projectPath: string
private viteConfig: any
constructor(projectPath: string = process.cwd()) {
this.projectPath = projectPath
this.viteConfig = this.loadViteConfig()
}
private loadViteConfig(): any {
const configPath = path.join(this.projectPath, 'vite.config.ts')
if (!fs.existsSync(configPath)) {
console.warn('vite.config.ts not found, assuming default configuration')
return {}
}
try {
// In a real implementation, you'd need to properly load the Vite config
return {}
} catch (error) {
console.warn('Failed to load Vite config:', error.message)
return {}
}
}
migrate(): void {
console.log('🔄 Starting migration from Vite to Turbopack...')
this.convertToNextJs()
this.migratePlugins()
this.updateConfiguration()
this.updatePackageJson()
console.log('✅ Vite to Turbopack migration completed!')
}
private convertToNextJs() {
console.log('🔄 Converting to Next.js structure...')
// Create app directory structure
const appDir = path.join(this.projectPath, 'src', 'app')
fs.mkdirSync(appDir, { recursive: true })
// Convert index.html to layout.tsx and page.tsx
this.convertIndexHtml()
// Convert src/main.tsx to app components
this.convertMainTs()
}
private convertIndexHtml() {
const indexPath = path.join(this.projectPath, 'index.html')
if (fs.existsSync(indexPath)) {
const indexContent = fs.readFileSync(indexPath, 'utf8')
const title = indexContent.match(/<title>(.*?)<\/title>/)?.[1] || 'App'
// Create layout.tsx
const layoutContent = `import './globals.css'
export const metadata = {
title: '${title}',
description: 'Migrated from Vite to Turbopack',
}
function RootLayoutFromViteMigration({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<div id="root">{children}</div>
</body>
</html>
)
}`
fs.writeFileSync(
path.join(this.projectPath, 'src', 'app', 'layout.tsx'),
layoutContent
)
console.log('📄 Converted index.html to Next.js layout')
}
}
private convertMainTs() {
const mainPath = path.join(this.projectPath, 'src', 'main.tsx')
if (fs.existsSync(mainPath)) {
const mainContent = fs.readFileSync(mainPath, 'utf8')
// Create page.tsx from main.tsx content
const pageContent = `'use client'
${mainContent.replace(/import React from 'react'/, '')}
function HomePageFromViteMigration() {
return <App />
}`
fs.writeFileSync(
path.join(this.projectPath, 'src', 'app', 'page.tsx'),
pageContent
)
console.log('📄 Converted main.tsx to Next.js page')
}
}
private migratePlugins() {
// Vite plugins need to be converted to Next.js configuration
if (this.viteConfig.plugins) {
console.log('🔌 Analyzing Vite plugins for migration...')
// Handle common plugins
const pluginMap: Record<string, string> = {
'@vitejs/plugin-react': 'Built-in to Next.js',
'vite-plugin-svgr': '@svgr/webpack in Turbopack',
'tailwindcss': 'Built-in to Next.js',
'postcss': 'Built-in to Next.js'
}
this.viteConfig.plugins.forEach((plugin: any) => {
const pluginName = typeof plugin === 'string' ? plugin : plugin.name
if (pluginMap[pluginName]) {
console.log(` ✅ ${pluginName}: ${pluginMap[pluginName]}`)
} else {
console.log(` ⚠️ ${pluginName}: May require custom configuration`)
}
})
}
}
private updateConfiguration() {
console.log('⚙️ Creating Next.js configuration...')
const nextConfig = {
experimental: {
turbo: {
// Vite-specific settings would go here
}
}
}
const configContent = `/** @type {import('next').NextConfig} */
const nextConfig = ${JSON.stringify(nextConfig, null, 2)}
module.exports = nextConfig`
fs.writeFileSync(
path.join(this.projectPath, 'next.config.js'),
configContent
)
}
private updatePackageJson() {
console.log('📦 Updating package.json...')
const packageJsonPath = path.join(this.projectPath, 'package.json')
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
// Update dependencies
packageJson.dependencies = {
...packageJson.dependencies,
next: '^14.0.0',
'react': '^18.0.0',
'react-dom': '^18.0.0'
}
// Remove Vite-specific dependencies
delete packageJson.devDependencies?.vite
delete packageJson.devDependencies?.['@vitejs/plugin-react']
// Update scripts
packageJson.scripts = {
dev: 'next dev --turbo',
build: 'next build',
start: 'next start',
preview: 'next build && next start',
lint: 'next lint'
}
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
}
}
// 4. Migration Verification Script
// scripts/verify-migration.ts
class MigrationVerifier {
private projectPath: string
constructor(projectPath: string = process.cwd()) {
this.projectPath = projectPath
}
async verify(): Promise<boolean> {
console.log('🔍 Verifying migration...')
const checks = [
this.checkDependencies(),
this.checkConfiguration(),
this.checkProjectStructure(),
this.checkDevelopmentServer(),
this.checkBuildProcess()
]
const results = await Promise.allSettled(checks)
const failures = results.filter(r => r.status === 'rejected')
if (failures.length === 0) {
console.log('✅ All verification checks passed!')
return true
} else {
console.log(`❌ ${failures.length} verification checks failed:`)
failures.forEach((failure, index) => {
console.log(` ${index + 1}. ${failure.reason}`)
})
return false
}
}
private async checkDependencies(): Promise<void> {
const requiredPackages = ['next', 'react', 'react-dom']
const packageJsonPath = path.join(this.projectPath, 'package.json')
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
const missing = requiredPackages.filter(pkg => !packageJson.dependencies?.[pkg])
if (missing.length > 0) {
throw new Error(`Missing required packages: ${missing.join(', ')}`)
}
}
private async checkConfiguration(): Promise<void> {
const configPath = path.join(this.projectPath, 'next.config.js')
if (!fs.existsSync(configPath)) {
throw new Error('next.config.js not found')
}
}
private async checkProjectStructure(): Promise<void> {
const requiredPaths = [
'src/app/layout.tsx',
'src/app/page.tsx'
]
const missing = requiredPaths.filter(p => !fs.existsSync(path.join(this.projectPath, p)))
if (missing.length > 0) {
throw new Error(`Missing required files: ${missing.join(', ')}`)
}
}
private async checkDevelopmentServer(): Promise<void> {
// This would typically try to start the dev server
// For now, just check if the script exists
const packageJsonPath = path.join(this.projectPath, 'package.json')
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
if (!packageJson.scripts?.dev?.includes('--turbo')) {
throw new Error('Development script not configured for Turbopack')
}
}
private async checkBuildProcess(): Promise<void> {
const packageJsonPath = path.join(this.projectPath, 'package.json')
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
if (!packageJson.scripts?.build) {
throw new Error('Build script not found')
}
}
}
// 5. Usage Examples
// CLI execution
if (require.main === module) {
const args = process.argv.slice(2)
const command = args[0]
switch (command) {
case 'assess':
const assessor = new MigrationAssessor()
console.log(assessor.generateReport())
break
case 'webpack':
const webpackMigrator = new WebpackToTurbopackMigrator()
webpackMigrator.migrate()
break
case 'vite':
const viteMigrator = new ViteToTurbopackMigrator()
viteMigrator.migrate()
break
case 'verify':
const verifier = new MigrationVerifier()
verifier.verify().then(success => {
process.exit(success ? 0 : 1)
})
break
default:
console.log(`
Usage: npm run migrate [command]
Commands:
assess - Assess project migration readiness
webpack - Migrate from Webpack to Turbopack
vite - Migrate from Vite to Turbopack
verify - Verify migration was successful
`)
}
}
export {
MigrationAssessor,
WebpackToTurbopackMigrator,
ViteToTurbopackMigrator,
MigrationVerifier
}