A Hands-on Guide to the SWC Platform: Unleashing the Power of Rust on the Web

A Hands-on Guide to the SWC Platform Unleashing the Power of Rust on the Web

Introduction

Rust is an innovative systems programming language promising improved performance, safety, and concurrency compared to mainstream web languages like JavaScript, Python, and Ruby.

However, Rust has seen limited adoption on the web due to lack of tools and frameworks tailored for this environment.

SWC aims to change that by providing an ecosystem of technologies enabling productive web development in Rust.

This comprehensive guide introduces the SWC platform for unlocking Rust on the web. We’ll cover:

  • SWC Compiler for transpiling modern JavaScript and TypeScript
  • Substrate back-end web framework
  • Full-stack application frameworks like Spruce
  • Hands-on example of building a web app with Spruce

By the end, you’ll understand how SWC enables building robust and scalable web systems in Rust.

Challenges with Current Web Development

Let’s first consider common pain points in mainstream web stacks:

  • Performance Overheads – Scripting languages have high runtime costs resulting in poor latency and throughput at scale.
  • Safety Issues – Languages like JavaScript and Python are prone to crashes, bugs, and runtime exceptions.
  • Concurrency Headaches – Achieving efficient parallelism and async programming is challenging.
  • Codebase Complexity – Projects accumulate cruft and tech debt as features continuously change.
  • Debugging Difficulties – Reproducing and fixing issues in dynamic runtime environments is hard.
  • Productivity Limits – Loose typing hampers refactoring. Boilerplate code clutters logic.

Rust provides solutions to these problems through its unique set of capabilities:

  • Performance – Compiled language close to metal with minimal runtime.
  • Safety – Strong static types and ownership model eliminate classes of bugs.
  • Concurrency – Lightweight threads, async/await, and fearless parallel code.
  • Reliability – Tested robust standard libraries and cargo package manager.
  • Productivity – Expressive type system, pattern matching, and functional style.

By harnessing Rust’s strengths, SWC provides technologies to overcome challenges with current web development stacks.

Introducing the SWC Platform

The SWC platform aims to unlock the power of Rust for the web through its suite of technologies:

  • SWC Compiler – Drop-in replacement for Babel to transpile modern JavaScript and TypeScript.
  • Substrate – Low-level framework for building server-side web services in Rust.
  • App Frameworks – High-level abstractions for productive full-stack web programming with Rust.

This layered ecosystem lets you leverage Rust and WebAssembly according to your needs – from incrementally replacing Babel to full-stack applications.

SWC Compiler

The SWC compiler provides a faster, more extensible drop-in replacement for Babel to transpile modern JavaScript and TypeScript source code.

It processes code in a series of self-contained, pluggable transforms:

  • Parsing – Convert source code into abstract syntax tree (AST).
  • Transforming – Plugins apply transformations like JSX conversion on the AST.
  • Printing – Prints the final transformed AST back into code.

This compiler pipeline model enables fast incremental changes by only re-running necessary transforms.

SWC improves on Babel by:

  • Compiling via Rust for native speed vs JavaScript interpretation overhead.
  • Concurrent transform execution via Rayon harnessing multi-core CPUs.
  • Avoids Babel’s glue code that hampers optimizations.
  • Extensibility – additional plugins can be implemented in JavaScript/TypeScript.

The result is significantly faster transpilation with flexibility:

Let’s install SWC:

# Install via npm
npm install -g @swc/cli @swc/core

# Transpile React file
swc src/app.jsx --out-dir build

This provides a transpilation pipeline with best-in-class performance.

Substrate Web Framework

With the SWC compiler handling transpilation, the next layer is Substrate – a low-level web framework for building server-side web applications in Rust.

Substrate provides ergonomic APIs for concepts like routing, middleware, and request handling without dictating high-level app structure:

// Import crates
use substrate_app_server::{get,post,App,Middleware};
use serde::{Deserialize, Serialize};

// Handler functions 
#[get("/")]
fn index() -> &'static str {
  "Hello world!"  
}

#[post("/echo")]
fn echo(body: String) -> String {
  body
}

// Construct App
let app = App::new().
  middleware( LoggingMiddleware ). 
  route("/hello", get(handler_fn) ).
  route("/echo", post(echo)); 

// Run server
app.listen("127.0.0.1:3000");

This allows gradually introducing Rust into existing codebases while benefiting from Rust’s runtime advantages.

