Blazor components with shadcn/ui styling and typed C# APIs.
Quark gives you forms, tables, navigation, dialogs, and more with consistent defaults. Compose components in Razor, handle events in C#, and control layout and appearance with typed properties.
Use it to build dashboards, admin tools, customer portals, and other Blazor applications without styling every control from scratch.
Explore the live demo → · Component catalog · Get started · NuGet
- Less styling to repeat. Components share defaults for spacing, typography, colors, and interaction states. Variants cover common choices such as primary and secondary actions.
- Ordinary Razor and C#. Compose headers, content, and actions in markup. Bind values and handle events using the Blazor patterns you already know.
- Typed styling. Set layout, spacing, colors, and responsive behavior with Quark properties and fluent builders. Reuse styling through presets.
- Shared themes. Theme tokens apply your colors and light/dark appearances across components.
- Build tooling included. Install through NuGet and generate styles and icons during your .NET build. The generators provision Node.js and npm when needed.
Quark is MIT-licensed and uses Bradix interaction primitives for behaviors such as focus management and overlays.
The following setup uses a .NET 10 standalone Blazor WebAssembly app. In an existing app, start with the package commands in its project directory.
dotnet new blazorwasm -n MyQuarkApp
cd MyQuarkApp
dotnet add package Soenneker.Quark.Suite
dotnet add package Soenneker.Quark.Gen.Tailwind
dotnet add package Soenneker.Quark.Gen.Tailwind.Manifest
dotnet add package Soenneker.Quark.Gen.Lucide
dotnet add package Soenneker.Lucide.IconsThese packages provide the components, stylesheet generation, and Lucide icons. Add them directly to the app project.
Add this property group inside your app's .csproj:
<PropertyGroup>
<TailwindGeneratorBuildEnabled>true</TailwindGeneratorBuildEnabled>
</PropertyGroup>In the <head> of wwwroot/index.html, add:
<link rel="stylesheet" href="css/quark-tailwind.min.css" />Your .NET build generates the stylesheet. The first build needs network access to download any missing tools and dependencies; Node.js and npm are provisioned automatically when needed.
In Program.cs, add these namespaces:
using Soenneker.Quark;
using Soenneker.Quark.Gen.Lucide.Generated;After creating builder and before builder.Build(), register Quark and icons:
builder.Services.AddQuarkSuiteAsScoped();
builder.Services.AddLucideIconsAsScoped();Add to _Imports.razor:
@using Soenneker.Quark
@using Soenneker.Lucide.Enums.IconsUsing a Blazor Web App? Load the stylesheet in your document shell, usually Components/App.razor, and register the services in the project that runs your interactive components. Pages with input and event handlers need an interactive render mode. See the installation guide for more setup details.
Create Pages/QuarkStart.razor:
@page "/quark-start"
<Card MaxWidth="MaxWidth.IsMd">
<CardHeader>
<CardTitle>Create a workspace</CardTitle>
<CardDescription>Choose a name for your team's workspace.</CardDescription>
</CardHeader>
<CardContent>
<Field>
<FieldLabel For="workspace-name">Workspace name</FieldLabel>
<Input Id="workspace-name" @bind-Value="_name" />
</Field>
</CardContent>
<CardFooter>
<Button OnClick="CreateWorkspace">
<Icon Name="LucideIcon.Check" aria-hidden="true" />
Create workspace
</Button>
</CardFooter>
</Card>
<Paragraph role="status">@_message</Paragraph>
@code {
private string? _name = "My workspace";
private string _message = "";
private void CreateWorkspace()
{
_message = string.IsNullOrWhiteSpace(_name)
? "Give your workspace a name to get started."
: $"Workspace name: {_name}";
}
}Run the app:
dotnet runOpen /quark-start at the address printed in your terminal. The example demonstrates component composition, input binding, and a button handler. It only updates a local message; connect the handler to your application service to create a workspace.
The component catalog includes working examples. Common starting points:
| What you are building | What to reach for |
|---|---|
| Application workspaces | Sidebars, cards, and tabs for navigation and page structure. |
| Forms and settings | Inputs, fields, and date pickers for collecting and organizing input. |
| Dashboards and reporting | Data tables, charts, and real-time charts for exploring data. |
| Actions and feedback | Dialogs, dropdown menus, and toast notifications for focused interactions. |
| AI and attachment workflows | Prompt inputs, attachments, and file drop zones for composing messages and working with files. |
Use built-in variants to give actions the right emphasis:
<Button>Save changes</Button>
<Button Variant="ButtonVariant.Secondary">Preview</Button>
<Button Variant="ButtonVariant.Outline">Cancel</Button>Typed styling keeps spacing and responsive behavior alongside your components:
<Div Display="Display.Flex"
FlexDirection="FlexDirection.Col.OnMd.Row"
Gap="Gap.Is3"
Padding="Padding.OnX.Is4.OnY.Is2">
<Button>Save changes</Button>
<Button Variant="ButtonVariant.Outline">Cancel</Button>
</Div>The actions stack on smaller screens and sit in a row from the medium breakpoint. Read the chains left to right: OnMd.Row applies the breakpoint to the row layout; OnX.Is4.OnY.Is2 sets horizontal and vertical padding.
Use typed Quark properties for styling whenever an equivalent property exists. For reusable styling, group those properties in a dedicated Quark preset.
Explore styling properties · Build responsive grids
Use semantic colors so components follow your theme in light and dark mode:
<Div BackgroundColor="BackgroundColor.Card"
TextColor="TextColor.CardForeground"
Padding="Padding.Is4">
<Paragraph>A surface that follows your application theme.</Paragraph>
</Div>Configure tokens in tailwind/quark-shadcn.theme.json, or use the optional Soenneker.Quark.Gen.Themes package to define a shared theme in C#. The theme guide walks through configuration, stylesheet setup, and switching between light and dark mode.
The quick start includes Lucide icons. Reference an icon by name in your markup:
<Button Variant="ButtonVariant.Outline">
<Icon Name="LucideIcon.Check" aria-hidden="true" />
Mark as complete
</Button>For brand logos, add Soenneker.Quark.Gen.SimpleIcons and Soenneker.SimpleIcons.Icons, then register AddSimpleIconsAsScoped() from Soenneker.Quark.Gen.SimpleIcons.Generated. See the generator guide for setup and dynamically selected icons.
Use SeoHead for page titles, descriptions, canonical URLs, Open Graph, Twitter cards, and optional JSON-LD. It works with Blazor's HeadOutlet; your application supplies its own branding and structured data.
| Next step | Guide |
|---|---|
| Find a component and see it in action | Component catalog |
| Walk through a complete first example | Your first component |
| Customize layout and appearance | Styling · Themes |
| Configure CSS, icons, or build tooling | Generator guide |
| Resolve missing styles, icons, or interaction | Troubleshooting |
| Learn from a working application | Demo source |
| Problem | Check |
|---|---|
| Components appear unstyled | Enable TailwindGeneratorBuildEnabled, rebuild, and confirm the generated stylesheet is loaded by the page. |
| Buttons or inputs do not respond | In a Blazor Web App, ensure the page uses an interactive render mode and Quark services are registered in the project running the components. |
| Lucide icons do not appear | Confirm both Lucide packages are installed and AddLucideIconsAsScoped() is registered, then rebuild. |
See the troubleshooting guide for more details.
Quark is available under the MIT license. Issues and contributions are welcome.
For bugs, open an issue with the package version, hosting model, and a minimal reproduction. For feature requests, describe the workflow you need to support.