WebAssembly Plugins
The WASM plugins interface is still experimental. Please share your bug reports and feedback.
Use the WebAssembly interace to extend SWC and create high-performance plugins.
Create your first plugin
You can create your first WebAssembly plugin for SWC using the CLI.
First, install the CLI package through cargo:
$ cargo install swc_cliWe've provided helpful code generation to scaffold a new project for creating plugins. Create a new plugin project using the SWC CLI:
$ swc plugin new my-plugin --target-type=wasm32-wasiExample plugin
Here's an example plugin that replaces console.log(${text}) with console.log('changed_via_plugin'):
use swc_plugin::{ast::*, errors::HANDLER, plugin_transform, syntax_pos::DUMMY_SP};
struct ConsoleOutputReplacer;
/// An example plugin replaces any `console.log(${text})` into
/// `console.log('changed_via_plugin')`.
impl VisitMut for ConsoleOutputReplacer {
fn visit_mut_call_expr(&mut self, call: &mut CallExpr) {
if let Callee::Expr(expr) = &call.callee {
if let Expr::Member(MemberExpr { obj, .. }) = &**expr {
if let Expr::Ident(ident) = &**obj {
if ident.sym == *"console" {
call.args[0].expr = Box::new(Expr::Lit(Lit::Str(Str {
span: DUMMY_SP,
has_escape: false,
kind: StrKind::default(),
value: JsWord::from("changed_via_plugin"),
})));
}
}
}
}
}
}Loading plugins
{
jsc: {
experimental: {
// Optional, specify where swc will create wasm bytecode cache.
cache_root: String,
// If `pluginname` is resolvable to npm package,
// it'll try to load from installed npm packages.
// Otherwise, it can be an absolute path to the .wasm binary.
plugins: [ ['pluginname', pluginOptions: Record<string, any>] ]
}
}Publishing
To publish your WebAssembly plugin to npm, you can build the required .wasm file using cargo build:
$ cargo build --release --target wasm32-wasiAdjusting configuration for smaller plugins
You can reduce the size of your plugin by configuring your Cargo.toml file:
[profile.release]
# Remove more dead code
codegen-units = 1
lto = true
# Optimize for size
opt-level = "s"Frequently Asked Questions
The plugin binary is WASM. Does that mean I can write plugins without Rust?
Yes. As long as you generate a WebAssembly binary, it satisfies SWC's transform interface. However, there are some challenges:
- Serialization / Deserialization: there is no other language binding for the serialization / deserialization mechanism used in the plugin.
- AST interfaces: We only have typed AST interface support with Rust so far.
- Utility support: SWC's AST helper is written in Rust.
If you write a plugin without Rust, please let us know and we can add an example.
I'm using the WASM version of SWC. How does the plugin work?
Currently, the wasm version of SWC doesn't support any plugins, except for JavaScript. We are working on solutions here.
What is the plan for JavaScript plugins?
Existing JavaScript plugins for SWC will continue to work. We aren’t planning to invest in improving the performance of the JS plugins, since we now recommend using WASM instead. We will post a future RFC with the migration path from JavaScript to WASM plugins.
Plugins CLI Reference
--targetwasm32-wasiwasm32-unknown-unknown