<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: novaai0401-ui</title>
    <description>The latest articles on DEV Community by novaai0401-ui (@novaai0401ui).</description>
    <link>https://dev.to/novaai0401ui</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3900818%2F80af2436-b2d6-4f8e-af1a-f0edc80b925b.png</url>
      <title>DEV Community: novaai0401-ui</title>
      <link>https://dev.to/novaai0401ui</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/novaai0401ui"/>
    <language>en</language>
    <item>
      <title>I built a React UI library to replace Puppeteer, MUI, and react-image-crop in one install</title>
      <dc:creator>novaai0401-ui</dc:creator>
      <pubDate>Mon, 27 Apr 2026 16:23:59 +0000</pubDate>
      <link>https://dev.to/novaai0401ui/i-built-a-react-ui-library-to-replace-puppeteer-mui-and-react-image-crop-in-one-install-1832</link>
      <guid>https://dev.to/novaai0401ui/i-built-a-react-ui-library-to-replace-puppeteer-mui-and-react-image-crop-in-one-install-1832</guid>
      <description>&lt;p&gt;A year ago I was rebuilding the same &lt;code&gt;&amp;lt;PhoneInput&amp;gt;&lt;/code&gt; for the third time across three different projects. Each time I reached for &lt;code&gt;react-phone-number-input&lt;/code&gt; (45 KB), wired it to a form, gave up on its accessibility, then wrapped my own thing on top.&lt;/p&gt;

&lt;p&gt;Same story for the photo cropper (&lt;code&gt;react-image-crop&lt;/code&gt;), the i18n stack (&lt;code&gt;i18next&lt;/code&gt; + &lt;code&gt;react-intl&lt;/code&gt;), the date picker, the autocomplete, the captcha, the watermark — and then the truly painful one: rendering the same React tree to both the browser &lt;strong&gt;and&lt;/strong&gt; a downloaded PDF, which usually means spinning up a Puppeteer worker on a separate Lambda because Chromium is 200 MB.&lt;/p&gt;

&lt;p&gt;So I stopped. Today there are &lt;strong&gt;11 npm packages&lt;/strong&gt; under the &lt;code&gt;tekivex-*&lt;/code&gt; family that try to make every one of those decisions for you, with one consistent design system, one accessibility floor (WCAG 2.1 AAA), and zero runtime dependencies in the core.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;tekivex-ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This article is the "should I actually use this?" version — what's in it, the trade-offs, and what it does that nothing else does.&lt;/p&gt;

&lt;h2&gt;
  
  
  The product shipment
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Thing you'd normally install&lt;/th&gt;
&lt;th&gt;What ships in tekivex-ui&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@mui/material&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;tekivex-ui&lt;/code&gt; (99 components)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;@react-pdf/renderer&lt;/code&gt; + Puppeteer&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;tekivex-pdf&lt;/code&gt; (one package, no Chromium)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;react-phone-number-input&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;TkxPhoneInput&lt;/code&gt; (built-in, E.164, 50 countries)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;react-image-crop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TkxImageEditor&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;react-i18next&lt;/code&gt; + locale files&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;I18nProvider&lt;/code&gt; + 35 locales&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;react-hot-toast&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;TkxToast&lt;/code&gt; + &lt;code&gt;ToastProvider&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;react-confetti&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;TkxConfetti&lt;/code&gt; (RAF, prefers-reduced-motion)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;react-signature-canvas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TkxSignaturePad&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;react-dropzone&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;TkxFileUpload&lt;/code&gt; (magic-byte MIME check)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;dompurify&lt;/code&gt; + custom sanitisers&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tekivex-security-core&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare Turnstile / hCaptcha wrapper&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TkxCaptcha&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;eslint-plugin-jsx-a11y&lt;/code&gt; extras&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;tekivex-audit&lt;/code&gt; (CLI)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;11 packages, all unscoped, all MIT, all under &lt;code&gt;tekivex-*&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tekivex-ui              v3.0.3   main library — 99 components, 1034 tests
tekivex-pdf             v0.1.1   React → PDF without a headless browser
tekivex-templates       v0.1.1   7 ready-made PDF layouts
tekivex-form            v0.1.0   slim form-only re-export (24 inputs)
tekivex-india           v0.1.1   Aadhaar, PAN, KYC, Tithi, INR lakh/crore
tekivex-finance         v0.1.1   payments, OTP, statements
tekivex-content         v0.1.1   signature, markdown, watermark, SEO
tekivex-security-core   v0.1.1   framework-agnostic security kernel
tekivex-audit           v0.1.1   static-analysis CLI
create-tekivex-app      v0.1.1   project scaffolder
tekivex-add             v0.1.0   shadcn-style component copier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the parts that are actually different.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. React → PDF without Puppeteer
&lt;/h2&gt;

