Skip to content

Repository files navigation

"After playing around with Replicant, I realized I could build Web Components without React — actually, even without Replicant.

I'm wondering if it's called 'Replicant' because of Blade Runner (I love Blade Runner).

Maybe I could name my own library something similar... Tyrell? No, that feels pretentious.

Anyway, I don't really want to type something long like tyrell-button. It should be shorter — maybe ty-button.

Yes! Let's call it ty."

Nine months later…

"Nine months in, ty still reads as 'thank you' — Just had to cut that and call it properly."

"The library is Tyrell. CLJS namespaces are tyrell.* now (tyrell.router, tyrell.components, tyrell.lucide). Component tags stay ty-* — web custom elements need the dash anyway, and two letters earn their keep. CSS classes stay ty-* for the same reason. The prefix earned the shortcut; the brand didn't."

"No thanks involved. Just replicants."

Tyrell

jsDelivrNPM VersionClojars Project

More framework than framework. Tyrell ships Web Components that work everywhere — React, Vue, HTMX, vanilla JS, ClojureScript.

Live Demo & Docs →

Why Tyrell?

Tyrell is a framework-agnostic evolution of Toddler, a ClojureScript UI library built on Helix (React).

Toddler provided great components (calendar, dropdown, routing, icons) but was locked to React/Helix. Tyrell takes that component library and rebuilds it with Web Components, making the same functionality available everywhere — React, Vue, HTMX, vanilla JS, and all ClojureScript frameworks (Replicant, UIx, Reagent).

Same components. Zero framework lock-in.


Load from CDN

Always loads the latest version:

<linkrel="stylesheet" href="https://cdn.jsdelivr.net/npm/tyrell-components/css/tyrell.css"><linkrel="stylesheet" href="https://cdn.jsdelivr.net/npm/tyrell-components/css/tyrell-theme.css"><scriptsrc="https://cdn.jsdelivr.net/npm/tyrell-components/dist/tyrell.js"></script>

Pin to a specific version (recommended for production):

<linkrel="stylesheet" href="https://cdn.jsdelivr.net/npm/tyrell-components@1.0.0-RC10/css/tyrell.css"><linkrel="stylesheet" href="https://cdn.jsdelivr.net/npm/tyrell-components@1.0.0-RC10/css/tyrell-theme.css"><scriptsrc="https://cdn.jsdelivr.net/npm/tyrell-components@1.0.0-RC10/dist/tyrell.js"></script>

Browse all available versions on NPM or jsdelivr.

The OKLCH theme engine

tyrell.css alone has no color tokens — spacing, typography, shadows, component structure only. tyrell-theme.css, loaded after it, supplies every color via a computed OKLCH engine: correct-contrast button text on any color, seed-based rebranding, named/scoped themes, animated theme transitions. Rebrand the whole library coherently in light AND dark mode with a single CSS variable:

<style>:root {
--ty-primary-hue:200; /* teal */--ty-primary-chroma:0.13;
}
</style>

Don't want the theme engine? Load tyrell-colors-static.css instead of tyrell-theme.css for a plain hardcoded fallback palette — no relative-color-syntax requirement, works on older browsers, no theming API.

Every component — buttons, inputs, dropdowns, calendars, focus rings, scrollbars — retints together. Drag the sliders at /docs/theming to preview, then copy the :root snippet straight to your app.

Use components anywhere

<ty-buttonflavor="primary">Click me</ty-button><ty-selectlabel="Country" placeholder="Select..."><ty-optionvalue="us">United States</ty-option><ty-optionvalue="de">Germany</ty-option></ty-select>

Using with AI coding agents

Tyrell is documented for AI agents from day one. Two artifacts make it work:

  • Agent instructions snippet — drop into your project's CLAUDE.md, .cursorrules, .windsurfrules, .github/copilot-instructions.md, or whichever instruction file your agent reads. The snippet teaches the agent the rules (colors come from Tyrell, events live on event.detail, icons need registration, etc.) and points at the doc index.
  • llms.txt — machine-readable index of every guide, served as raw markdown. Tell your agent to fetch it once and it has a navigable map of the entire documentation set. Per the llmstxt.org convention.

