Astro
Install newt/ui in an Astro site, where React and Vue components can live side by side as islands.
Choose the brand hue, the radius and the font in newt/create, and it prints a preset code. Pass that code to init and the project comes out already wearing it.
pnpm dlx create astro@latestnpx create astro@latestyarn dlx create astro@latestbunx create astro@latestpnpm dlx newtui@latest init --preset <code>npx newtui@latest init --preset <code>yarn dlx newtui@latest init --preset <code>bunx newtui@latest init --preset <code>pnpm dlx newtui@latest add buttonnpx newtui@latest add buttonyarn dlx newtui@latest add buttonbunx newtui@latest add buttonAstro has no scaffold template, so the project is created by its own tool first and init runs inside the result. It detects the framework, the bundler and the stylesheet on its own.
pnpm dlx create astro@latestnpx create astro@latestyarn dlx create astro@latestbunx create astro@latestpnpm dlx newtui@latest initnpx newtui@latest inityarn dlx newtui@latest initbunx newtui@latest initpnpm dlx newtui@latest add buttonnpx newtui@latest add buttonyarn dlx newtui@latest add buttonbunx newtui@latest add buttonCreate the site and add a framework
npm create astro@latest my-sitenpx astro add reactnpx astro add vueBoth integrations can be installed at once. This site runs them together: the switcher at the top of the page decides which island paints, and the other one’s markup is hidden rather than unmounted.
Add Tailwind
npx astro add tailwind@import "tailwindcss";Declare the alias
{
"compilerOptions": {
"paths": { "@/*": ["./src/*"] }
}
}Astro resolves tsconfig paths on its own, so there is no second copy to keep
in the Vite config.
Run init
pnpm dlx newtui@latest init --framework reactnpx newtui@latest init --framework reactyarn dlx newtui@latest init --framework reactbunx newtui@latest init --framework reactpnpm dlx newtui@latest init --framework vue --bundler vitenpx newtui@latest init --framework vue --bundler viteyarn dlx newtui@latest init --framework vue --bundler vitebunx newtui@latest init --framework vue --bundler viteA site with both integrations has both frameworks in its dependencies, so name
the one you want the components written for. Running init twice with different
--framework values is fine: the tokens are written once and skipped after
that.
Load the stylesheet and mark the root
---
import "../styles/global.css"
---
<html lang="en">
<body class="newt-root">
<slot />
</body>
</html>Add a component
pnpm dlx newtui@latest add buttonnpx newtui@latest add buttonyarn dlx newtui@latest add buttonbunx newtui@latest add buttonAn interactive component is an island, so it needs a client: directive. A
static one does not.
---
import { Button } from "@/components/ui/button"
---
<Button client:load variant="primary">Send</Button>---
import { Button } from "@/components/ui/button"
---
<Button client:load variant="primary">Send</Button>What init writes
components.json the config, shared with shadcn
src/styles/global.css the --newt-* token block
src/lib/utils.ts cn()
src/components/ui/button.tsx add button (React)
The Vue flavour writes a folder per component instead — Button.vue plus an
index.ts barrel.
Two frameworks in one site
Nothing stops a site from carrying both registries: they share the same
--newt-* tokens, so a React island and a Vue island rendered next to each
other are indistinguishable. Keep them in separate directories —
components/ui for one and components/ui-vue for the other — and point
components.json at whichever you are adding to at the time.
See Dark mode for the theme toggle, and RTL if the site has to run right to left.