&lt;p&gt;This is the v3.0 headline. Most "render React to PDF" stories end the same way: spin up a worker on Lambda or Railway, install &lt;code&gt;puppeteer-core&lt;/code&gt;, fight a 200 MB Chromium binary, eat 2–4 second cold starts, watch your bill creep up.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tekivex-pdf&lt;/code&gt; is a thin opinionated layer over &lt;code&gt;@react-pdf/renderer&lt;/code&gt; (1 MB, pure JS) that gives you the same component philosophy as &lt;code&gt;tekivex-ui&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;TkxPDFDocument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TkxPDFPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TkxPDFRow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TkxPDFColumn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TkxPDFText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TkxPDFImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TkxPDFWatermark&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;renderToPDF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tekivex-pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Biodata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sessionId&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFDocument&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFPage&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"A4"&lt;/span&gt; &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFWatermark&lt;/span&gt;
        &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`PREVIEW · &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tiled"&lt;/span&gt;
        &lt;span class="na"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mf"&gt;0.07&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFRow&lt;/span&gt; &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFColumn&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFText&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFText&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFText&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"muted"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtitle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFText&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFColumn&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFColumn&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFImage&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFColumn&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFRow&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFPage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxPDFDocument&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Server-side&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;renderToPDF&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Biodata&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"abc123"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// → 1.6–3 KB Node Buffer with `%PDF-` magic bytes, ready to write or stream&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Puppeteer&lt;/th&gt;
&lt;th&gt;tekivex-pdf&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cold start&lt;/td&gt;
&lt;td&gt;2–4 s&lt;/td&gt;
&lt;td&gt;~50 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bundle size&lt;/td&gt;
&lt;td&gt;200 MB&lt;/td&gt;
&lt;td&gt;&amp;lt; 2 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAM per render&lt;/td&gt;
&lt;td&gt;100–200 MB&lt;/td&gt;
&lt;td&gt;~10 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vercel serverless?&lt;/td&gt;
&lt;td&gt;❌ exceeds limit&lt;/td&gt;
&lt;td&gt;✅ fits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same React tree as browser?&lt;/td&gt;
&lt;td&gt;Different &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; rendering&lt;/td&gt;
&lt;td&gt;Same component philosophy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What it gives you for free:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;7 templates that work out of the box: &lt;strong&gt;Biodata, Invoice, Certificate, Resume, Ticket, BoardingPass, Receipt&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Diagonal tiled watermarks&lt;/li&gt;
&lt;li&gt;Indic font registration helpers (Devanagari, Tamil, Telugu, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;renderToPNG()&lt;/code&gt; for image output (via Sharp, optional peer dep)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the tradeoff: &lt;code&gt;@react-pdf/renderer&lt;/code&gt; supports a &lt;em&gt;subset&lt;/em&gt; of CSS (flexbox-style layout, no &lt;code&gt;position: absolute&lt;/code&gt; quirks, limited transforms). For structured documents (invoices, certificates, biodata, resumes), this is fine. For pixel-perfect screenshots of arbitrary web pages, &lt;strong&gt;keep Puppeteer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I wrote a smoke test that proves the API actually works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;node packages/tekivex-pdf/smoke-test.mjs

Running: renderToPDF produces a buffer starting with %PDF- magic
  ✓ PDF buffer: 1623 bytes, &lt;span class="nv"&gt;magic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%PDF-"&lt;/span&gt;
Running: Row/Column/View/Text compose without error
  ✓ Composed Row/Column doc: 1833 bytes
Running: TkxPDFWatermark adds tiled overlay
  ✓ Watermarked PDF: 2444 bytes
Running: BiodataTemplate renders to a valid PDF
  ✓ BiodataTemplate: 2962 bytes
Running: InvoiceTemplate renders to a valid PDF
  ✓ InvoiceTemplate: 3149 bytes

✓ All 5 smoke tests passed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5/5 pass. Real PDFs that Acrobat opens.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. WCAG 2.1 AAA across all 99 components — not AA
&lt;/h2&gt;

&lt;p&gt;Most React UI libraries aim for AA. AAA is genuinely rare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AA&lt;/strong&gt; = 4.5:1 contrast for normal text, 3:1 for large&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AAA&lt;/strong&gt; = 7:1 for normal text, 4.5:1 for large&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That difference matters for &lt;strong&gt;vision-impaired users&lt;/strong&gt;, &lt;strong&gt;older users on cheap LCD screens&lt;/strong&gt;, and &lt;strong&gt;anyone reading on a phone outdoors&lt;/strong&gt;. Most "accessible" libraries fail the contrast test on at least one variant (usually the secondary buttons, the muted text, or the disabled state).&lt;/p&gt;

&lt;p&gt;What I had to do to get AAA:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Computed contrast ratios programmatically for every text/background pair across every variant × every theme — flagged any pair &amp;lt; 7:1 with an automated test&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;44×44 minimum touch targets&lt;/strong&gt; on &lt;code&gt;size="md"&lt;/code&gt; and above (older parents in Tier-2/3 India filling biodata forms — that's the user)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:focus-visible&lt;/code&gt; outline at 2px on every interactive element, configurable per theme&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prefers-reduced-motion&lt;/code&gt; respected — slides become fades, confetti renders nothing, autoplay carousels pause&lt;/li&gt;
&lt;li&gt;Real screen-reader testing on &lt;strong&gt;NVDA + JAWS + VoiceOver iOS + TalkBack Android&lt;/strong&gt; — published as a 470-cell matrix (88% pass rate documented honestly, the failures are listed)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Not a marketing claim — it's a CI gate. &lt;code&gt;npm run a11y:audit&lt;/code&gt; runs axe-core against all 99 components on every PR. Drops below the threshold and the build fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Built-in security kernel — every prop sanitised
&lt;/h2&gt;

&lt;p&gt;The xz/Bitwarden/Shai-Hulud npm worm wave of 2025 made supply-chain a board-level concern. Every dep you add is a CVE you'll triage one day at 2 AM.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tekivex-ui&lt;/code&gt; ships with &lt;strong&gt;zero runtime dependencies&lt;/strong&gt;. Not "few" — zero. &lt;code&gt;npm install tekivex-ui&lt;/code&gt; adds exactly one folder to your &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But more interesting: every prop that touches a DOM-dangerous surface is sanitised at the boundary. The same kernel ships as a standalone package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;tekivex-security-core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;sanitizeHref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// blocks javascript:, data:, vbscript: schemes&lt;/span&gt;
  &lt;span class="nx"&gt;sanitizeUnicode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// CVE-2021-42574 Trojan Source defense&lt;/span&gt;
  &lt;span class="nx"&gt;scrubPII&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="c1"&gt;// redact email/phone/SSN/credit-card from logs&lt;/span&gt;
  &lt;span class="nx"&gt;buildTkxCSP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// construct a strict Content-Security-Policy&lt;/span&gt;
  &lt;span class="nx"&gt;installTrustedTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// browser-side DOM-XSS guard&lt;/span&gt;
  &lt;span class="nx"&gt;isFramed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;installFrameBuster&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// clickjacking defense&lt;/span&gt;
  &lt;span class="nx"&gt;createRateLimiter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// token-bucket, prevent brute-force on form submit&lt;/span&gt;
  &lt;span class="nx"&gt;deepFreeze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// prototype-pollution defense&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tekivex-security-core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// One-line strict CSP for your &amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;csp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildTkxCSP&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;r4nd0m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;strict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// → "default-src 'self'; frame-ancestors 'none'; ..."&lt;/span&gt;

&lt;span class="c1"&gt;// Sanitize untrusted URLs before &amp;lt;a href&amp;gt;&lt;/span&gt;
&lt;span class="nf"&gt;sanitizeHref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;javascript:alert(1)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// → null&lt;/span&gt;
&lt;span class="nf"&gt;sanitizeHref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// → 'https://example.com'&lt;/span&gt;

&lt;span class="c1"&gt;// Strip Unicode bidi-override attacks (the GitHub/Rust 2021 CVE)&lt;/span&gt;
&lt;span class="nf"&gt;sanitizeUnicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;u202E&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;u2066 evil&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// → 'admin evil'&lt;/span&gt;

&lt;span class="c1"&gt;// Redact PII before sending to your logger / analytics / LLM&lt;/span&gt;
&lt;span class="nf"&gt;scrubPII&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;call 415-555-0100 or email a@b.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// → 'call [PHONE] or email [EMAIL]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every export maps to a specific OWASP / CWE / CVE reference. The full threat model is published at &lt;a href="https://github.com/007krcs/tekivex-ui/blob/master/docs/SECURITY-THREAT-MODEL.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/SECURITY-THREAT-MODEL.md&lt;/code&gt;&lt;/a&gt; — I think this is the only mainstream React UI library that publishes one.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Indian-market features — out of the box
&lt;/h2&gt;

&lt;p&gt;Most UI libraries are built by US/EU teams and treat Indian-market needs as edge cases. Things tekivex-ui ships natively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;TkxAadhaarInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// 12-digit Aadhaar with Verhoeff checksum validation&lt;/span&gt;
  &lt;span class="nx"&gt;TkxPanInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// PAN regex + entity-character validation&lt;/span&gt;
  &lt;span class="nx"&gt;TkxVoterIdInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TkxDrivingLicenceInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TkxAddressInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// PIN-code → city/state lookup via India Post API&lt;/span&gt;
  &lt;span class="nx"&gt;TkxCurrencyInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// ₹1,23,456 (lakh/crore grouping, not 123,456)&lt;/span&gt;
  &lt;span class="nx"&gt;TkxCalendarLunar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// Tithi/Nakshatra (Hindu), Hijri, Hebrew, Buddhist&lt;/span&gt;
  &lt;span class="nx"&gt;TkxFontProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// lazy-load Devanagari/Tamil/Telugu/Bengali subsets&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tekivex-ui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Aadhaar input does real Verhoeff checksum validation in 13 lines of pure TypeScript. The currency input formats &lt;code&gt;123456&lt;/code&gt; as &lt;code&gt;1,23,456&lt;/code&gt; for INR (&lt;code&gt;en-IN&lt;/code&gt; locale), &lt;code&gt;123,456&lt;/code&gt; for USD, no decimals for JPY/KRW — driven by &lt;code&gt;Intl.NumberFormat&lt;/code&gt;, not a hardcoded table.&lt;/p&gt;

&lt;p&gt;If you're building anything for the Indian market, this saves you 2–3 weeks of plumbing.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The 4 companion packages worth knowing about
&lt;/h2&gt;

&lt;p&gt;Beyond the main library:&lt;/p&gt;

&lt;h3&gt;
  
  
  tekivex-form
&lt;/h3&gt;

&lt;p&gt;Slimmer install for apps that only need form widgets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;tekivex-form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;24 components re-exported from &lt;code&gt;tekivex-ui&lt;/code&gt;. Same React copy via peer dependency, no two-React-copies bug. Tree-shakeable.&lt;/p&gt;

&lt;h3&gt;
  
  
  tekivex-add
&lt;/h3&gt;

&lt;p&gt;shadcn-style component copier — when you want to fork a single component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tekivex-add button
&lt;span class="c"&gt;# Copies TkxButton.tsx into your project's src/components/&lt;/span&gt;
&lt;span class="c"&gt;# Edit it freely, no upstream coupling&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  tekivex-audit
&lt;/h3&gt;

&lt;p&gt;Static-analysis CLI that catches what ESLint plugins miss — XSS via &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt;, missing &lt;code&gt;rel="noopener"&lt;/code&gt; on &lt;code&gt;target="_blank"&lt;/code&gt;, hardcoded API keys in source, &lt;code&gt;eval()&lt;/code&gt;, &lt;code&gt;target="_blank"&lt;/code&gt; without &lt;code&gt;rel="noopener"&lt;/code&gt;, missing CSP meta tags. 15 checks total, each mapped to OWASP/CWE/WCAG references:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tekivex-audit &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--fail-on&lt;/span&gt; warn &lt;span class="nt"&gt;--format&lt;/span&gt; md &lt;span class="nt"&gt;--out&lt;/span&gt; audit.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it as a CI gate. First time I ran it on my own demo site it found 9 errors and 67 warnings. Embarrassing, but that's the point.&lt;/p&gt;

&lt;h3&gt;
  
  
  create-tekivex-app
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create tekivex-app@latest my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two templates: &lt;strong&gt;basic&lt;/strong&gt; (React + Vite + tekivex-ui) or &lt;strong&gt;secure&lt;/strong&gt; (everything plus pre-wired CSP meta tag, Trusted Types installer, frame-buster, and live SecurityCore demos).&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest comparison
&lt;/h2&gt;

&lt;p&gt;This is the section every "I built a thing" post should have but most don't.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Compared to tekivex-ui&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MUI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Teams already on Material Design; massive ecosystem&lt;/td&gt;
&lt;td&gt;More mature; AAA contrast inconsistent; data grid is paid; bigger bundle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chakra UI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Theming flexibility, fast prototyping&lt;/td&gt;
&lt;td&gt;Excellent DX; AA not AAA; no PDF, no security kernel, no India pack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mantine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Forms, hooks, fast iteration&lt;/td&gt;
&lt;td&gt;Great form story; AA not AAA; no PDF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;shadcn/ui&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Copy-paste customisation, Tailwind-native&lt;/td&gt;
&lt;td&gt;Brilliant for tinkerers; only ~30 components; you own all the code (also a downside if you don't want to)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ant Design&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enterprise data-heavy apps&lt;/td&gt;
&lt;td&gt;Huge component count; bundle size; AA not AAA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tekivex-ui&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AAA accessibility hard requirement, India market, document/PDF-heavy apps, security-conscious teams&lt;/td&gt;
&lt;td&gt;Younger; smaller community; opinionated stack&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If your stack is already on MUI/Chakra/Mantine and you're shipping a North American B2B SaaS, you probably don't need to switch — you'd lose ecosystem to gain features you don't need.&lt;/p&gt;

&lt;p&gt;If you're starting fresh, building something India-shaped, AI-shaped, or PDF-shaped, or you have a hard accessibility ceiling — give it a shot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;tekivex-ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TkxButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TkxInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TkxForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TkxFormField&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tekivex-ui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tekivex-ui/styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeProvider&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"auto"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxForm&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxFormField&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxInput&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxFormField&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TkxButton&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Sign up&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxButton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TkxForm&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;mode="auto"&lt;/code&gt; follows the OS &lt;code&gt;prefers-color-scheme&lt;/code&gt; reactively — pin to &lt;code&gt;"dark"&lt;/code&gt; or &lt;code&gt;"light"&lt;/code&gt; if you prefer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;v3.1&lt;/strong&gt; — payments + commerce (&lt;code&gt;TkxCheckout&lt;/code&gt; flow, Razorpay/Stripe/Square integration helpers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v3.2&lt;/strong&gt; — vertical packs filled out (&lt;code&gt;tekivex-india&lt;/code&gt;, &lt;code&gt;tekivex-finance&lt;/code&gt;, &lt;code&gt;tekivex-content&lt;/code&gt; currently re-export; getting their own deep components)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long-term&lt;/strong&gt; — bigger AI-native surface (chat, confidence, streaming)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Honest gaps
&lt;/h2&gt;

&lt;p&gt;I'd rather list these than pretend they don't exist:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;docs site&lt;/strong&gt; at &lt;code&gt;ui.tekivex.com&lt;/code&gt; is currently serving a fallback homepage because Astro 5 + Starlight 0.36 + Zod 4 hit a route-generation crash. Working on it. The component documentation is real and comprehensive in the GitHub source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test coverage&lt;/strong&gt; is at 64.84% lines / 51.10% functions / 56.77% branches — enforced via a CI ratchet. Path to 90/90/85 is documented in &lt;a href="https://github.com/007krcs/tekivex-ui/blob/master/docs/test-coverage-roadmap.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/test-coverage-roadmap.md&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community size&lt;/strong&gt;: I'm one person + occasional contributors. If that's a deal-breaker for you, that's fair.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try it &amp;amp; break it
&lt;/h2&gt;

&lt;p&gt;If you build anything with this — especially something that breaks — please open an issue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 npm: &lt;a href="https://www.npmjs.com/package/tekivex-ui" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/tekivex-ui&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐛 Issues: &lt;a href="https://github.com/novaai0401-ui/tekivex-issue-report/issues" rel="noopener noreferrer"&gt;https://github.com/novaai0401-ui/tekivex-issue-report/issues&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🎮 Live playground: &lt;a href="https://ui.tekivex.com/playground/" rel="noopener noreferrer"&gt;https://ui.tekivex.com/playground/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Especially interested in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;People dropping &lt;code&gt;tekivex-pdf&lt;/code&gt; into existing Puppeteer pipelines and reporting back&lt;/li&gt;
&lt;li&gt;Indian-market apps using the KYC pack&lt;/li&gt;
&lt;li&gt;Anyone who notices an AAA contrast slip — that's a P0 bug to me&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading. And if this saved you from rebuilding &lt;code&gt;&amp;lt;PhoneInput&amp;gt;&lt;/code&gt; for the fourth time, drop a 🦄 below.&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