For agents with web fetch (Claude Code's WebFetch, Cursor's @web, ChatGPT browsing), pointing them at https://gersak.github.io/tyrell/llms.txt at session start is enough. For agents without it, paste the snippet into the instruction file and the agent learns the rules without any network calls.

The treasure-map entry point for AI navigation is guides/AI_GUIDE.md — two routing tables that get an agent to the right framework guide in one hop.


Guides

Pick the entry point for your stack:

JavaScript / TypeScript

  • Vanilla JS Guide — bundlers, subpath imports, icon tree-shaking, code splitting, SSR
  • React Guidetyrell-react wrappers
  • Vue Guide — Vue 3 / Nuxt native usage (no wrapper package)
  • Svelte Guide — Svelte 5 / SvelteKit native usage (no wrapper package)

ClojureScript

Server-driven UIs


ClojureScript

Add to deps.edn:

{:deps {dev.gersak/tyrell {:mvn/version"1.0.0-RC10"}}} ; icons come transitively

That single dep brings:

  • Routing, i18n, layout, icon registry, shim — tyrell.router, tyrell.i18n, tyrell.layout, tyrell.icons, tyrell.shim
  • The tyrell.components shim that side-effect-imports the npm package
  • 12,000+ tree-shakeable icons (tyrell.lucide, tyrell.heroicons.*, tyrell.material.*, tyrell.fontawesome.*)

The npm tyrell-components package is declared in this artifact's deps.cljs, so shadow-cljs auto-installs it on first build.

Pick your view layer

You're usingGuide
Reagent, re-frame, UIx, HelixQUICKSTART → Track Atyrell.react wrappers
Replicant, vanilla CLJS, server-renderedREPLICANT_TY_GUIDE — raw <ty-*> elements

Icon registration

<ty-icon name="check"> is a runtime registry lookup. Register the icons you reference at app startup:

(nsmy-app.core
(:require [tyrell.components] ; side-effect: registers all <ty-*> elements
[tyrell.icons :as icons]
[tyrell.lucide :as lucide]
[tyrell.heroicons.outline :as ho]))
(defnregister-icons! []
(icons/register!
{:check lucide/check
:search lucide/search
:user ho/user-circle}))

Shadow-cljs :advanced removes unused icons automatically — you only pay for what you reference. See CLOJURESCRIPT_GUIDE → Icon registration.

Build Your Own Components

Use tyrell.shim to turn any ClojureScript render function into a Web Component:

(nsapp.components
(:require [replicant.dom :as d]
[tyrell.shim :as shim]))
(defngreeting [name]
[:div.ty-elevated.p-4.rounded-lg
[:h2.ty-text+"Hello, " name "!"]
[:ty-button {:flavor"primary"} "Wave"]])
(defnrender! [^js el]
(d/render (shim/ensure-shadow el)
(greeting (or (shim/attr el "name") "World"))))
(shim/define!"my-greeting"
{:observed [:name]
:connected render!
:attr (fn [el _] (render! el))})
<my-greetingname="Clojure"></my-greeting>

Component Building Guide → | Code Splitting →


Components

ComponentDescription
ty-buttonSemantic buttons with flavors, sizes, and icon slots
ty-inputText input with labels, validation, numeric formatting, debounce
ty-textareaMulti-line text with auto-resize and character count
ty-checkboxStyled checkbox with indeterminate state
ty-switchToggle switch primitive
ty-radio-group / ty-radioExclusive single-choice selection
ty-select / ty-optionTHE select control — single by default, multiple for multi-select, searchable popup
ty-selected-optionsOut-of-band dismissible chips for a ty-select selection
ty-calendarFull calendar with date selection and form integration
ty-date-pickerCalendar dropdown for date input
ty-tabs / ty-tabCarousel tabs with smooth animations
ty-wizard / ty-stepStep-by-step wizard with progress tracking
ty-modalNative dialog with backdrop and focus management
ty-popupAnchored popover with smart positioning
ty-tooltipHover tooltips with placement options
ty-iconSVG icons from Lucide, Heroicons, Material, FontAwesome
ty-tagRemovable tags for selections
ty-copyClick-to-copy with visual feedback
ty-scroll-containerScrollable area with fade indicators
ty-resize-observerSelf-observing element with debounce

See all components in action →


Links


MIT License

About

Clojurescript WebComponents library

Topics

Resources

Stars

32 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages