Installation
Unframework fits into a project in one of two ways. A design system writes its components once and builds them for every framework with the unframework command, then publishes them as one package. An app imports .uf.tsx components, its own or a design system's, and the bundler plugin compiles them to the app's framework as part of its build. Most teams use both: the design system builds, and its apps install the result.
What you install
| Package | What it gives you | Who needs it |
|---|---|---|
unframework | The authoring API that a .uf.tsx file imports, its JSX types, defineConfig and the unframework command | every project |
@unframework/unplugin | The bundler plugin, and the Astro integration | an app that compiles .uf.tsx files |
typescript | tsc, to type-check .uf.tsx files through tsconfig.uf.json | any project that type-checks |
Packaging lists what each framework's packager needs, for a design system that publishes a package.
We build and test with Node 24, TypeScript 7 and Vite 8.
Before the first release
Unframework isn't published yet, and the name unframework on npm belongs to another project until our first release. So npm install unframework gives you a different package, and so does the "unframework": "latest" that create-unframework writes into a new project's package.json. Until then, install them from tarballs that you pack from a checkout of the repository, as our end-to-end apps do:
- Clone the repository and install its dependencies, with Node 24 or later and pnpm:
git clone https://github.com/uxfront-com/unframework.git cd unframework pnpm install - Build and pack the packages. This writes a tarball for
unframework,@unframework/unplugin, every package they depend on and our sample design system intotests/e2e/.tarballs/, withpacked.json, which names each package's tarball:pnpm --filter @unframework/e2e prepare-apps --pack - In your project, depend on
unframework, and on@unframework/unpluginfor an app, throughfile:paths to their tarballs. Then add an override with thefile:path of every tarballpacked.jsonnames, since the packages depend on each other at version0.0.0, and an install would otherwise look for them on npm. With pnpm, the overrides go inpnpm-workspace.yaml.
The end-to-end suite's README shows how its apps do the same.
Start a project
With unframework installed, unframework init writes a config, an example component with its stylesheet, tsconfig.uf.json and AGENTS.md, and unframework check passes on them. In a new directory, create-unframework <dir> writes a package.json that depends on unframework. Once you've installed its dependencies, run unframework init there. The CLI lists what each file holds.
From there:
- To build a design system, set your targets in
unframework.config.ts, then rununframework build, orunframework build --packageto package it. - To use components in an app, add the bundler plugin to your Vite config, or the Astro integration, and import a
.uf.tsxfile. - To write components, start with Props.
Introduction
Unframework is the compiler that speaks seven UI frameworks. Write a component once, and it compiles to native React, Vue, Svelte, Angular, Solid, Qwik and Astro code.
Props
A component takes its props as one typed parameter, destructured with static defaults or read as props.x, and every framework declares them its own way.