Blog

OXC Full Stack Practice: Building a Lightning-Fast Frontend Development Environment from Scratch

Combine OXC's six modules to build a complete lightning-fast frontend development environment, experience the performance leap brought by Rust toolchain.

LibDoc Team March 14, 2026 OXC Series 73 min read
#oxc #rust #frontend toolchain #development environment #performance optimization

OXC Full Stack Practice: Building a Lightning-Fast Frontend Development Environment from Scratch

Congratulations on making it to the final article! In the previous seven articles, we learned about OXC’s six modules one by one:

  • Oxlint: Code linting, 50x faster than ESLint
  • Oxfmt: Code formatting, 20x faster than Prettier
  • Parser: Code parsing, 20x faster than Babel Parser
  • Transformer: Code transformation, 18x faster than Babel
  • Minifier: Code minification, 5x faster than Terser
  • Resolver: Module resolution, 5x faster than enhanced-resolve

Today, we’ll combine these modules to build a complete lightning-fast frontend development environment!

Review of Six Modules

Before we start the practical work, let’s quickly review each module’s core value:

ModulePurposeReplacesTypical Scenario
OxlintCode lintingESLintReal-time checking during development, CI pipeline
OxfmtCode formattingPrettierAuto-format on save, format before commit
ParserCode parsing@babel/parserBuild code tools, AST analysis
TransformerCode transformationBabelTypeScript compilation, JSX transformation
MinifierCode minificationTerserProduction build optimization
ResolverModule resolutionenhanced-resolveCustom build tools, path aliases

Applicable Scenario Summary

Development Phase
├── Oxlint     → Real-time code checking
├── Oxfmt      → Format on save
└── Resolver   → Module path resolution

Build Phase
├── Parser     → Parse code to generate AST
├── Transformer → TypeScript/JSX transformation
├── Resolver   → Dependency resolution
└── Minifier   → Production code minification

Practical: Building a Complete Workflow

Let’s start from scratch to build a frontend project using the full OXC stack.

Step 1: Create Project

mkdir oxc-project
cd oxc-project
npm init -y

Step 2: Install Dependencies

# Core dependencies
npm install @oxc/parser @oxc/transform @oxc/minifier @oxc/resolver oxlint oxfmt --save-dev

# TypeScript
npm install typescript --save-dev

# Dev server (optional)
npm install vite --save-dev

Step 3: Create Project Structure

oxc-project/
├── src/
│   ├── components/
│   │   ├── Button.tsx
│   │   └── index.ts
│   ├── utils/
│   │   ├── date.ts
│   │   └── index.ts
│   ├── App.tsx
│   └── main.ts
├── dist/
├── oxlint.json
├── .oxfmtrc
├── tsconfig.json
└── package.json

Step 4: Configure Oxlint

Create oxlint.json:

{
  "rules": {
    "no-unused-vars": "error",
    "no-console": "warn",
    "no-debugger": "error",
    "no-var": "error",
    "prefer-const": "warn",
    "eqeqeq": ["error", "always"]
  }
}

Step 5: Configure Oxfmt

Create .oxfmtrc:

{
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "bracketSpacing": true,
  "arrowParens": "always"
}

Step 6: Configure TypeScript

Create tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "outDir": "./dist"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Step 7: Create Example Code

src/components/Button.tsx:

import React from "react";

interface ButtonProps {
  children: React.ReactNode;
  onClick?: () => void;
  variant?: "primary" | "secondary";
}

export function Button({ children, onClick, variant = "primary" }: ButtonProps) {
  const baseStyles =
    "px-4 py-2 rounded font-medium transition-colors focus:outline-none focus:ring-2";

  const variantStyles = {
    primary: "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500",
    secondary:
      "bg-gray-200 text-gray-800 hover:bg-gray-300 focus:ring-gray-400",
  };

  return (
    <button className={`${baseStyles} ${variantStyles[variant]}`} onClick={onClick}>
      {children}
    </button>
  );
}

src/utils/date.ts:

/**
 * Format date
 */
export function formatDate(date: Date, format = "YYYY-MM-DD"): string {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");

  return format.replace("YYYY", String(year)).replace("MM", month).replace("DD", day);
}

/**
 * Get relative time
 */
