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

lojee-ui

v0.1.0-alpha.17

Published

React + TypeScript UI component library styled with Tailwind v4 — ships auto-generated Web Components alongside the React components, with a built-in demo/docs site.

Readme

Lojee UI

npm license docs

Official site & docs: https://lojee-ui.vercel.app/

React + TypeScript UI component library styled with Tailwind v4 — ships auto-generated Web Components (<l-*> custom elements) alongside the React components, with a built-in demo/docs site.

Status: pre-release (0.1.0-alpha.x). Expect changes between alphas — see the changelog.

Features

  • 100+ components — buttons, forms, overlays, feedback, navigation, data display, charts, calendar, maps, flow diagrams, app layout and account screens.
  • React and Web Components — use <Button> in React, or <l-button> in Vue, Angular, or plain HTML.
  • Themes — light / dark mode, 12 brand accents and switchable looks (including Clay), all CSS variables.
  • Animation effects — animation="glow" | "pulse" | "sweep" | "bounce" | "float" | "wiggle" | "border-spin" | "particles" | "tail" (combine with a list; respects prefers-reduced-motion).
  • DotScroll — a dotted, theme-colored scrollbar used across menus, drawers, tables and code blocks.
  • Data binding — set component state from outside and read changes back, in every framework.
  • Fully customizable — className and per-part classNames on every component, merged with tailwind-merge.
  • AI-friendly reference — public/COMPONENTS.md documents every component, prop and event.

Installation

npm install lojee-ui

Consumers need react, react-dom, lucide-react, and tailwindcss (v4) installed and set up as peer dependencies for the React build — nothing is bundled, and Tailwind is required (the components are styled with the Tailwind classes your build generates). Import lojee-ui/theme.css right after Tailwind; it carries the design tokens and the animation tokens, and tells Tailwind to scan the library itself, so no @source line is needed:

@import "tailwindcss";
@import "lojee-ui/theme.css";

For non-React consumers, the auto-generated <l-*> Web Components are available from the lojee-ui/elements subpath (self-contained, bundles React internally):

import "lojee-ui/elements";

Quick start

React:

import { ThemeProvider, Button } from "lojee-ui";

export default function App() {
  return (
    <ThemeProvider defaultMode="light" defaultAccent="emerald">
      <Button animation="glow">Save</Button>
    </ThemeProvider>
  );
}

Vue, Angular or plain HTML:

<script type="module">import "lojee-ui/elements";</script>
<l-button animation="glow">Save</l-button>

Components

| Category | Components | | --- | --- | | Basic | Button, SplitButton, ButtonGroup, SegmentButton, Badge, Avatar, Icon, Spinner, Divider | | Layout & Content | Card, Container, Section, Grid, List, Accordion, Carousel, Image, Video, CodeSnippet, Iframe, ChatBox | | Forms & Inputs | Input, Textarea, Checkbox, Radio, Switch, Select, MultiSelect, Combobox, DatePicker, TimePicker, FileUpload, SearchInput, PasswordInput, Slider, RangeSlider, TagInput, NumberInput, OtpInput, Rating, ColorPicker | | Overlays | Modal, Drawer, Sheet, Popover, DropdownMenu, ContextMenu, CommandMenu, AlertDialog, Tooltip | | Feedback | Alert, Toast, Notification, Thinking, ProgressBar, EmptyState, ErrorState, SuccessState, LoadingState, Skeleton | | Navigation | Navbar, Sidebar, TopBar, Header, Footer, NavigationMenu, BottomNavigation, Tabs, Stepper, Breadcrumbs, Pagination | | App | AppLayout (App, Top, Side, Main, Footer), ThemeSwitcher, AppBackground | | Data & Visualization | Table, GridView, DetailsList, Timeline, Stat, Chart, Calendar, ActivityFeed, FlowDiagram | | Maps | Map, MapMarker, MapRoute, MapControls | | User / Account | ProfileCard, UserMenu, LoginForm, SignupForm, AccountSettings, ProfileSettings, PlanBilling |

Live examples, playgrounds and per-framework API tables for each are on the docs site.

Data binding

Every component can be driven from outside and report changes back — controlled props and onChange in React, v-model / property bindings in Vue and Angular, and plain properties plus events on the <l-*> elements. See the per-language guides on the docs site.

