npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

simple-blog-ui

v0.4.2

Published

Terminal-style UI component library for simple-blog. 45 Web Components that work in plain HTML, React, and Vue. Built with Lit. Monospace, uppercase, 2px solid borders, zero rounded corners.

Downloads

1,025

Readme

simple-blog-ui

The UI kit for your terminal-style blog.

A framework-agnostic component library built with Lit — drop it into plain HTML, React, or Vue and get 45 Web Components styled after mkdocs-simple-blog: Fira Mono, uppercase, 2px borders, zero rounded corners. The kind of UI that looks like it was typeset on a Selectric.

📖 Live Storybook: fernandocelmer.github.io/simple-blog-ui

Why?

  • One lib, three stacks. Web Components are native — write them once, use them everywhere.
  • Opinionated design, zero configuration. The whole kit follows a single aesthetic: monospace terminal chic. No theme configuration required to look good.
  • Dark mode baked in. Flip data-theme="dark" on <html> and every component inverts correctly.
  • Syntax highlighting included. <sb-code> auto-highlights JavaScript, Python, Bash, JSON, HTML and 30+ more languages via highlight.js.
  • Tiny. ~5KB Lit runtime + per-component shadow DOM. No global CSS-in-JS bloat.
  • React-first DX. Official PascalCase wrappers via simple-blog-ui/react turn custom events (sb-click, sb-change) into native React handlers (onClick, onChange).
  • Blog-ready. Includes a dedicated Blog category with layout, sidebar, footer and prev/next primitives — drop-in building blocks for a documentation site.

Install

npm install simple-blog-ui

Quick start

HTML

<script type="module">
  import 'simple-blog-ui';
</script>
<link rel="stylesheet" href="node_modules/simple-blog-ui/src/styles/main.css" />

<sb-button variant="primary">Click me</sb-button>

React

import { Button, Input, Alert } from 'simple-blog-ui/react';
import 'simple-blog-ui/style.css';

export default function App() {
  return (
    <>
      <Button variant="primary" onClick={() => alert('hi')}>Click me</Button>
      <Input label="Email" onInput={(e) => console.log(e.detail.value)} />
      <Alert variant="success" title="Saved">Done.</Alert>
    </>
  );
}

Vue 3

<script setup>
import 'simple-blog-ui';
import 'simple-blog-ui/style.css';
</script>

<template>
  <sb-button variant="primary" @sb-click="onClick">Click me</sb-button>
</template>

Tell Vue that sb-* is a custom element — add to your vite.config:

vue({ template: { compilerOptions: { isCustomElement: (t) => t.startsWith('sb-') } } })

Components

45 components · 9 categories · all in the same minimalist style.

| Category | Count | Components | | -------------- | :---: | ----------------------------------------------------------------------------------------------- | | actions | 4 | sb-button · sb-icon-button · sb-button-group · sb-close-button | | typography | 3 | sb-heading · sb-text · sb-code | | layout | 3 | sb-container · sb-stack · sb-divider | | display | 9 | sb-card · sb-avatar · sb-badge · sb-tag · sb-accordion · sb-collapse · sb-list-group · sb-carousel · sb-table | | forms | 4 | sb-input · sb-textarea · sb-checkbox · sb-switch | | feedback | 4 | sb-alert · sb-spinner · sb-progress · sb-toast | | navigation | 6 | sb-link · sb-tabs · sb-nav · sb-navbar · sb-breadcrumb · sb-pagination | | overlays | 5 | sb-modal · sb-tooltip · sb-dropdown · sb-offcanvas · sb-popover | | blog 🆕 | 7 | sb-page-layout · sb-sidebar · sb-footer · sb-prev-next · sb-post-list · sb-profile · sb-error-page |

Play with every single one in the Storybook.

Blog primitives

The blog category provides the building blocks for a documentation-style site (used in production by mkdocs-simple-blog):

| Component | What it does | |---|---| | <sb-page-layout> | Max-width container + 25/75 sidebar/content grid. Collapses to one column on mobile. | | <sb-sidebar> | Nested TOC — pass items as JSON (supports unlimited depth). | | <sb-footer> | Centered footer section with top border and stacked items. | | <sb-prev-next> | 3-column prev/next post navigation. | | <sb-post-list> | Post index with date + title columns. | | <sb-profile> | Centered about page — name, role, bio slot, social links. | | <sb-error-page> | 404/500 with oversized code + message and action slot. |