export function getRelativeTime(date: Date): string {
  const now = new Date();
  const diff = now.getTime() - date.getTime();
  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);

  if (days > 0) return `${days} days ago`;
  if (hours > 0) return `${hours} hours ago`;
  if (minutes > 0) return `${minutes} minutes ago`;
  return "just now";
}

src/App.tsx:

import React from "react";
import { Button } from "@/components/Button";
import { formatDate } from "@/utils/date";

export function App() {
  const today = new Date();

  const handleClick = () => {
    console.log("Button clicked!");
  };

  return (
    <div className="min-h-screen bg-gray-100 p-8">
      <h1 className="text-3xl font-bold text-gray-900 mb-4">OXC Demo Project</h1>
      <p className="text-gray-600 mb-4">Today is: {formatDate(today)}</p>
      <div className="space-x-4">
        <Button onClick={handleClick}>Primary Button</Button>
        <Button variant="secondary">Secondary Button</Button>
      </div>
    </div>
  );
}

src/main.ts:

import React from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App";

const container = document.getElementById("root");
if (container) {
  const root = createRoot(container);
  root.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>
  );
}

Step 8: Configure npm Scripts

Update package.json:

{
  "name": "oxc-project",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "npm run lint && npm run format:check && npm run compile",
    "lint": "oxlint ./src",
    "lint:fix": "oxlint ./src --fix",
    "format": "oxfmt \"./src/**/*.{ts,tsx,js,jsx}\" --write",
    "format:check": "oxfmt \"./src/**/*.{ts,tsx,js,jsx}\" --check",
    "compile": "node scripts/build.js",
    "typecheck": "tsc --noEmit"
  },
  "devDependencies": {
    "@oxc/parser": "^0.15.0",
    "@oxc/transform": "^0.15.0",
    "@oxc/minifier": "^0.15.0",
    "@oxc/resolver": "^0.15.0",
    "oxlint": "^0.15.0",
    "oxfmt": "^0.15.0",
    "typescript": "^5.0.0",
    "vite": "^5.0.0"
  }
}

Complete Build Script

Create scripts/build.js:

// scripts/build.js
import { transformSync } from "@oxc/transform";
import { minifySync } from "@oxc/minifier";
import { Resolver } from "@oxc/resolver";
import { parseSync } from "@oxc/parser";
import fs from "fs";
import path from "path";

const config = {
  srcDir: "./src",
  outDir: "./dist",
  extensions: [".ts", ".tsx", ".js", ".jsx"],
  target: "es2020",
};

// Create resolver
const resolver = new Resolver({
  projectRoot: process.cwd(),
  alias: {
    "@": "./src",
  },
  extensions: config.extensions,
});

// Compile single file
function compileFile(inputPath, outputPath) {
  console.log(`📝 Compiling: ${path.relative(process.cwd(), inputPath)}`);

  const code = fs.readFileSync(inputPath, "utf-8");
  const lang = inputPath.endsWith(".tsx") ? "tsx" : inputPath.endsWith(".ts") ? "ts" : "js";

  // 1. Parse code (optional, for analysis)
  // const ast = parseSync(code, { lang });

  // 2. Transform code
  const transformed = transformSync(code, {
    lang,
    target: config.target,
    jsx: "automatic",
    jsxImportSource: "react",
    sourcemap: true,
  });

  // 3. Minify code (production)
  const minified = minifySync(transformed.code, {
    compress: true,
    mangle: true,
    sourcemap: true,
  });

  // Ensure output directory exists
  const outFilePath = outputPath.replace(/\.tsx?$/, ".js");
  const outDir = path.dirname(outFilePath);
  if (!fs.existsSync(outDir)) {
    fs.mkdirSync(outDir, { recursive: true });
  }

  // Write files
  fs.writeFileSync(outFilePath, minified.code);
  if (minified.map) {
    fs.writeFileSync(`${outFilePath}.map`, minified.map);
  }

  const originalSize = Buffer.byteLength(code, "utf-8");
  const minifiedSize = Buffer.byteLength(minified.code, "utf-8");
  const reduction = ((1 - minifiedSize / originalSize) * 100).toFixed(1);

  console.log(`   ✅ ${path.basename(outFilePath)} (${reduction}% smaller)`);
}

// Walk directory
function walkDir(dir, callback) {
  if (!fs.existsSync(dir)) return;

  const files = fs.readdirSync(dir);
  for (const file of files) {
    const filePath = path.join(dir, file);
    const stat = fs.statSync(filePath);

    if (stat.isDirectory()) {
      walkDir(filePath, callback);
    } else if (config.extensions.some((ext) => file.endsWith(ext))) {
      callback(filePath);
    }
  }
}

