Build Process
Understand how the SvelteKit Exec Adapter transforms your application into a single executable binary.
Overview
The build process involves several stages that transform your SvelteKit application into a standalone executable:
graph TD
A[SvelteKit Build] --> B[Asset Processing]
B --> C[Bundle Creation]
C --> D[Bun Compilation]
D --> E[Executable Binary]
Stage 1: SvelteKit Build
The adapter first runs the standard SvelteKit build process:
✅ SvelteKit build started
📦 Bundling client-side code...
🔧 Building server-side code...
✅ SvelteKit build completed
What happens:
- Client code is bundled and optimized
- Server routes are compiled
- Static assets are processed
- Build artifacts are created in
.svelte-kit/output
Stage 2: Asset Processing
The adapter analyzes and processes all static assets:
📊 Analyzing assets...
🔍 Found 42 static files (12.3 MB total)
✅ Asset validation passed
📦 Embedding static assets...
Asset validation checks:
- Individual file size limits
- Total asset size limits
- File type restrictions
- Security validations
Asset embedding process:
- Scan static directory - Find all static files
- Validate assets - Check size and type restrictions
- Encode assets - Convert to base64 or binary format
- Embed in bundle - Include in the final executable
Asset Embedding Example
// Before: Traditional file serving
app.use('/static', express.static('static'));
// After: Embedded asset serving
app.get('/favicon.png', (req, res) => {
res.type('image/png');
res.send(Buffer.from(EMBEDDED_ASSETS.favicon_png, 'base64'));
});
Stage 3: Bundle Creation
The adapter creates a unified bundle containing:
🔧 Creating bundle...
├── Server code
├── Client assets
├── Static files (embedded)
├── Runtime configuration
└── Bun runtime headers
Bundle structure:
bundle.js
├── SvelteKit server code
├── API routes and middleware
├── Client-side assets (HTML, CSS, JS)
├── Embedded static files
├── Environment configuration
└── Startup scripts
Server Bundle Example
// Generated bundle.js (simplified)
import { createServer } from 'http';
import { handler } from './app.js';
// Embedded assets
const ASSETS = {
'favicon.png': 'iVBORw0KGgoAAAANSUhEUgAA...',
'app.css': 'body{margin:0;padding:0}...'
};
// Asset serving middleware
function serveAsset(path) {
if (ASSETS[path]) {
return ASSETS[path];
}
return null;
}
// Start server
const server = createServer(handler);
server.listen(3000);
Stage 4: Bun Compilation
The bundle is compiled into an executable using Bun:
🔨 Compiling executable with Bun...
🎯 Target: linux-x64
📦 Bundle size: 15.2 MB
⚡ Compilation completed in 3.2s
Compilation process:
- Bundle analysis - Bun analyzes the JavaScript bundle
- Dependency resolution - All imports are resolved statically
- Runtime embedding - Bun runtime is included in the binary
- Platform compilation - Code is compiled for the target platform
- Asset integration - Embedded assets are included in the binary
Bun Compilation Command
# Equivalent to what the adapter runs
bun build bundle.js
--compile
--target=bun-linux-x64
--outfile=my-app
Stage 5: Executable Creation
The final executable contains everything needed to run your app:
✅ Executable created: build/my-app
📊 Final size: 47.3 MB
🚀 Ready to deploy!
Executable structure:
my-app (executable)
├── Bun runtime (30MB)
├── Your application code (10MB)
├── Node.js polyfills (5MB)
└── Embedded assets (2.3MB)
Build Optimization
Reducing Binary Size
1. Optimize asset embedding:
adapter({
embedStatic: false, // Serve from filesystem
validation: {
allowedExtensions: ['.js', '.css', '.svg'] // Essential files only
}
});
2. Minimize dependencies:
// Avoid large dependencies in your SvelteKit app
import { lightweight } from 'small-library';
// Instead of
import { heavy } from 'massive-library';
3. Use asset optimization:
# Optimize images before build
npm install -D @squoosh/cli
squoosh-cli --webp static/images/*.jpg
Build Performance
Parallel processing:
// The adapter automatically uses available CPU cores
// for asset processing and compression
Incremental builds:
# Only rebuilds changed assets
npm run build # Full build first time
npm run build # Incremental subsequent builds
Cross-Platform Building
Target Platforms
The adapter supports building for different platforms:
// Build for specific platform
adapter({
target: 'windows-x64' // Build Windows executable on any platform
});
Available targets:
linux-x64
- Linux 64-bitlinux-arm64
- Linux ARM64darwin-x64
- macOS Inteldarwin-arm64
- macOS Apple Siliconwindows-x64
- Windows 64-bit
CI/CD Integration
# GitHub Actions example
name: Cross-platform Build
on: [push]
jobs:
build:
strategy:
matrix:
platform:
- { os: ubuntu-latest, target: linux-x64 }
- { os: macos-latest, target: darwin-x64 }
- { os: windows-latest, target: windows-x64 }
runs-on: ${{ matrix.platform.os }}
steps:
- uses: actions/checkout@v3
- uses: oven-sh/setup-bun@v1
- run: npm ci
- run: npm run build
env:
TARGET: ${{ matrix.platform.target }}
Debugging Build Issues
Verbose Logging
Enable detailed build output:
DEBUG=sveltekit-exec-adapter npm run build
Common Build Problems
1. Asset too large:
❌ Error: Asset 'large-video.mp4' (150MB) exceeds limit (50MB)
Solution: Increase limit or exclude the file
adapter({
validation: { maxAssetSize: 200 * 1024 * 1024 }
})
2. Unsupported file type:
❌ Error: File type '.exe' is blocked for security
Solution: Remove blocked files or adjust validation
adapter({
validation: { blockedExtensions: [] }
})
3. Bun compilation fails:
❌ Error: Cannot resolve module 'some-native-module'
Solution: Use pure JavaScript alternatives or exclude native modules
Build Analysis
Analyze your build output:
# Check executable size
ls -lh build/my-app
# Analyze bundle composition
bun analyze bundle.js
# Check asset sizes
du -sh static/*
Advanced Build Customization
Custom Asset Processing
// In your build script
import { readFileSync, writeFileSync } from 'fs';
// Pre-process assets before build
const css = readFileSync('app.css', 'utf8');
const minified = css.replace(/s+/g, ' ').trim();
writeFileSync('app.min.css', minified);
Post-Build Scripts
{
"scripts": {
"build": "svelte-kit build && npm run post-build",
"post-build": "node scripts/sign-executable.js"
}
}
The build process is designed to be robust, fast, and produce optimized executables while maintaining all SvelteKit functionality.