{"slug": "stop-wasting-llm-tokens-i-built-a-rust-cli-to-prune-js-ts-codebases-by-80", "title": "Stop Wasting LLM Tokens! I Built a Rust CLI to Prune JS/TS Codebases by 80% 🦀🚀", "summary": "A developer built urai-ecma, a multi-threaded Rust CLI that uses SWC to parse JavaScript and TypeScript into ASTs and semantically prune codebases before feeding them to LLMs. The tool reportedly compresses a 209,757-token codebase to roughly 36,000 tokens, an 82.7% reduction, addressing attention degradation, KV-cache prefill lag, and rate-limit throttling in agentic coding workflows.", "body_md": "\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                       THE \"INFINITE CONTEXT\" TRAP                           │\n├──────────────────────────────┬──────────────────────────────────────────────┤\n│ 1. Attention Degradation     │ Lost-in-the-Middle: critical interfaces get  │\n│                              │ buried under repetitive DOM noise and loops. │\n├──────────────────────────────┼──────────────────────────────────────────────┤\n│ 2. KV-Cache Prefill Lag      │ Time-to-First-Token (TTFT) scales with prompt│\n│                              │ size; 150k+ raw tokens stall your agent.     │\n├──────────────────────────────┼──────────────────────────────────────────────┤\n│ 3. The \"Tailwind Tax\"        │ Paying frontier API rates to ingest 80-char  │\n│                              │ strings like \"flex items-center justify-...\" │\n├──────────────────────────────┼──────────────────────────────────────────────┤\n│ 4. Rate-Limit Throttling     │ Bloated prompts quickly exhaust TPM (Tokens  │\n│                              │ Per Minute) quotas in CI/CD pipelines.       │\n└──────────────────────────────┴──────────────────────────────────────────────┘\n```\n\nHave you ever dumped an entire React or Next.js repository into Claude 3.5 Sonnet, GPT-4o, or a local Ollama model to ask:\n\n*\"How does authentication state flow through my UI, and what endpoints handle it?\"*\n\nIf you inspect the prompt you sent, **over 70% of the tokens are dead weight**:\n\n`className=\"flex flex-col items-center justify-between p-8 bg-white dark:bg-zinc-950 rounded-2xl shadow-xl...\"`).\nWhile building an agentic Chrome extension powered by local LLMs, my context window collapsed: **209,757 tokens per scan**. Responses took forever, local inference crawled, and the model routinely hallucinated core functions because key architectural interfaces were buried under syntactic noise.\n\nI built [**`urai-ecma`**](https://sanjaiyan-dev.github.io/urai-ecma): a multi-threaded CLI tool written in **Rust** that uses **SWC (Speedy Web Compiler)** to parse JavaScript and TypeScript into Abstract Syntax Trees (AST). Instead of blindly concatenating files together like a text scraper, it acts as a semantic compiler for prompt engineering—compressing that same **209k token codebase down to 36k tokens (an 82.7% reduction) in milliseconds**.\n\nHere is how it works, how it is architected under the hood, real benchmarks, and the engineering trade-offs you should know before using it.\n\nIn classical Tamil literary heritage, monumental masterworks like the *Thirukkuṛaḷ* (திருக்குறள்) and *Tolkāppiyam* (தொல்காப்பியம்) contained dense, multi-layered philosophical thought. To make these works practical without destroying their architectural depth, classical scholars practiced **உரை எழுதுதல் (*Urai Ezhuthudhal*)**.\n\nMaster commentators (*Uraiyāsiriyars*) like **Parimelazhagar** and **Ilampuranar** did not just copy or mechanically summarize texts. They performed **structural distillation**:\n\nModern enterprise JavaScript and TypeScript codebases are the epic literatures of software engineering. When asking an LLM to reason about your code, it doesn't need raw syntactic exhaustion—it needs the structural anatomy, API contracts, state flows, and component signatures.\n\n`urai-ecma` acts as a modern *Uraiyāsiriyar* for your codebase.\n\nTools like `repomix`, `gitingest`, and `code2prompt` are file dumpers. They walk your directory, wrap raw text in XML/Markdown fences, and pass every single line of styling directly into your model's context.\n\n`urai-ecma` is an **AST-aware compiler engine**. Rather than treating code as raw strings, it parses your source into concrete syntax trees using ByteDance/Vercel’s `swc_ecma` engine and applies deterministic, semantic transformations:\n\n```\n┌─────────────────────────────────────────────────────────────────────────┐\n│                     URAI COMPILER PIPELINE                              │\n└─────────────────────────────────────────────────────────────────────────┘\n   Enterprise Monorepo (.ts, .tsx, .js, .mjs, .json)\n                          │\n                          ▼\n            [ignore::WalkBuilder (Rust)]\n         Honor .gitignore, prune node_modules & dist\n                          │\n                          ▼\n             [Rayon Parallel Work-Stealing]\n        Multi-threaded AST parsing across all CPU cores\n                          │\n          ┌───────────────┴───────────────┐\n          ▼                               ▼\n [swc_ecma_parser]               [swc_ecma_parser]\n  Worker Thread A                 Worker Thread B\n          │                               │\n          ├─► [RouteVisitor]              ├─► [RouteVisitor]\n          │   Next.js/Express/NestJS      │   Next.js/Express/NestJS\n          │                               │\n          ├─► [ReactComponentAnalyzer]    ├─► [ReactComponentAnalyzer]\n          │   Props, State, Hooks, JSX    │   Props, State, Hooks, JSX\n          │                               │\n          ├─► [ReactJsxPruner]            ├─► [ReactJsxPruner]\n          │   Tailwind static class strip │   Tailwind static class strip\n          │                               │\n          └─► [FunctionSummarizerVisitor] └─► [FunctionSummarizerVisitor]\n              Preserve structural stubs       Preserve structural stubs\n                          │\n                          ▼\n         [Foyer Hybrid Cache (Disk + RAM)]\n              Sha512_256 + Zstd compression\n                          │\n                          ▼\n         [swc_ecma_codegen + Tiktoken Engine]\n   Emits high-density Markdown prompt + BPE o200k report\n```\n\n`is_structural_stub_stmt`)\nTraditional minification forces a bad compromise: either include full function bodies (wasting thousands of tokens on loops and math) or strip functions down to empty signatures (which deletes hooks, event listeners, and JSX layouts).\n\n`urai-ecma` solves this through **Structural Stubbing**. It inspects AST statements and retains only nodes critical to architectural comprehension:\n\n```\n// Only statements defining component anatomy are preserved:\nfn is_structural_stub_stmt(stmt: &Stmt) -> bool {\n    match stmt {\n        Stmt::Decl(Decl::Fn(_)) => true, // Nested helper declarations\n\n        Stmt::Decl(Decl::Var(var_decl)) => var_decl.decls.iter().any(|decl| {\n            if let Some(init) = &decl.init {\n                matches!(**init, Expr::Arrow(_) | Expr::Fn(_))\n            } else {\n                false\n            }\n        }),\n\n        Stmt::Expr(expr_stmt) => {\n            if let Expr::Call(call_expr) = &*expr_stmt.expr\n                && let Callee::Expr(callee_expr) = &call_expr.callee\n                && let Expr::Ident(ident) = &**callee_expr\n            {\n                let name = ident.sym.as_ref();\n                // Preserves React Hooks, lifecycle timers, and global listeners:\n                return name.starts_with(\"use\")\n                    || name == \"setTimeout\"\n                    || name == \"setInterval\"\n                    || name.contains(\"addEventListener\")\n                    || name.contains(\"requestIdleCallback\");\n            }\n            false\n        }\n\n        Stmt::Return(ret_stmt) => {\n            // Preserves JSX layout hierarchies:\n            if let Some(arg) = &ret_stmt.arg {\n                matches!(\n                    &**arg,\n                    Expr::JSXElement(_) | Expr::JSXFragment(_) | Expr::Paren(_)\n                )\n            } else {\n                false\n            }\n        }\n\n        _ => false, // Computational loops, arithmetic, & validations are pruned\n    }\n}\n```\n\n`useEffect(() => { ... }, [dep])` remains intact, signaling side-effects to the LLM.\nModern utility CSS accounts for massive token bloat. `urai-ecma` provides 4 modes (`remove`, `remove_aggr`, `summarize`, `preserve`):\n\n`className={clsx(\"btn\", isActive && \"btn-active\")}` or ternary conditions, `/* UI: Frosted glass card with dark mode */`).\nSummarizing every single function with an LLM is slow. `urai-ecma` uses a **two-tier resolution strategy**:\n\n`@description`, `@param`, `@return`) already exist. It even includes a proximity-scan fallback (within a 300-byte span) to associate detached comments. This takes `gemma4`, `llama3.2`). `foyer` crate (64MB direct RAM buffer + 128MB Zstd-compressed disk storage with `Sha512_256` keys).\nLook at what happens to a bloated React component when passed through `urai-ecma`:\n\n``` js\nconst ErrorUI = ({\n    headerDescTxt = \"The real-time telemetry pipeline requires runtime binding. Ensure this window resides in a Chrome extension popup configured with permission parameters.\",\n    copyTextCommand = 'OLLAMA_ORIGINS=\"*\" ollama serve',\n    copyTagTxt = \"MV3\",\n    copyHeaderTxt = \"Manifest Interface Schema\",\n    copiedButtonTxt = \"Copied Configuration\",\n    copyButtonTxt = \"Copy Permission Manifest\",\n}) => {\n    const [copyState, setCopyState] = useState(false);\n\n    const handleCopyManifest = () => {\n        navigator.clipboard.writeText(copyTextCommand);\n        setCopyState(true);\n        setTimeout(() => setCopyState(false), 2000);\n    };\n\n    const copyButtonTxtNode = copyState ? copiedButtonTxt : copyButtonTxt;\n    return (\n        <div className=\"relative min-h-screen w-full bg-[#05050A] border border-white/10 overflow-hidden p-6 text-[#F8FAFC] flex flex-col justify-between\">\n            <div className=\"absolute top-[-10%] left-[-10%] w-45 h-45 rounded-full bg-[#FF2E63] opacity-20 blur-[64px] pointer-events-none\" />\n            <div className=\"space-y-6\">\n                <div className=\"flex items-center space-x-3\">\n                    <div className=\"w-2.5 h-2.5 rounded-full bg-[#FF2E63] animate-pulse shadow-[0_0_8px_#FF2E63]\" />\n                    <span className=\"text-[10px] font-mono tracking-widest text-[#FF2E63] uppercase font-bold\">\n                        Diagnostics Status: Telemetry Offline\n                    </span>\n                </div>\n                <div className=\"bg-white/[0.03] border border-white/[0.08] rounded-2xl p-4 space-y-3\">\n                    <button className={`text-[9px] font-mono px-2 py-1 rounded-md transition-all bg-[#8B5CF6] text-white`}>\n                        {copyTagTxt}\n                    </button>\n                    <motion.button onClick={handleCopyManifest} className=\"w-full py-2 bg-white/[0.06] hover:bg-white/[0.1] border border-white/10 text-xs font-mono font-medium rounded-xl flex items-center justify-center space-x-2 text-white\">\n                        <span>{copyButtonTxtNode}</span>\n                    </motion.button>\n                </div>\n            </div>\n        </div>\n    );\n};\n```\n\n`urai-ecma` (After)\n\n```\n### React Component Breakdown: `<ErrorUI>` \n\n- **Props**:\n  - `headerDescTxt` (type: `any`) [optional]\n  - `copyTextCommand` (type: `any`) [optional]\n  - `copyTagTxt` (type: `any`) [optional]\n  - `copyHeaderTxt` (type: `any`) [optional]\n  - `copiedButtonTxt` (type: `any`) [optional]\n  - `copyButtonTxt` (type: `any`) [optional]\n- **State Management**:\n  - Manages state `copyState` via setter `setCopyState`.\n- **Hooks**: Uses `useState` (Total Side-Effects: 0).\n- **Rendered JSX Tree**: `<div>, <span>, <h1>, <p>, <button>, <motion.button>`\njs\nconst ErrorUI = ({ headerDescTxt = \"...\", copyTextCommand = \"...\", copyTagTxt = \"MV3\", copyHeaderTxt = \"...\", copiedButtonTxt = \"...\", copyButtonTxt = \"...\" })=>{\n    const handleCopyManifest = ()=>{\n        setTimeout(()=>setCopyState(false), 2000);\n        '/* \"Copies the manifesto text to the clipboard and sets a temporary success state for two seconds.\" */';\n    };\n    return (\n        <div className=\"/* UI: Full-screen dark mode layout with border and text overflow management */\">\n            <div className=\"/* UI: Absolute background blur element positioned outside the main container */\"/>\n            <div>\n                <span>Diagnostics Status: Telemetry Offline</span>\n                <div>\n                    <button className={`text-[9px] font-mono px-2 py-1 rounded-md transition-all bg-[#8B5CF6] text-white`}>\n                        {copyTagTxt}\n                    </button>\n                    <motion.button onClick={handleCopyManifest}>\n                        <span>{copyButtonTxtNode}</span>\n                    </motion.button>\n                </div>\n            </div>\n        </div>\n    );\n    '/* \"Presents a user interface displaying diagnostic status and provides a copy function for a necessary runtime binding command.\" */';\n};\n```\n\nNotice what happened:\n\n`` `text-[9px] ... ${...}` `` were left untouched.\nWe benchmarked `urai-ecma` on an Apple Silicon machine across different workloads using OpenAI’s native `o200k_base` BPE tokenizer:\n\n| Metric | Raw Project (TS/TSX) | `urai-ecma` Output | Total Reduction | \n|---|---|---|---|\n| **Token Volume (`o200k_base`)** | **209,757 tokens** | **36,153 tokens** | **-82.76%** 🚀 | \n| **Downstream LLM Context** | Exceeds local 64k limits | Fits easily in local Ollama | **Usable on 8GB VRAM** | \n| **KV-Cache TTFT (Time-to-First-Token)** | ~18.4 seconds | ~1.9 seconds | **~9.6x Faster** | \n\n`plugin-api-docgen`) — Cold vs. Warm Performance\nHere are the terminal runs comparing an initial cold run (querying local Ollama) against subsequent warm runs (hitting the `foyer` hybrid cache):\n\n``` bash\n# RUN 1: Cold Execution (AST Parsing + Local Ollama Inference)\n$ time urai-ecma\n🚀 [urai-ecma] Starting AST Analysis on project: ./src\n🔍 Found 6 source file(s) for analysis.\n✅ [urai-ecma] Prompt successfully generated at: ./output.md\n📊 [urai-ecma] Estimated Tokens in ./output.md: 1317 tokens\n============================================================\n📊 TOKEN SAVINGS & OPTIMIZATION REPORT\n============================================================\n📁 Raw Source Code (All JS/TS):       3023 tokens\n⚡ Optimized Output (output.md):      1317 tokens\n------------------------------------------------------------\n🎉 Reduction: -56.43% tokens saved! (Saved ~1706 tokens)\n============================================================\nurai-ecma  0.06s user 0.04s system 0% cpu 21.541 total\nbash\n# RUN 2: Warm Execution (AST Parsing + Foyer Hybrid Cache Hits)\n$ time urai-ecma\n🚀 [urai-ecma] Starting AST Analysis on project: ./src\n🔍 Found 6 source file(s) for analysis.\n✅ [urai-ecma] Prompt successfully generated at: ./output.md\n📊 [urai-ecma] Estimated Tokens in ./output.md: 1299 tokens\n============================================================\n📊 TOKEN SAVINGS & OPTIMIZATION REPORT\n============================================================\n📁 Raw Source Code (All JS/TS):       3023 tokens\n⚡ Optimized Output (output.md):      1299 tokens\n------------------------------------------------------------\n🎉 Reduction: -57.03% tokens saved! (Saved ~1724 tokens)\n============================================================\nurai-ecma  0.03s user 0.01s system 92% cpu 0.049 total\nExecution Latency Comparison (plugin-api-docgen)\n──────────────────────────────────────────────────────────────────\nCold Run (Ollama Local Inference):  ████████████████████ 21.541s\nWarm Run (Foyer Zstd Cache):        ▍ 0.049s (49ms)\n──────────────────────────────────────────────────────────────────\nSpeedup Factor: ~439x Faster on Cache Hit!\n```\n\n| Feature | `repomix` /`gitingest` | `code2prompt` | `urai-ecma` | \n|---|---|---|---|\n| **Engine** | Node.js / Python | Rust | **Rust (SWC + Rayon)** | \n| **Parsing Strategy** | Naive String Concatenation | Handlebars Templates | **True AST Traversal** | \n| **Tailwind Handling** | Preserves all noise (0% saved) | Preserves all noise (0% saved) | **4-Mode AST Pruning** | \n| **Structural Stubbing** | ❌ No | ❌ No | **✅ Yes (`is_structural_stub`)** | \n| **API Route Tables** | ❌ No | ❌ No | **✅ Auto-extracted (Next/Nest/Express)** | \n| **Component Analysis** | ❌ No | ❌ No | **✅ Props, State, Hooks, JSX tree** | \n| **Privacy / Offline** | Dependent on API | Offline string copy | **100% Offline (Local Ollama/JSDoc)** | \n| **Token Savings** | 0% (Expands token size) | 0% | **Up to 82.7% reduction** | \n\nNo tool is a silver bullet. Because `urai-ecma` prunes function internals into architectural stubs, you need to understand when to use it and when to skip it:\n\n`urai-ecma` is distributed as a single static binary with zero runtime dependencies.\n\n```\ncurl --proto '=https' --tlsv1.2 -LsSf https://github.com/sanjaiyan-dev/urai-ecma/releases/download/v0.1.1/urai-ecma-installer.sh | sh\npowershell -ExecutionPolicy Bypass -c \"irm https://github.com/sanjaiyan-dev/urai-ecma/releases/download/v0.1.1/urai-ecma-installer.ps1 | iex\"\nnpm install -g urai-ecma\n# or: pnpm add -g urai-ecma | bun add -g urai-ecma | deno add -g npm:urai-ecma\ncargo install urai-ecma\n```\n\nInitialize a documented configuration file in your project root:\n\n```\nurai-ecma create\n```\n\nThis creates `urai.config.jsonc`. Because `urai-ecma` is registered globally with **SchemaStore**, you get instant auto-complete and documentation in **VS Code, WebStorm, IntelliJ, and Visual Studio**:\n\n```\n{\n    \"$schema\": \"https://www.schemastore.org/urai-ecma.json\",\n    // Source directory or file to analyze\n    \"input_project\": \"./src\",\n\n    // Target markdown prompt output\n    \"output_file\": \"./output.md\",\n\n    // Local Ollama instance (Optional)\n    \"ollama_endpoint\": \"http://localhost:11434\",\n    \"ollama_modelname\": \"gemma4\",\n\n    // Tailwind CSS mode: \"remove\" | \"remove_aggr\" | \"summarize\" | \"preserve\"\n    \"tailwind_mode\": \"remove\",\n    \"tailwind_threshold\": 96,\n\n    // Summarize function bodies via JSDoc or Ollama\n    \"summarize_functions\": true,\n    \"summarize_functions_threshold\": 5,\n\n    // Extract Express / Fastify / Next.js / NestJS routes\n    \"generate_route_table\": true,\n\n    // React component introspection (Props, State, Hooks)\n    \"analyze_react_components\": true,\n\n    // Generate ASCII tree & Mermaid ESM dependency graph\n    \"generate_file_graph\": true\n}\n```\n\nRun analysis anywhere:\n\n```\n# Run with configuration file\nurai-ecma\n\n# Or run ad-hoc via CLI flags\nurai-ecma -i ./src -o prompt.md --tailwind-mode remove\n```\n\n`llms.txt`)\n*Transform bloated JavaScript & TypeScript repositories into hyper-dense, token-optimized context prompts.*\n\nIn classical Tamil literary heritage, monumental epics and ancient treatises—such as the *Thirukkuṛaḷ*, *Tolkāppiyam*, and *Cilappatikāram*—span vast volumes of dense, poetic, and complex thought. To make these monumental texts intelligible without losing their depth, classical scholars (*Uraiyāsiriyars*) practiced **உரை எழுதுதல் (*Urai Ezhuthudhal*)**: the disciplined art of writing a lucid, structured, and insightful commentary that distills the core essence, syntax, and architectural meaning of vast literature.\n\nToday, enterprise JavaScript and TypeScript codebases are the **epic literatures of modern software**. Spanning thousands of files across Next.js, React, Node.js, and TypeScript, they are laden with boilerplate, repetitive utility classes, and nested syntax.\n\nWhen feeding these systems to Large Language Models:\n\nIf you're sick of burning through API credits and watching your AI coding agents drown in static CSS strings, give `urai-ecma` a spin on your project. Drop your before-and-after token savings in the comments below!", "url": "https://wpnews.pro/news/stop-wasting-llm-tokens-i-built-a-rust-cli-to-prune-js-ts-codebases-by-80", "canonical_source": "https://dev.to/sanjaiyan_dev/stop-wasting-llm-tokens-i-built-a-rust-cli-to-prune-jsts-codebases-by-80-3i2e", "published_at": "2026-09-12 21:16:05+00:00", "updated_at": "2026-09-12 21:23:52.542100+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "large-language-models", "ai-agents", "ai-infrastructure"], "entities": ["urai-ecma", "Rust", "SWC", "JavaScript", "TypeScript", "Claude 3.5 Sonnet", "GPT-4o", "Ollama"], "alternates": {"html": "https://wpnews.pro/news/stop-wasting-llm-tokens-i-built-a-rust-cli-to-prune-js-ts-codebases-by-80", "markdown": "https://wpnews.pro/news/stop-wasting-llm-tokens-i-built-a-rust-cli-to-prune-js-ts-codebases-by-80.md", "text": "https://wpnews.pro/news/stop-wasting-llm-tokens-i-built-a-rust-cli-to-prune-js-ts-codebases-by-80.txt", "jsonld": "https://wpnews.pro/news/stop-wasting-llm-tokens-i-built-a-rust-cli-to-prune-js-ts-codebases-by-80.jsonld"}}