Prerequisites
- Basic understanding of JavaScript 📝
- TypeScript installation ⚡
- VS Code or preferred IDE 💻
What you'll learn
- Understand SWC fundamentals 🎯
- Apply SWC in real projects 🏗️
- Debug common SWC issues 🐛
- Write type-safe builds with SWC ✨
🎯 Introduction
Welcome to the blazing-fast world of SWC! 🎉 If you’ve been waiting forever for your TypeScript builds to finish, you’re in for a treat. SWC (Speedy Web Compiler) is a Rust-based compiler that’s up to 20x faster than traditional JavaScript tools!
Think of SWC as the Formula 1 car 🏎️ of JavaScript/TypeScript compilers. While other tools are still warming up their engines, SWC has already crossed the finish line! Whether you’re building massive enterprise applications 🏢, lightning-fast web apps 🌐, or complex libraries 📚, SWC will supercharge your development workflow.
By the end of this tutorial, you’ll be compiling TypeScript at warp speed and wondering how you ever lived without SWC! Let’s dive in! 🚀
📚 Understanding SWC
🤔 What is SWC?
SWC is like having a super-powered mechanic 🔧 for your JavaScript and TypeScript code. Think of it as a translator that speaks multiple languages fluently - it can transform your modern TypeScript into various JavaScript versions, optimize your code, and do it all at incredible speed!
In technical terms, SWC is a extensible Rust-based platform for the next generation of fast developer tools 🛠️. This means you can:
- ✨ Compile TypeScript to JavaScript at lightning speed
- 🚀 Transform JSX and modern syntax
- 🛡️ Minimize and optimize your code
- 📦 Bundle modules efficiently
💡 Why Use SWC?
Here’s why developers are falling in love with SWC:
- Blazing Speed ⚡: 10-20x faster than Babel/TSC
- Memory Efficient 🧠: Uses less RAM during compilation
- Plugin Ecosystem 🔌: Extensible with Rust plugins
- Drop-in Replacement 🔄: Easy migration from existing tools
- Active Development 👨💻: Constantly improving and updating
Real-world example: Imagine your current TypeScript build takes 2 minutes ⏰. With SWC, it might finish in just 6 seconds! That’s like upgrading from a bicycle 🚲 to a rocket ship 🚀.
🔧 Basic Syntax and Usage
📦 Installation
Let’s get SWC running in your project:
# 📦 Install SWC core
npm install -D @swc/core @swc/cli
# 🎯 For TypeScript support
npm install -D @swc/core @types/node
# 🚀 For React/JSX (if needed)
npm install -D @swc/plugin-react
📝 Basic Configuration
Create a .swcrc
file in your project root:
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true
},
"target": "es2020",
"loose": false,
"externalHelpers": false,
"keepClassNames": false,
"transform": {
"react": {
"pragma": "React.createElement",
"pragmaFrag": "React.Fragment",
"throwIfNamespace": true,
"development": false,
"useBuiltins": false
}
}
},
"module": {
"type": "commonjs",
"strict": false,
"strictMode": true,
"lazy": false,
"noInterop": false
},
"minify": false,
"sourceMaps": true
}
💡 Explanation: This configuration tells SWC to parse TypeScript with JSX support, target ES2020, and generate source maps for debugging!
🎯 Command Line Usage
Here are the essential SWC commands:
# 🔄 Compile a single file
npx swc src/app.ts -o dist/app.js
# 📁 Compile entire directory
npx swc src -d dist
# 👀 Watch mode for development
npx swc src -d dist --watch
# 🗜️ Minify output
npx swc src -d dist --minify
# 🎯 Specific TypeScript config
npx swc src -d dist --config-file .swcrc
💡 Practical Examples
🛒 Example 1: E-commerce Product Transformer
Let’s build a real-world TypeScript application with SWC:
// 🛍️ src/product.ts - Our TypeScript source
interface Product {
id: string;
name: string;
price: number;
category: 'electronics' | 'clothing' | 'books';
inStock: boolean;
tags: string[];
emoji: string; // Every product needs personality!
}
// 🏪 Product store with advanced TypeScript features
class ProductStore {
private products: Map<string, Product> = new Map();
// ➕ Add product with validation
addProduct(product: Product): void {
if (this.validateProduct(product)) {
this.products.set(product.id, product);
console.log(`✅ Added ${product.emoji} ${product.name} to store!`);
} else {
throw new Error(`❌ Invalid product: ${product.name}`);
}
}
// 🔍 Find products by category
findByCategory(category: Product['category']): Product[] {
return Array.from(this.products.values())
.filter(product => product.category === category && product.inStock);
}
// 💰 Calculate category totals
getCategoryStats(): Record<Product['category'], { count: number; value: number }> {
const stats: Record<Product['category'], { count: number; value: number }> = {
electronics: { count: 0, value: 0 },
clothing: { count: 0, value: 0 },
books: { count: 0, value: 0 }
};
for (const product of this.products.values()) {
if (product.inStock) {
stats[product.category].count++;
stats[product.category].value += product.price;
}
}
return stats;
}
// 🛡️ Private validation method
private validateProduct(product: Product): boolean {
return product.price > 0 &&
product.name.length > 0 &&
product.id.length > 0;
}
}
// 🎮 Let's use our store!
const store = new ProductStore();
store.addProduct({
id: "laptop-1",
name: "Gaming Laptop",
price: 1299.99,
category: "electronics",
inStock: true,
tags: ["gaming", "portable", "rgb"],
emoji: "💻"
});
store.addProduct({
id: "book-1",
name: "TypeScript Handbook",
price: 29.99,
category: "books",
inStock: true,
tags: ["programming", "typescript", "reference"],
emoji: "📘"
});
🚀 Compile with SWC:
# ⚡ Lightning-fast compilation
npx swc src/product.ts -o dist/product.js
# 🎯 Result: Optimized JavaScript in milliseconds!
🎮 Example 2: Game Development Build Pipeline
Let’s create a more complex build setup:
// 🎮 src/game/player.ts
interface PlayerStats {
health: number;
mana: number;
level: number;
experience: number;
inventory: Item[];
}
interface Item {
id: string;
name: string;
type: 'weapon' | 'armor' | 'consumable';
rarity: 'common' | 'rare' | 'epic' | 'legendary';
emoji: string;
}
// 🧙♂️ Advanced TypeScript class with decorators
class Player {
private stats: PlayerStats;
private position: { x: number; y: number };
constructor(name: string) {
this.stats = {
health: 100,
mana: 50,
level: 1,
experience: 0,
inventory: []
};
this.position = { x: 0, y: 0 };
console.log(`🎮 Player ${name} has entered the game!`);
}
// 🗡️ Attack with type-safe damage calculation
attack(target: Player): number {
const weapon = this.getEquippedWeapon();
const baseDamage = weapon ? this.calculateWeaponDamage(weapon) : 10;
const levelBonus = this.stats.level * 2;
const totalDamage = baseDamage + levelBonus;
console.log(`⚔️ Dealt ${totalDamage} damage with ${weapon?.emoji || '👊'}`);
return totalDamage;
}
// 🎒 Inventory management
addItem(item: Item): void {
this.stats.inventory.push(item);
console.log(`📦 Received ${item.emoji} ${item.name} (${item.rarity})!`);
}
// 🔍 Private helper methods
private getEquippedWeapon(): Item | undefined {
return this.stats.inventory.find(item => item.type === 'weapon');
}
private calculateWeaponDamage(weapon: Item): number {
const rarityMultiplier = {
common: 1,
rare: 1.5,
epic: 2,
legendary: 3
};
return 20 * rarityMultiplier[weapon.rarity];
}
}
⚙️ Advanced SWC Configuration:
// 🎯 .swcrc for game development
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true,
"dynamicImport": true
},
"target": "es2020",
"loose": false,
"transform": {
"optimizer": {
"globals": {
"vars": {
"DEBUG": "false"
}
}
},
"legacyDecorator": true,
"decoratorMetadata": true
}
},
"module": {
"type": "es6"
},
"minify": true,
"sourceMaps": true
}
🚀 Advanced Concepts
🧙♂️ Custom SWC Plugins
When you’re ready to level up, create custom transformations:
// 🦀 Example Rust plugin concept (simplified)
use swc_core::ecma::{
ast::*,
visit::{as_folder, FoldWith, VisitMut, VisitMutWith},
};
pub struct EmojiTransformer;
impl VisitMut for EmojiTransformer {
fn visit_mut_str(&mut self, s: &mut Str) {
// 🎨 Transform console.log messages to include emojis
if s.value.starts_with("console.log") {
s.value = format!("🚀 {}", s.value).into();
}
}
}
🏗️ Webpack Integration
Integrate SWC with your existing build tools:
// 📦 webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: '@swc/loader',
options: {
jsc: {
parser: {
syntax: 'typescript',
tsx: true,
},
transform: {
react: {
runtime: 'automatic',
},
},
},
},
},
exclude: /node_modules/,
},
],
},
};
⚠️ Common Pitfalls and Solutions
😱 Pitfall 1: Configuration Confusion
// ❌ Wrong - Missing important settings
{
"jsc": {
"parser": {
"syntax": "typescript"
}
}
}
// ✅ Correct - Complete configuration
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true,
"dynamicImport": true
},
"target": "es2020",
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
}
},
"module": {
"type": "commonjs"
},
"sourceMaps": true
}
🤯 Pitfall 2: Module System Mismatch
// ❌ Dangerous - Mixed module systems!
import { something } from './module'; // ES6 import
const other = require('./other'); // CommonJS require
// ✅ Safe - Consistent module usage!
import { something } from './module';
import { other } from './other';
// OR use all CommonJS consistently
🚫 Pitfall 3: Source Map Issues
# ❌ Missing source maps - debugging nightmare!
npx swc src -d dist
# ✅ Include source maps - debugging bliss!
npx swc src -d dist --source-maps
🛠️ Best Practices
- 🎯 Use .swcrc: Centralize configuration instead of CLI options
- 📊 Profile Builds: Use
--profile
to identify bottlenecks - 🗜️ Minify Wisely: Only minify production builds
- 🔍 Source Maps: Always enable for debugging
- ⚡ Incremental Builds: Use watch mode during development
- 🔌 Plugin Sparingly: Only add plugins you actually need
🧪 Hands-On Exercise
🎯 Challenge: Build a TypeScript Microservice with SWC
Create a complete build pipeline for a REST API:
📋 Requirements:
- ✅ TypeScript Express.js server
- 🏷️ Decorators for routing and validation
- 👤 Advanced types for request/response
- 📅 Build optimization for production
- 🎨 Source maps for debugging
- 🚀 Lightning-fast compilation
🚀 Bonus Points:
- Add custom SWC configuration
- Implement watch mode for development
- Create production build script
- Add bundle size analysis
💡 Solution
🔍 Click to see solution
// 🎯 src/server.ts - Our TypeScript microservice
import express, { Request, Response, NextFunction } from 'express';
import cors from 'cors';
// 🎨 Advanced TypeScript interfaces
interface ApiResponse<T = any> {
success: boolean;
data?: T;
error?: string;
timestamp: string;
emoji: string;
}
interface User {
id: string;
name: string;
email: string;
avatar: string;
createdAt: Date;
isActive: boolean;
}
interface CreateUserRequest {
name: string;
email: string;
avatar?: string;
}
// 🛡️ Type-safe response helper
function createResponse<T>(
success: boolean,
data?: T,
error?: string,
emoji: string = '✅'
): ApiResponse<T> {
return {
success,
data,
error,
timestamp: new Date().toISOString(),
emoji
};
}
// 🏪 In-memory user store (for demo)
class UserStore {
private users: Map<string, User> = new Map();
create(userData: CreateUserRequest): User {
const user: User = {
id: `user_${Date.now()}`,
name: userData.name,
email: userData.email,
avatar: userData.avatar || '👤',
createdAt: new Date(),
isActive: true
};
this.users.set(user.id, user);
console.log(`✅ Created user: ${user.avatar} ${user.name}`);
return user;
}
findById(id: string): User | undefined {
return this.users.get(id);
}
findAll(): User[] {
return Array.from(this.users.values());
}
update(id: string, updates: Partial<User>): User | undefined {
const user = this.users.get(id);
if (user) {
Object.assign(user, updates);
console.log(`🔄 Updated user: ${user.avatar} ${user.name}`);
return user;
}
return undefined;
}
}
// 🚀 Express server setup
const app = express();
const userStore = new UserStore();
// 🛠️ Middleware
app.use(cors());
app.use(express.json());
// 📝 Logging middleware
app.use((req: Request, res: Response, next: NextFunction) => {
console.log(`🌐 ${req.method} ${req.path} - ${new Date().toISOString()}`);
next();
});
// 🎯 Routes
app.get('/health', (req: Request, res: Response) => {
res.json(createResponse(true, { status: 'healthy' }, undefined, '💚'));
});
app.get('/users', (req: Request, res: Response) => {
const users = userStore.findAll();
res.json(createResponse(true, users, undefined, '👥'));
});
app.get('/users/:id', (req: Request, res: Response) => {
const user = userStore.findById(req.params.id);
if (user) {
res.json(createResponse(true, user, undefined, '👤'));
} else {
res.status(404).json(createResponse(false, null, 'User not found', '❌'));
}
});
app.post('/users', (req: Request, res: Response) => {
try {
const userData: CreateUserRequest = req.body;
// 🛡️ Basic validation
if (!userData.name || !userData.email) {
return res.status(400).json(
createResponse(false, null, 'Name and email are required', '⚠️')
);
}
const user = userStore.create(userData);
res.status(201).json(createResponse(true, user, undefined, '🎉'));
} catch (error) {
res.status(500).json(
createResponse(false, null, 'Internal server error', '💥')
);
}
});
app.put('/users/:id', (req: Request, res: Response) => {
const updates = req.body;
const user = userStore.update(req.params.id, updates);
if (user) {
res.json(createResponse(true, user, undefined, '✨'));
} else {
res.status(404).json(createResponse(false, null, 'User not found', '❌'));
}
});
// 🚀 Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`🚀 Server running on port ${PORT}`);
console.log(`🌐 Health check: http://localhost:${PORT}/health`);
});
export default app;
⚙️ Advanced .swcrc Configuration:
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true,
"dynamicImport": true
},
"target": "es2020",
"loose": false,
"externalHelpers": false,
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true,
"optimizer": {
"globals": {
"vars": {
"NODE_ENV": "production"
}
}
}
}
},
"module": {
"type": "commonjs",
"strict": false,
"strictMode": true
},
"minify": true,
"sourceMaps": true,
"env": {
"targets": {
"node": "16"
}
}
}
🔧 Package.json Scripts:
{
"scripts": {
"dev": "npx swc src -d dist --watch && node dist/server.js",
"build": "npx swc src -d dist --minify",
"start": "node dist/server.js",
"build:profile": "npx swc src -d dist --profile"
}
}
🎓 Key Takeaways
You’ve learned so much about SWC! Here’s what you can now do:
- ✅ Setup SWC in any TypeScript project 💪
- ✅ Configure builds for maximum performance 🛡️
- ✅ Integrate with tools like Webpack and Express 🎯
- ✅ Debug efficiently with source maps 🐛
- ✅ Optimize builds for production deployment 🚀
Remember: SWC isn’t just faster - it’s a paradigm shift toward Rust-based tooling that prioritizes speed without sacrificing features! 🤝
🤝 Next Steps
Congratulations! 🎉 You’ve mastered SWC and unlocked blazing-fast TypeScript compilation!
Here’s what to do next:
- 💻 Replace your current build tools with SWC
- 🏗️ Experiment with custom plugins and configurations
- 📚 Move on to our next tutorial: “Turbopack: Next-Generation Bundler”
- 🌟 Share your build time improvements with the community!
Remember: Every millisecond saved in build time is a millisecond gained for creativity. Keep optimizing, keep building, and most importantly, keep having fun with blazing-fast development! 🚀
Happy coding at the speed of Rust! 🦀⚡✨