SWC Feature Flags
A two-phase feature flag system for SWC that provides build-time marking and runtime dead code elimination.
Overview
This library enables powerful feature flag management with aggressive dead code elimination. It works in two phases:
- Build-time (SWC Plugin): Marks feature flag usage locations by replacing flag identifiers with
__SWC_FLAGS__markers - Runtime (Standalone Crate): Substitutes flag values and eliminates dead code branches
Features
- ✅ Destructuring support:
const { featureA, featureB } = useExperimentalFlags() - ✅ Customizable function names: Not hardcoded to specific function names
- ✅ Selective processing: Exclude specific flags from transformation
- ✅ Scope-safe: Uses SWC's
Idsystem to handle variable shadowing correctly - ✅ Dead code elimination: Removes unreachable code branches
- ✅ Statistics tracking: Reports bytes removed and branches eliminated
- ✅ Minifier-safe markers: Uses
__SWC_FLAGS__pattern that minifiers preserve
Architecture
Phase 1: Build-Time Transformation
The build-time plugin (@swc/plugin-feature-flags) performs these transformations:
Input:
import from '@their/library';
Output:
The plugin:
- Tracks imports from configured libraries
- Detects destructuring from configured flag functions
- Replaces flag identifiers with
__SWC_FLAGS__.flagNamemarkers - Removes import statements and hook calls
Phase 2: Runtime Transformation
The runtime transformer substitutes flag values and eliminates dead code:
Input (from Phase 1):
Runtime Config:
Output:
Installation
Rust API
Add to your Cargo.toml:
[]
= "0.1"
SWC Plugin (WASM)
Usage
Rust API
use ;
use HashMap;
use resolver;
use Mark;
// Build-time configuration
let mut libraries = new;
libraries.insert;
let build_config = BuildTimeConfig ;
// Apply resolver first (required for scope safety)
let unresolved_mark = new;
let top_level_mark = new;
program = program.apply;
// Apply build-time pass
program = program.apply;
// Runtime configuration
let mut flag_values = new;
flag_values.insert;
flag_values.insert;
let runtime_config = RuntimeConfig ;
// Apply runtime pass
program = program.apply;
SWC Plugin (.swcrc)
Configuration
Build-Time Config
interface BuildTimeConfig {
/** Library configurations: library name -> config */
libraries: Record<string, LibraryConfig>;
/** Flags to exclude from build-time marking */
excludeFlags?: string[];
/** Global object name for markers (default: "__SWC_FLAGS__") */
markerObject?: string;
}
interface LibraryConfig {
/** Function names to detect (e.g., ["useExperimentalFlags"]) */
functions: string[];
}
Runtime Config
Dead Code Elimination
The runtime transformer eliminates:
If Statements
// Input
if else
// Output
console.log;
Ternary Expressions
// Input
const result = __SWC_FLAGS__. ? 'On' : 'Off'; // false
// Output
const result = 'Off';
Logical Operators
// Input
const a = __SWC_FLAGS__. && ; // true
const b = __SWC_FLAGS__. && ; // false
const c = __SWC_FLAGS__. || ; // true
// Output
const a = ;
const b = false;
const c = true;
Negation
// Input
const notA = !__SWC_FLAGS__.; // true
// Output
const notA = false;
Scope Safety
The library uses SWC's Id system (symbol + syntax context) to handle variable shadowing correctly:
import from '@their/library';
Output:
Statistics
When collect_stats is enabled, the runtime transformer tracks:
Testing
# Run all tests
# Run fixture tests only
License
Apache-2.0
Contributing
Contributions are welcome! Please ensure:
- All tests pass
- Code follows Rust formatting guidelines
- New features include tests