Installation
Simurgh supports two installation models. Choose one model for a component and keep its import path consistent:
- Copy source with the CLI when you want the component implementation inside your application and expect to edit it.
- Install packages when you want normal dependency upgrades and imports from
@simurgh-ui/{framework}.
The project is pre-release. Pin exact versions in production and review changes before upgrading or overwriting copied source.
Copy editable source with the CLI
Section titled “Copy editable source with the CLI”Run the initializer from the root of an existing Angular, React, or Vue application:
pnpm dlx @simurgh-ui/cli initpnpm dlx @simurgh-ui/cli add dialog tabs checkboxinit detects the framework from package.json, writes simurgh.json, copies the token stylesheet
and recipe index, and installs that adapter’s runtime dependencies. Each add command copies the
matching component recipes and adds them to the index. Pass --framework react,
--framework vue, or --framework angular only when detection cannot choose correctly. Use
--skip-install when your package manager or workspace policy requires installing dependencies
separately.
Generated files default to these locations:
| Framework | Component source | Styles |
|---|---|---|
| React | [src/]components/ui/<component>.tsx | [src/]styles/simurgh/ |
| Vue | [src/]components/ui/<component>.ts | [src/]styles/simurgh/ |
| Angular | src/app/components/ui/<component>.ts | src/styles/simurgh/ |
For React and Vue, the src/ prefix is used when the application already has a src directory.
Projects using a root layout, including Next.js applications created without the src option, stay
root-based; init does not create a new src directory.
add writes one framework-native source file and one CSS recipe per component. Existing source and
recipe files are preserved unless --overwrite is supplied. The generated recipes.css file
imports only installed component recipes. With no component names, add copies the complete
catalog.
# Inspect available registry componentspnpm dlx @simurgh-ui/cli list
# Check one locally copied component against the current registrypnpm dlx @simurgh-ui/cli diff dialogdiff exits with a non-zero status when the local source differs, including intentional local
customizations. Review the difference before running add dialog --overwrite; overwrite replaces
the local component and is not a merge operation. Commit or otherwise back up local changes first.
Import copied components from their local path, not from @simurgh-ui/react,
@simurgh-ui/vue, or @simurgh-ui/angular. Add the copied tokens.css and recipes.css to the
application’s global stylesheet entry according to the framework build tool. Component styles live
under styles/simurgh/components/ and can be customized independently.
Install as packages
Section titled “Install as packages”Install the adapter for your framework plus the optional recipe package:
# Reactpnpm add @simurgh-ui/react @simurgh-ui/styles
# Vuepnpm add @simurgh-ui/vue @simurgh-ui/styles
# Angularpnpm add @simurgh-ui/angular @simurgh-ui/stylesThe package manager installs Core and positioning dependencies declared by the chosen adapter. React 18 or newer, Vue 3.4 or newer, or Angular 18 or newer is required. Import recipe CSS in a global stylesheet or framework-level entry so it is available before the component renders.
React quick start
Section titled “React quick start”import { Button } from '@simurgh-ui/react/button';import '@simurgh-ui/styles/button.css';
export function SaveButton() { return <Button type="button">Save changes</Button>;}React components accept the documented component props together with supported native attributes. Use the component subpath shown above to keep unrelated components out of the bundle.
Vue quick start
Section titled “Vue quick start”<script setup lang="ts">import { Button } from '@simurgh-ui/vue/button';import '@simurgh-ui/styles/button.css';</script>
<template> <Button type="button">Save changes</Button></template>Vue components forward supported attributes to their interactive element. Importing component CSS from a global application entry is also valid and avoids repeating it across single-file components.
Angular quick start
Section titled “Angular quick start”import { Component } from '@angular/core';import { ButtonComponent } from '@simurgh-ui/angular/button';
@Component({ selector: 'app-save-button', standalone: true, imports: [ButtonComponent], template: `<simurgh-button type="button">Save changes</simurgh-button>`,})export class SaveButtonComponent {}Add the recipe to the application’s global styles entry:
@import '@simurgh-ui/styles/button.css';Angular exports standalone components. Import the documented component class into the consuming standalone component or NgModule.
Styles: recipes or headless behavior
Section titled “Styles: recipes or headless behavior”Import tokens.css for semantic variables and component recipes for the optional visual layer. Headless behavior does not depend on either stylesheet. Avoid importing the complete recipes.css catalog in production unless the application genuinely uses most components.
Production imports
Section titled “Production imports”Prefer component subpaths so application bundlers receive the narrowest possible graph:
import { Button } from '@simurgh-ui/react/button';import '@simurgh-ui/styles/button.css';Each component stylesheet includes the shared tokens, so applications can import only button.css in this example. Import tokens.css separately when an application consumes tokens without a component recipe.
The same pattern applies to Vue (@simurgh-ui/vue/button) and Angular (@simurgh-ui/angular/button). When several primitives are needed together, @simurgh-ui/{framework}/basic provides common non-floating controls, while @simurgh-ui/{framework}/overlays provides dialogs, menus, tooltips, and related positioned UI. The basic boundary intentionally excludes overlay positioning code.
Root adapter imports and @simurgh-ui/styles/all.css remain convenient opt-in aggregates. Use them when the complete catalog is genuinely required; component JavaScript and CSS subpaths are the recommended production default.
Lazy-load overlays
Section titled “Lazy-load overlays”Dialogs, menus, tooltips, and other positioned components include Simurgh’s small internal positioning layer. Keep that positioning code out of the initial application bundle by loading an overlay at its route or interaction boundary.
// Reactimport { lazy } from 'react';
const Dialog = lazy(() => import('@simurgh-ui/react/dialog').then((module) => ({ default: module.Dialog, })),);// Vueimport { defineAsyncComponent } from 'vue';
const Dialog = defineAsyncComponent(() => import('@simurgh-ui/vue/dialog').then((module) => module.Dialog),);// Angular route{ path: 'dialog-example', loadComponent: () => import('@simurgh-ui/angular/dialog').then( (module) => module.DialogComponent, ),}Lazy loading moves the overlay and positioning layer into an asynchronous chunk. It does not reduce the total downloaded code when the overlay is opened, but it keeps that cost off the initial path.
Last verified on 2026-08-13 against Simurgh registry 0.1.1.