Skip to content
All designer tools

HTML to JSX Converter

Paste markup and CSS, take away a component — React, Vue, Svelte, styled-components or Tailwind

tsxCard.tsx
/**
 * Card — Card
 * Converted from HTML and CSS.
 *
 * Converted by Hoverlab (hoverlab.dev/tools/convert) from HTML and CSS. Drop this file into any React app (Next.js, Vite,
 * CRA, Remix) and import it — no extra dependencies, no build
 * configuration.
 *
 * The CSS ships in a <style> tag so the class selectors resolve exactly as
 * they do in the original. If you render this component many times on one
 * page, lift the <style> into a global stylesheet instead so the rules are
 * only parsed once.
 */
export function Card() {
  return (
    <>
      <style>{`
.card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-radius: 14px;
  border: 1px solid #e5e7eb;
  background: #ffffff;
}

.card__title {
  font-size: 1.125rem;
  font-weight: 700;
}

.card__btn {
  align-self: flex-start;
  border-radius: 8px;
  padding: 8px 16px;
  color: #ffffff;
  background: var(--accent);
  transition: transform 150ms ease;
}

.card__btn:hover {
  transform: translateY(-1px);
}
      `}</style>
      <div className="card" style={{ '--accent': '#6d28d9', padding: '24px' }}>
        <svg className="card__icon" viewBox="0 0 24 24" fill="none" strokeWidth="2">
          <defs>
            <linearGradient id="g" gradientUnits="userSpaceOnUse">
              <stop stopColor="#6d28d9"></stop>
            </linearGradient>
          </defs>
          <path d="M12 2 L22 20 H2 Z" stroke="url(#g)" strokeLinecap="round"></path>
        </svg>
        <h3 className="card__title">Ship it</h3>
        <p className="card__body">Paste markup on the left. Take a component away.</p>
        <label className="card__check" htmlFor="ok"> <input id="ok" type="checkbox" defaultChecked /> Ready to go </label>
        <button className="card__btn" onClick={() => { ship() }}>Deploy</button>
      </div>
    </>
  )
}

export default Card

What changed on the way through

  • 1 inline style attribute rewritten as style objects. A style string is a runtime error in React, not a warning.
  • onclick became arrow functions. The code inside them still refers to whatever it referred to before, so those globals have to exist where the component is used.

Worth knowing about JSX / React

  • Valid as both .tsx and .jsx — there are no type annotations to strip.
  • Inputs render uncontrolled (defaultChecked) so React does not warn about a value without an onChange handler.

A single .tsx file that runs as .jsx too — there are no type annotations to strip. Attributes are renamed, inline styles become objects, and the stylesheet ships in a <style> tag so your selectors resolve exactly as they did.

It runs in your tab

No request is made with what you paste. The same module runs in our API and CLI, so the conversion here is byte-for-byte the one an agent gets — it is just running on your machine instead of ours.

It is not a compiler

Markup and CSS convert. JavaScript does not: a <script> is removed and inline handlers become arrow functions around your original code, which still needs whatever it referred to before.

Free, and staying that way

Every target here is ungated. The catalog gates some of its own exports; this page is your code, and charging rent on your paste is not a business we are in.

Now use it on something

Every effect, block, page and template in the catalog is styled against tokens shaped exactly like these — so they take your values rather than fighting them.

Hand these tokens to an agent

npx shadcn@latest add https://hoverlab.dev/r/hoverlab.json

Keep this snippet. This browser remembers what you last had open. A free account remembers the ones you name, on every machine you use.

More designer tools

All 36 run in the tab — no account, no upload.See all