Skip to content

Qwik (Vite)

Setup for a standard Qwik + Vite project. Qwik uses class (not className) and has its own class$ reactive primitive — both go through the JSX transformer.

Quick start

bash
npm install -D tailwindcss-obfuscator
bash
pnpm add -D tailwindcss-obfuscator
bash
yarn add -D tailwindcss-obfuscator
bash
bun add -D tailwindcss-obfuscator
ts
// vite.config.ts
import { defineConfig } from "vite";
import { qwikVite } from "@builder.io/qwik/optimizer";
import tailwindcss from "@tailwindcss/vite";
import TailwindObfuscator from "tailwindcss-obfuscator/vite";

export default defineConfig({
  plugins: [qwikVite(), tailwindcss(), TailwindObfuscator({ prefix: "tw-" })],
});

Qwik City

For a full Qwik City app (the meta-framework), wire the obfuscator after qwikCity():

ts
// vite.config.ts
import { defineConfig } from "vite";
import { qwikCity } from "@builder.io/qwik-city/vite";
import { qwikVite } from "@builder.io/qwik/optimizer";
import tailwindcss from "@tailwindcss/vite";
import TailwindObfuscator from "tailwindcss-obfuscator/vite";

export default defineConfig({
  plugins: [qwikCity(), qwikVite(), tailwindcss(), TailwindObfuscator({ prefix: "tw-" })],
});

Qwik patterns the plugin handles

PatternStatus
<div class="flex items-center gap-2" />✅ Static string
<div class={["flex", "items-center"]} />✅ Array of strings
<div class={{ "bg-red-500": hasError.value }} />✅ Object syntax
<div class$={() => useSignal().value && "ring-2"} />✅ Reactive — string literals inside still obfuscated
<div class={\bg-${color}-500`} />`❌ Dynamic interpolation — kept as-is

TIP

class$() is Qwik's lazy reactive class binding (the $ suffix marks it as a serialised closure). The plugin reads the string literals inside the closure body at AST time and rewrites them; the reactivity at runtime is preserved.

Troubleshooting

Pre-rendered SSR output

Qwik produces server-rendered HTML at build time. If you see un-obfuscated classes in the rendered HTML, check that the plugin runs after qwikVite() and qwikCity() in the plugin array. Order matters because Qwik rewrites JSX into its own format first.

See also