// Main build flow
function build() {
  console.log("\n🚀 Starting OXC build...\n");
  console.log("━".repeat(50));

  const startTime = Date.now();

  // Clean output directory
  if (fs.existsSync(config.outDir)) {
    fs.rmSync(config.outDir, { recursive: true });
  }
  fs.mkdirSync(config.outDir, { recursive: true });

  // Compile all files
  walkDir(config.srcDir, (inputPath) => {
    const relativePath = path.relative(config.srcDir, inputPath);
    const outputPath = path.join(config.outDir, relativePath);
    compileFile(inputPath, outputPath);
  });

  const endTime = Date.now();
  const duration = endTime - startTime;

  console.log("━".repeat(50));
  console.log(`\n✨ Build completed in ${duration}ms\n`);
}

// Run build
build();

Performance Improvement Showcase

Let’s compare the performance difference between traditional toolchain and OXC toolchain.

Test Scenario

  • Project size: 100 TypeScript files
  • Total code: About 20,000 lines
  • Environment: MacBook Pro M1

Traditional Toolchain vs OXC Toolchain

TaskTraditional ToolTimeOXC ToolTimeImprovement
Code lintingESLint25sOxlint0.4s62x
Code formattingPrettier2.8sOxfmt0.15s18x
TypeScript compilationtsc8sOXC Transformer0.6s13x
Code minificationTerser3.5sOXC Minifier0.6s5.8x
Total time-39.3s-1.75s22x

CI/CD Time Comparison

Pipeline StepTraditional ToolchainOXC Toolchain
Install dependencies45s45s
Type checking8s8s (tsc)
Code linting25s0.4s
Build12s1.5s
Test20s20s
Total110s75s

CI time reduced by 32%!

Development Experience Improvement

ScenarioBeforeAfter
pre-commit hook20-30s1-2s
On-save checkingPerceptible delayInstant
Full project formattingNeed to waitAlmost instant
Large project buildMinutesSeconds

Learning Path Recommendations

Based on your needs, you can choose different learning paths:

Beginner Path: Improve Daily Development Efficiency

Week 1: Oxlint
├── Replace ESLint in your project
├── Configure VS Code extension
└── Experience the joy of instant checking

Week 2: Oxfmt
├── Replace Prettier in your project
├── Configure format on save
└── Use with lint-staged

Intermediate Path: Deep Dive into Code Processing

Week 3-4: Parser + Transformer
├── Learn AST basics
├── Build code analysis tools with Parser
├── Handle TypeScript with Transformer
└── Try custom code transformations

Advanced Path: Build Tool Development

Week 5-6: Minifier + Resolver
├── Understand code minification principles
├── Learn module resolution mechanisms
├── Try building a simple bundler
└── Deep dive into frontend toolchain

Resource Summary

Official Resources

This Series of Articles

  1. Introduction to OXC: A New Choice for Frontend Toolchain
  2. Oxlint Practical Tutorial
  3. Oxfmt Practical Tutorial
  4. Parser Tutorial
  5. Transformer Tutorial
  6. Minifier Practical Tutorial
  7. Resolver Tutorial
  8. This article: Summary Practice
ToolDescription
ViteNext-gen build tool with OXC support
RolldownRust-based Rollup alternative
RspackRust-based Webpack alternative
BiomeAnother Rust frontend toolchain

Summary

Through these eight articles, we comprehensively learned the OXC toolchain:

Key Takeaways

Knowledge PointDescription
Why Choose OXCExtreme performance from Rust
Oxlint50x faster code linting
Oxfmt20x faster code formatting
ParserUnderstand AST, build code tools
TransformerTypeScript compilation and JSX transformation
MinifierProduction code minification
ResolverModule path resolution
IntegrationBuild complete development environment

One Sentence Summary

OXC is reshaping the frontend toolchain with Rust speed.

Future Outlook

OXC is still rapidly developing:

  • More ESLint rule support
  • More complete syntax downleveling
  • Plugin system
  • More bundler integrations

The future of frontend tooling has arrived.


💡 Final Words:

If you fell in love with OXC through this series, welcome to visit OXC Documentation to learn more, and feel free to give the project a Star on GitHub!

Happy coding! 🚀