Breaking changes in recent alphas

  • Loader / <l-loader> was removed (alpha.12) — use Skeleton / <l-skeleton>.
  • The animated prop was renamed animation (alpha.13).

See the full changelog.

Development

npm install
npm run dev       # demo/docs app with HMR

Other scripts:

| Script | Purpose | | --- | --- | | npm run dev | Run the demo/docs app locally | | npm run build | Build the demo/docs app (dist/) | | npm run build:lib | Build the React component library (dist/index.js, dist/index.cjs, dist/lib/*.d.ts) | | npm run build:elements | Build the framework-agnostic Web Components bundle (dist/elements.js) | | npm run build:pkg | Build the full publishable package: build:lib + build:elements | | npm run lint | Run ESLint | | npm run preview | Preview the built demo app |

Releasing

npm run release                       # next pre-release (0.1.0-alpha.N+1): docs, bump, build, commit, tag, publish, push
npm run release -- minor              # or patch | major | an exact version
npm run release -- --dry-run          # show the steps, change nothing
npm run release -- --no-publish       # everything except `npm publish`

It needs a clean main, an npm login (or an NPM_TOKEN environment variable), and push rights. It regenerates the API reference, changelog and COMPONENTS.md, bumps the version, type-checks, builds, commits "Release x", tags vx, publishes with the latest tag (plus alpha while it is a pre-release) and pushes the commit and tag.

Publishing manually with an access token

The full step-by-step guide, with example commands and output, is in commands/npm.md. In short: create a granular token, paste it once at read -rs NPM_TOKEN, bump the version, build, then npm publish --tag latest --userconfig "$TMP_NPMRC". npm run release does the same and reads NPM_TOKEN.

Note: npm run build (demo app) and npm run build:pkg (library) both write to dist/. Don't run them back to back expecting both outputs to coexist — run build:pkg on its own in a clean checkout when you need the package output.

Styling & customization

Every component accepts a className prop for the root element, plus a classNames prop for overriding the styling of its internal parts individually — similar to the classNames/slot-override pattern used by shadcn-style component libraries.

<Button classNames={{ icon: "text-emerald-500", badge: "bg-blue-500" }}>
  Save
</Button>

<Modal
  open={open}
  onClose={onClose}
  classNames={{ overlay: "bg-black/70", header: "bg-slate-50", body: "p-4" }}
>
  ...
</Modal>

Under the hood, cx() (src/core/tokens.ts) merges classes with tailwind-merge, so a conflicting utility you pass in (e.g. a different bg-*) always wins over the component's built-in styling, regardless of argument order.

Available slots per component:

| Component | Slots | | --- | --- | | Button | root, icon, badge | | SplitButton | root, divider, mainButton, menuButton, menu | | ButtonGroup | root | | SegmentButton | root, icon | | Modal | root, overlay, header, title, closeButton, body | | Badge | root, icon | | Avatar | root, image, fallback, status | | AvatarGroup | root | | Tooltip | root, bubble | | Spinner | root, dot, bar | | Divider | root, line, label | | Skeleton | root, line |

SplitButton's dropdown is composed from SplitButtonMenuItem children (not a data prop), each with its own className:

<SplitButton icon="download" label="Export">
  <SplitButtonMenuItem icon="file" onClick={() => exportAs("pdf")}>Export as PDF</SplitButtonMenuItem>
  <SplitButtonMenuItem icon="list" onClick={() => exportAs("csv")}>Export as CSV</SplitButtonMenuItem>
  <SplitButtonMenuItem disabled>Cancel</SplitButtonMenuItem>
</SplitButton>

Icon has no classNames — it renders a single element, so its existing className prop already covers full customization.

Theming

lojee-ui ships light/dark mode and switchable brand accents. Both are plain CSS variables defined in lojee-ui/theme.css, so they also work inside the <l-*> Web Components.

import { ThemeProvider, useTheme } from "lojee-ui";

<ThemeProvider defaultMode="light" defaultAccent="emerald">
  <App />
</ThemeProvider>;

const { mode, setMode, accent, setAccent } = useTheme(); // mode: "light" | "dark"

ThemeProvider persists the choice in localStorage and sets data-theme / data-accent on <html>. Without React, set those attributes yourself (<html data-theme="dark" data-accent="teal">); with neither set, the theme is light and the accent is slate.

  • Semantic utilities for your own UI: bg-surface, bg-surface-muted, bg-surface-raised, text-fg, text-fg-muted, text-fg-subtle, border-border, border-border-strong.
  • accent-* palette (bg-accent-600, text-accent-700, …) and color="accent" on any component with a color prop — follows the selected accent. Explicit colors (color="rose") are unaffected.
  • Customise by overriding the --lojee-* variables, e.g. [data-theme="dark"] { --lojee-surface: #000; }.

Maps

Map, MapMarker, MapRoute and MapControls draw interactive vector maps with MapLibre GL and free CARTO basemaps (no API key). Maps follow the light / dark theme, and MapLibre is loaded on demand — only when a map is shown.

npm install maplibre-gl      # optional peer dependency, only needed for the React maps
import { Map, MapMarker, MapRoute } from "lojee-ui";

<Map center={[123.9, 10.305]} zoom={12} controls>
  <MapMarker lng={123.9054} lat={10.2925} label="Fort San Pedro" popup="Hello" />
  <MapRoute waypoints={[[123.9, 10.305], [123.9049, 10.3182]]} />
</Map>

The Web Components bundle includes MapLibre. Markers and routes are plain data there:

<l-map id="map" style="height: 360px" controls="true"></l-map>
<script type="module">
  import "lojee-ui/elements";
  const map = document.getElementById("map");
  map.center = [123.9, 10.305];
  map.zoom = 11;
  map.markers = [{ lng: 123.9054, lat: 10.2925, label: "Fort San Pedro", popup: "Hello" }];
  map.routes = [{ waypoints: [[123.9, 10.305], [123.9049, 10.3182]] }];
</script>

Alternative distribution methods

Registry-free ways to get dist/ (built via npm run build:pkg) into a consumer project — useful for local development or non-npm environments. All of them ship the exact same output that npm publish does (package.json already declares "files": ["dist"] plus the right main/module/types/exports fields).

1. Build the package

npm run build:pkg

Produces dist/index.js (ESM), dist/index.cjs (CJS), dist/elements.js (Web Components, ESM), dist/theme.css, and dist/lib/index.d.ts.

2. Local install / linking (for active development)

Fastest way to try the package in another local project — no registry, no packing:

# npm link — in this repo:
npm run build:pkg && npm link
# then in the consumer project:
npm link lojee-ui

# OR npm install from a local path — in the consumer project:
npm install /absolute/path/to/lojee-ui
# or: npm install file:../lojee-ui

Both approaches symlink the consumer's node_modules/lojee-ui to this repo, so after the initial link you only need to re-run npm run build:pkg (or vite build --config vite.lib.config.ts --watch for a live rebuild loop) — no re-linking required.

3. Git install

npm install git+https://github.com/lojeevlim/lojee-ui.git#<commit-or-tag>

npm does not run a build step for a plain git dependency unless the package has a prepare script, and dist/ isn't committed to the repo. To make this work, either:

  • commit built dist/ output to a dedicated dist/release branch or tag that consumers point at, or
  • add "prepare": "npm run build:pkg" to package.json so it builds automatically on install (requires the build's devDependencies to be installable in the consumer's environment).

4. Tarball via GitHub Release

npm run build:pkg && npm pack

This produces lojee-ui-<version>.tgz. Upload it as a GitHub Release asset, then consumers install it directly:

npm install https://github.com/lojeevlim/lojee-ui/releases/download/<tag>/lojee-ui-<version>.tgz
# or, downloaded locally:
npm install ./lojee-ui-<version>.tgz

5. GitHub Packages (npm-compatible registry)

The closest like-for-like replacement for publishing to npmjs.com:

  1. Add a scoped name (e.g. @lojeevlim/lojee-ui) and publishConfig.registry pointing at https://npm.pkg.github.com in package.json.
  2. Authenticate with a GitHub token that has write:packages scope and run npm publish.
  3. Consumers add an .npmrc scoping @lojeevlim to the GitHub Packages registry, then npm install @lojeevlim/lojee-ui.

6. CDN (jsDelivr / unpkg) straight from GitHub

No publish step needed — works directly off pushed commits or tags, and is the easiest path for non-npm consumers who just want the <l-*> Web Components:

<script type="module" src="https://cdn.jsdelivr.net/gh/lojeevlim/lojee-ui@<tag>/dist/elements.js"></script>

Requires dist/ to be committed (or attached) at that tag, same as the git-install caveat above.