Key capabilities:

  • Familiar middleware and routing model
  • Async request handling via async/await
  • First-class WebAssembly compilation
  • Lean by avoiding imposedopinions

Substrate enables building production web services in Rust idiomatically.

High-Level App Frameworks

While Substrate provides the low-level web app runtime, higher-level frameworks add structure and patterns tailored for ergonomic full-stack development.

Spruce

Spruce offers an opinionated batteries-included full-stack web framework for building services and frontend applications in Rust.

It brings together Substrate, SWC, and declarative code generation to accelerate development.

// example/app.rs
use spruce::{App, HttpMethod};

pub fn create_app() -> App {
  App::new().
    get("/", |_req| "Hello from Spruce!").
    api(Api::new().endpoint(
      HttpMethod::Post,
      "/ Signup",
      |mut ctx| async move { /*...*/ },
    ))  
}

This defines an app with “/” and “/signup” endpoints declaratively with minimal boilerplate.

Key highlights:

  • Productive – Hot reloading, code generation, integrated debugging
  • Opinionated – Conventions to reduce repetitive code
  • Modular – Compose UI and business logic from reusable components
  • Full-stack – Unified foundations across frontend and backend code
  • Observability – Logging, metrics, distributed tracing built-in
  • Safety + Speed – Leverage Rust without compromising productivity

Spruce enables rapidly building web systems in Rust safely without sacrificing developer experience.

Let’s build a simple Spruce app next to experience it first-hand.

Building a Web App with Spruce

To get hands-on with these technologies, we’ll create a basic Spruce app for url shortening.

1. Install Rust and Spruce

Ensure Rust is installed from rustup.rs. Then install Spruce:

cargo install spruce

2. Generate Scaffolding

Run spruce init and choose fullstack:

$ spruce init 
? Select app type › fullstack

This generates starter code with two directories:

  • server – Backend Spruce service
  • ui – Frontend SvelteKit app

3. Implement Redirect API

In server/src/main.rs define an API endpoint:

use spruce::*;

#[api]
pub fn create_redirect(
  req: &HttpRequest,
  body: Json<CreateRedirect>,
) -> Result<HttpResponse, Error> {

  // Save redirect 

  let res = HttpResponse::Created();
  
  Ok(res)
}

#[derive(Deserialize)]
struct CreateRedirect {
  url: String
}

This deserializes the request body and will ultimately save and generate the short link.

4. Call API from Client

In ui/src/routes/+page.svelte call the API:

const res = await fetch('/api/redirect', {
  method: 'POST',
  body: { url: 'https://long-url.com' }
});

// Display shortened link

We can now send requests between the client and Rust backend!

5. Run Locally

Start the Spruce dev server:

cd server
cargo run

This starts the backend on port 5000. Next run the SvelteKit dev server:

cd ui
npm run dev

The fullstack app runs on localhost!

Conclusion

The SWC ecosystem paves an exciting path towards leveraging Rust’s benefits for productive and robust web development:

  • SWC Compiler – Improved transpilation of modern JavaScript/TypeScript
  • Substrate – Low-level web framework for Rust services
  • Spruce – High-level fullstack app framework for rapid development

Together they provide the missing pieces for unlocking Rust on the web.

While early stage, Rust and WebAssembly exhibit huge potential for use cases requiring performance, safety, and concurrency. SWC provides the platform for realizing that potential today.

Visit swc.rs to explore introducing Rust and WebAssembly into your web stack!

Frequently Asked Questions

How production-ready is using Rust for web development today?

SWC provides a solid foundation but ecosystem is still maturing. Exciting improvements underway.

What are some example use cases suited for Rust and WebAssembly vs JavaScript?

Highly parallel workloads, complex computations, video processing, 3D rendering all excel in Rust. General websites are fine in JS.

What is the learning curve for Rust coming from languages like JavaScript and Python?

Rust has steeper initial learning curve but pays off in more robust code and productivity. Lifetimes/borrow checker are main hurdles.

How can Rust be incrementally added to existing codebases?

SWC for transpilation, WASM modules for performance critical routines, API services to replace legacy systems. Lots of integration options.

Are there capabilities and ecosystems Rust still lacks compared to other languages?

Debugging, hot reloading, and editor integration still trail more mature languages but improving actively.

Leave a Reply

Your email address will not be published. Required fields are marked *