DEV Community

Marek Jóźwiak
Marek Jóźwiak

Posted on

Why I Rewrote Nocta CLI in Rust (Even Though I Didn't Need To)

The Backstory

When I first built the Nocta UI CLI, it was a simple JavaScript tool — a few Node scripts that let developers initialize projects, install components, and sync their design tokens. It worked great, and honestly, it didn't need to change.

But like many dev experiments, this rewrite started with curiosity, not necessity.

I'd recently come across how packages like @openai/codex ship native Rust binaries inside an npm package — completely transparent to the end user. You install or run it via npx, and under the hood, you're actually executing optimized compiled code. That idea stuck with me.

Could I make Nocta CLI work the same way — still npm-first, but powered by Rust under the hood?

Turns out, yes.

Introducing the New Nocta CLI

The new CLI lives here:

You can still run it exactly like before:

npx @nocta-ui/cli init
npx @nocta-ui/cli add button card accordion
Enter fullscreen mode Exit fullscreen mode

But now, when you do, you're running native Rust binaries — distributed through npm and executed transparently via a lightweight JavaScript wrapper.

Why Rewrite Something That Worked Fine?

Honestly? Curiosity.

This rewrite wasn't driven by performance bottlenecks or bugs — it was driven by fascination. I wanted to explore what happens when you combine the ergonomics of npm with the performance and reliability of Rust.

And it turned out to be a surprisingly elegant setup.

Under the Hood

The project is now structured as a polyglot monorepo:

.
├── Cargo.lock
├── Cargo.toml
├── crates
│   ├── cli          # Handles commands like init, add, list
│   └── core         # Core logic: config, fs ops, registry, deps
├── js
│   ├── bin/nocta-ui.js   # Tiny Node wrapper around the native binary
│   └── package.json
└── package.json
Enter fullscreen mode Exit fullscreen mode

Here's what happens when you run npx @nocta-ui/cli init:

  1. Node wrapper runs → detects your platform
  2. Loads the right Rust binary → compiled for macOS, Linux, or Windows
  3. Executes native logic — all the heavy lifting (file ops, config parsing, dependency detection) is done in Rust

No crazy runtime setup, no dependencies — just a fast native executable doing its job.

What's New Under the Hood

The CLI still does everything you'd expect:

  • Initializes new projects
  • Detects frameworks like Next.js, Vite + React, Tanstack Start or React Router 7
  • Installs Tailwind v4 tokens
  • Scaffolds components with their dependencies
  • Integrates seamlessly with your existing package manager

But now it feels instant. Every command runs with near-zero startup time, thanks to Rust's compiled performance.

The Real Win: Simplicity in Distribution

What made this rewrite truly interesting wasn't the Rust code itself — it was how simple npm makes distributing native binaries once you step outside the "pure JS" mindset.

Each platform gets its own small binary, published alongside the npm package. The JavaScript layer just picks the right one and runs it. No users even notice the difference — except for the speed.

It's a hybrid model that feels… right.

Lessons Learned

  • Rust + npm is a surprisingly powerful combo.
  • Native performance can live inside your JS workflow without friction.
  • And most importantly: rewrites don't always need a reason — sometimes, they're just how we learn.

The Future

This rewrite won't change how developers use Nocta UI — it'll just make their CLI faster, more stable, and easier to maintain.

If you're curious about how native binaries and npm can coexist, check out the repo and peek under the hood:

👉 https://github.com/nocta-ui/nocta-ui-cli

And if you're already using Nocta UI, just keep running the same command:

npx @nocta-ui/cli init
Enter fullscreen mode Exit fullscreen mode

It's the same CLI you know — just rebuilt for fun, and made faster by Rust.

Top comments (0)