Skip to content

Get started

Install and use Skribly UI

The library is a private package installed from git over SSH. Apps with React use the components; any other page uses the plain CSS. Both read the same tokens.

RequirementsLink to the section Requirements

  • Node 26

    The package and its build need Node 26 or newer.

  • SSH access

    A GitHub account with read access to skribly/ui and an SSH key on it.

  • React 19 and Tailwind 4

    Only for the React layer. The plain CSS needs neither.

Check Node and your SSH keybash
. ~/.nvm/nvm.sh && nvm use 26
ssh -T git@github.com

Install from git over SSHLink to the section Install from git over SSH

Add the dependency with the git+ssh address. The semver range picks the newest matching tag; until the first tag exists, use #main.

package.jsonjson
{
  "dependencies": {
    "@skribly/ui": "git+ssh://git@github.com/skribly/ui.git#semver:^0.1.0"
  }
}
Installbash
npm install

Information: The package builds itself during install

dist is not committed. The prepare script builds it, and npm 11 prints an install-scripts warning while the build still runs. For local work next to this repository, file:../skriblyUI is a symlink that runs no build, so run npm install in the library first.

Use in ReactLink to the section Use in React

1. Import the styles

styles.css holds the tokens, the Tailwind mapping, the page defaults, the plain classes and the @source that shows Tailwind the built components.

app.csscss
@import "tailwindcss";
@import "@skribly/ui/styles.css";

2. Set the theme before the first paint

ThemeScript goes first in the head, so a stored dark theme never flashes light. ThemeProvider keeps the choice and follows the system until the reader picks one.

layout.tsxtsx
import { ThemeProvider, ThemeScript } from '@skribly/ui/theme'

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <ThemeScript />
      </head>
      <body>
        <ThemeProvider>{children}</ThemeProvider>
      </body>
    </html>
  )
}

3. Use a component

Import from the package root, or from one group to load only that group. Every visible word and every accessible name is a prop.

A button and a badge
Done
tsx
import { Button } from '@skribly/ui/actions'
import { Badge } from '@skribly/ui/feedback'

<Button onPress={save}>{t('save')}</Button>
<Badge tone="ok">{t('status.done')}</Badge>

Use with plain CSSLink to the section Use with plain CSS

Pages with no React and no Tailwind, such as an Astro site or a single HTML file, import plain.css. Everything sits in cascade layers, so the page’s own CSS wins without specificity fights.

site.csscss
@import "@skribly/ui/plain.css";
Plain HTML
Done
html
<button class="sk-button">Save</button>
<button class="sk-button sk-button--outline">Cancel</button>
<span class="sk-badge sk-badge--ok">Done</span>

Every class is on the plain CSS page.

FontsLink to the section Fonts

The library names its fonts in the tokens and loads none, so each app decides where they come from. Inter is the interface face, JetBrains Mono the code face and Bricolage Grotesque the display face. Each stack falls back to system fonts.

index.htmlhtml
<link rel="preconnect" href="https://fonts.bunny.net" />
<link rel="stylesheet" href="https://fonts.bunny.net/css?family=bricolage-grotesque:600,700,800|inter:400,500,600,700|jetbrains-mono:400,500&display=swap" />

Aa

Inter · --sk-font-sans

Aa

JetBrains Mono · --sk-font-mono

Aa

Bricolage Grotesque · --sk-font-display

Next stepsLink to the section Next steps

Search this site

Arrows move through the results, Enter opens one, Esc closes. Ctrl K /