React — event handling

Custom events map to standard React props. The CustomEvent payload lives at event.detail.

| React prop | Components | | --------------- | --------------------------------------- | | onClick | Button · IconButton | | onChange | Input · Checkbox · Switch · Accordion | | onInput | Input · Textarea | | onClose | Modal · Offcanvas · Toast · CloseButton | | onSelect | Dropdown · ListGroup | | onPageChange | Pagination | | onTabChange | Tabs | | onDismiss | Alert | | onRemove | Tag | | onToggle | Collapse | | onSlide | Carousel |

Theming

Two themes out of the box. Toggle with a single attribute:

<html data-theme="dark">

Every component reads its colors and spacing from CSS custom properties defined in root.css. Override any of them to re-theme globally:

:root {
  --primary: #1e40af;        /* change primary accent */
  --color-red: #b91c1c;      /* change error color */
  --background: #fef3c7;     /* change page background */
}

Core tokens (inherited verbatim from mkdocs-simple-blog):

--text: #000        --color-blue:   #4051b5
--title: #000       --color-green:  #4cae4f
--primary: #000     --color-yellow: #f1dc15
--background: #fff  --color-orange: #ffa724
--color-gray: #808080
                    --color-purple: #ab47bd
                    --color-red:    #ff2c06

Storybook and docs

Every component has a live Storybook page with HTML / React / Vue code tabs, interactive controls, and the full set of variants.

npm install
npm run storybook   # opens http://localhost:6006

Three usage guides inside Storybook: Usage / HTML, Usage / React, Usage / Vue — plus Design / Colors and Design / Typography for the full token map.

Scripts

npm run storybook        # dev server at :6006
npm run build            # library build (ESM + CJS)
npm run build-storybook  # static Storybook site
npm pack                 # produce a local tarball for testing

Why Web Components (and Lit)?

The lib is built with Lit, which compiles to standard Web Components — native browser APIs. That means:

  • No framework lock-in. A <sb-button> is just an HTML element with Shadow DOM. It works in React, Vue, Svelte, Solid, Angular, plain HTML, or any future framework.
  • Scoped styles. Shadow DOM isolates each component's CSS — no class name collisions, no global leaks.
  • Tiny runtime. Lit is ~5KB gzip, loaded once for the whole library. No per-component bundle bloat.
  • Future-proof. Web Components are a W3C standard. Your investment survives framework churn.

How it compares

| Library | Distribution | Design system | Dark mode | Frameworks | Blog primitives | |---|---|---|---|---|---| | simple-blog-ui | npm (ESM + CJS) | Monospace, B&W, 2px borders | ✅ built-in | HTML · React · Vue | ✅ Page layout · TOC · Prev/Next | | Shoelace | npm | Modern, rounded | ✅ | all via WC | ❌ | | MUI | npm | Material Design | ✅ | React only | ❌ | | Chakra UI | npm | Clean, rounded | ✅ | React only | ❌ | | shadcn/ui | copy-paste | Opinionated | ✅ | React only | ❌ |

When to pick simple-blog-ui — you want a clean, opinionated monospace/terminal aesthetic, your app or blog is documentation-centric, or you want one lib that works across React and Vue without rewrites.

FAQ

Does it work with Next.js / Nuxt? Yes. Register the components client-side (Next: in a client component; Nuxt: via a .client.ts plugin). Both frameworks support Web Components.

What about SSR? Components render in the browser (Shadow DOM is client-side). The server sends the <sb-*> tags, the client hydrates. For pre-rendered HTML you can use Lit SSR separately — not included here.

Is it tree-shakeable? Individual components can be imported per-file in the React wrapper layer (import { Button } from 'simple-blog-ui/react'). The Web Component registrations in the main entry are side-effect imports — the full set is ~96KB gzipped.

Can I theme it? Yes. All colors, fonts, spacing come from CSS custom properties. Override on :root to re-theme globally or on any parent for scoped overrides.

Is there a Figma kit? Not yet.

How do I contribute? Open an issue or PR at github.com/FernandoCelmer/simple-blog-ui.

Credits

Born as a React/Vue companion to mkdocs-simple-blog. Built with Lit and highlight.js. React wrappers generated via @lit/react. Documented with Storybook.

License

MIT — Fernando Celmer