Skip to content

Installation

Terminal window
# bun (recommended)
bun add @f0rbit/ui
# npm
npm install @f0rbit/ui
# pnpm
pnpm add @f0rbit/ui

This library requires SolidJS ^1.8.0 as a peer dependency. If you don’t have it installed:

Terminal window
bun add solid-js

Import the styles once in your app’s entry point:

import "@f0rbit/ui/styles";

If you prefer more control, import individual style layers:

import "@f0rbit/ui/styles/tokens"; // CSS variables (colors, spacing, etc.)
import "@f0rbit/ui/styles/reset"; // CSS reset
import "@f0rbit/ui/styles/utilities"; // Utility classes
import "@f0rbit/ui/styles/components"; // Component styles
import { Button, Card } from "@f0rbit/ui";
<Card>
<Button>Click me</Button>
</Card>

For a standard Vite + SolidJS project:

// src/index.tsx (or main.tsx)
import { render } from "solid-js/web";
import "@f0rbit/ui/styles";
import App from "./App";
render(() => <App />, document.getElementById("root")!);

Your vite.config.ts typically requires no special configuration:

import { defineConfig } from "vite";
import solidPlugin from "vite-plugin-solid";
export default defineConfig({
plugins: [solidPlugin()],
});

For Astro with the SolidJS integration:

  1. Ensure you have the SolidJS integration installed:
Terminal window
bun add @astrojs/solid-js
  1. Import styles in your layout or page:
src/layouts/Layout.astro
---
import "@f0rbit/ui/styles";
---
<html>
<body>
<slot />
</body>
</html>
  1. Use components in .astro files with the client: directive:
---
import { Button } from "@f0rbit/ui";
---
<Button client:load>Click me</Button>

Or in SolidJS components (.tsx files) as normal:

src/components/MyComponent.tsx
import { Button, Card } from "@f0rbit/ui";
export default function MyComponent() {
return (
<Card>
<Button>Click me</Button>
</Card>
);
}

@f0rbit/ui ships with full TypeScript support. Types are automatically resolved from the package.

{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "preserve",
"jsxImportSource": "solid-js",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}

All component props are exported as types:

import type { ButtonProps, CardProps, ModalProps } from "@f0rbit/ui";
const myButtonProps: ButtonProps = {
variant: "primary",
size: "md",
loading: false,
};

Symptom: Components render but appear unstyled.

Solution: Ensure you import styles in your app’s entry point:

import "@f0rbit/ui/styles";

For Vite, verify the import is in your index.tsx or main.tsx, not just in individual components.

For Astro, import in your layout file or use is:global in a style tag.

Symptom: TypeScript errors or missing type definitions.

Solution: Check your tsconfig.json:

  1. Ensure moduleResolution is set to "bundler" or "node16":
{
"compilerOptions": {
"moduleResolution": "bundler"
}
}
  1. If using older module resolution, try adding the package to types:
{
"compilerOptions": {
"types": ["@f0rbit/ui"]
}
}

Symptom: Components don’t appear or throw hydration errors in SSR frameworks.

Solution: For Astro, ensure you add a client: directive:

<Button client:load>Works</Button> <!-- Correct -->
<Button>Missing directive</Button> <!-- Won't hydrate -->

Available directives: client:load, client:idle, client:visible.

Symptom: Your custom styles are being overridden by component styles.

Solution: @f0rbit/ui uses CSS @layer for lower specificity. Your styles should naturally win. If not, wrap your overrides:

/* Your styles will override component styles */
.my-button {
background: red;
}

Or use CSS variables for theming instead:

:root {
--accent: oklch(55% 0.2 250);
}

Symptom: Components don’t respond to dark mode.

Solution: @f0rbit/ui automatically respects prefers-color-scheme. To force a mode, add a class to your root element:

<html class="dark"> <!-- Force dark mode -->
<html class="light"> <!-- Force light mode -->

Or use CSS custom properties to override token values. See Theming for details.