Show HN: Basecoat – shadcn/UI components, no React required

3 days ago

Basecoat ports the upcoming shadcn/ui v4 [1] to plain HTML + Tailwind (no React):

- Live demo & documentation: https://basecoatui.com

- MIT‑licensed and free: https://github.com/hunvreus/basecoat/

- Works with any backend (Flask, Django, Rails, PHP, etc.) or static site.

- Fully theme‑compatible with shadcn/ui [2].

- Uses a sliver of Alpine.js only for a few interactive bits (e.g. combobox). Swap in your own JS if you prefer.

- Dead simple to use, just drop in a class here and there:

  <button class="btn" data-tooltip="This is a tooltip text">Click me</button>

Why I built it: after moving from a Next.js stack back to Flask + Tailwind + HTMX, I missed shadcn/ui and didn’t want walls of Tailwind classes (like Flowbite or Preline).

Feedback is most welcome: bugs, requests for components, criticism.

[1]: https://v4.shadcn.com/

[2]: https://basecoatui.com/installation/#install-theming

[3]: https://pagescms.org

I’m moving from react to wordpress and I could not be happier that I discovered this today

I’m so pumped to try this out!!!

> Why I built it: after moving from a Next.js stack back to Flask + Tailwind + HTMX, I missed shadcn/ui and didn’t want walls of Tailwind classes (like Flowbite or Preline).

I understand that Next.js can feel bloated, especially when used as a static site generator or within a classic JAMStack setup.

Basecoatui reminds me a bit of Bootstrap during the golden era of Ruby on Rails.

I took a look at the Git repository and tried to find an automated solution to convert shadcn to plain HTML but didn't find anything suitable. Is there a script available for this, or was this done manually?

Looks great!

One suggestion would be adding a focus trap, such as when a Dialog opens. It's nice to use the tab key to move around the Dialog (inputs and buttons). Currently focus leaves to the page behind. It might be as simple as adding https://alpinejs.dev/plugins/focus#x-trap

Very cool! Are you manually porting all components or are you using some sort of automated process?

  • All manual. It was a bit of work at first, but mostly because I had to decide how to structure them. It's actually quite straightforward to extend and maintain now.

Really great! A major downside of moving from SPA's back to vanilla JS is how much you lose in terms of UI components.

I've normally done DaisyUI + Tailwind + Rails but it never feels quite right. Basecoat is a really nice step forward.

I have to imagine the author is planning to charge for a premium package at some point, but given that a huge % of development is spent on UI design, I'd be more than happy to pay for a year of updates.

  • Glad you like it. Do let me know what you end up building with it.

    > I've normally done DaisyUI + Tailwind + Rails but it never feels quite right.

    Same here: I could never quite get into Flowbite, Daisy UI, Preline or any of the other many alternatives.

    > I have to imagine the author is planning to charge for a premium package at some point,

    I did wonder if people would want to buy premium layouts or components. No plan to charge for anything for now though.

There’s a huge need for this, thank you! I build server-rendered marketing sites and there’s a huge gulf between the jQuery and React era.

  • Have you played with Alpine.js before? HTMX?

    I think you can get quite far these days WITHOUT React or Vue.js (and I say that as the maintainer of a Next.js/React open source project [1]).

    [1]: https://pagescms.org

    • Yep, I’ve used Alpine extensively and HTMX here and there. Lots of Vue.

      There are not sets of polished, battle-tested UI libraries made for server side. Bootstrap ships with JS, but most of the CSS and template frameworks assume you’re using a headless setup.

      I thought Web Components might spur things, but not really. React has continued to dominate.

      1 reply →

Why did you decide going old school using Alpine.js instead of using plain vanilla web components?

  • I did seriously consider it, but again that was about trying to solve the problem in the least opinionated way.

    Which is also why I made the Alpine code as unobtrusive as possible.

    You can get away with using purely the CSS if you don't need dialogs or combobox. And you can plug your own JS if you decide to do so.

    However, I will definitely try and see if I can make a web components version as soon as I have some time.

  • Alpine is old school now?

    • I'd say anything new in 2025 that involves working with the DOM that doesn't use web component is a waste. Lately I have been porting some old JS libraries (7+ years old) that still are visually impressive to web components, and in my experience after porting some libraries there is about 30% fewer lines of code. Before web components there was so much work to get things up and running in the DOM. Alpine.js does this behind the scenes, but there isn't really a need for it anymore.

      2 replies →

This looks great. I've never used React so had never heard of shadcn, and annoyingly I've just got to the point in a side project where pulling out DaisyUI and replacing it with this might be a bit of a chore.

  • Do let me know if you end up using this. I'd love to get real life feedback on using it.

Can someone eli5 how this is different from something like bootstrap?

  • Bootstrap is a completely different framework with a different design language (one that many may precieve as out of fashion). This library/framework allows folks to use ShadCN (a component library) similar to Bootstrap which is only available through React/Vue/Svelte, etc.. with vanilla HTML.

    • So it's different in visual design, but the goal here is actually to make shadcn more like bootstrap? Hmm.. I think I like that.

      1 reply →

This is exactly what I was wanting to reach for, wanted my chrome extension UI to match my react website. Appreciate your work!

So if I understand correctly all JS is custom-written Alpine JS components.

And all CSS is custom classes that use Tailwind @apply, I'm not sure why, can someone elaborate.

  • - I prefer using Alpine rather than Vanilla JS these days. But the JS code is only for dialogs, combobox and tabs. I don't even use it myself on most simple projects. Curious what you would recommend using instead? Web components?

    - I use `@apply` in all of my custom Tailwind classes. It's easy to keep it consistent with the rest of your styles, and in this case it meant it was pretty easy for me to copy a good chunk of shadcn/ui's own components. You usually just use regular CSS for custom Tailwind utility classes?

This is awesome. I did the same and have been using AlpineJS Pines UI library. Been pretty happy with it! But will take a look at this

  • Pines is really neat. I just don't like the wall of classes, but super neat nonetheless.

Absolutely love this. Wanted to do this myself but never enough to get started. You're a legend.

  • Thanks a lot, I got this done over the course of a few weeks and had no idea whether people would find this helpful. Looking forward to seeing others using it in the wild.

Would you be interested in getting rid of Tailwind and have the styling strictly with SASS mixins?

  • Yes, I wanted to export it as a raw CSS build and host it on a CDN.

    Feel free to watch the project if you want to be notified when I get that out.

Thank you! I was searching for this exact thing the other week.

  • That's great to hear. Do let me know if you see any bug or missing component (I'm planning on adding the command component for example).

>> Works with any backend

Have you fully tested it with Solaris or AIX? /s

  • You had me reminisce of my uni days, logging into the Solaris stations pretty much every day. That purple wallpaper is etched into my eyes.