Skip to content

KUIejs

GitHubJavaScriptui/ux / web

Most UI component work today happens inside React. The tooling, the design systems, the showcase infrastructure — all built around the assumption of a JavaScript-heavy runtime. Yet a significant category of products runs on server-rendered HTML: embedded device management panels, enterprise admin tools, invoice systems, email templates. These products need a coherent component story too, and almost nothing exists to serve them.

EJS Components Showcase is a deliberate attempt to build that story. It takes the discipline of a modern component system — layered architecture, design tokens, variant contracts, CI enforcement, accessibility standards — and applies it to server-side templating without compromise.

The Problem With "Just Use EJS"

EJS is often treated as a dumping ground. Templates grow without structure. Styles are duplicated across files. Data gets embedded directly in views. Partials accumulate without anyone knowing which ones are still used. The result is a codebase that works until it doesn't, and then becomes very hard to reason about.

The question this project asks is: what does a well-engineered EJS codebase look like? What does it mean to have a component system without React — real consistency, real constraints, real tooling?

A Four-Layer Architecture

The project enforces a strict dependency direction through four layers, each building on the one below.

modules/ui holds generic atoms and molecules: Button, Input, Modal, DataTable, Badge, Toast, Stepper, VideoPlayer, MapView, and around twenty others. These partials know nothing about the domain. They accept typed locals, render consistent markup, and expose a variant system where every visual permutation is driven by a lookup table at the top of the partial — not scattered class strings.

modules/app composes ui atoms into application-level shells: AppShell, AppSidebar, AppTopBar, AppCommandBar, FilterBar, GlobalSearch, Form, ErrorState, LoadingState. This layer builds the scaffolding that every theme will eventually sit inside.

modules/domain contains industry-specific compositions: auth forms, cart components, payment panels, invoice blocks, address selectors, currency displays, modem status cards, UPS outlet controls, API documentation components, and a full email template system. This is where product specificity lives — not in the primitives below it.

views/themes assembles these layers into complete, multi-page product experiences with realistic sample data. The themes demonstrate that the component system scales from a single component to a real user journey.

The Themes

The themes are the project's most concrete output, and they deliberately target domains that rarely appear in showcase portfolios.

The modem admin panel is a full-featured network device management interface with thirteen pages: dashboard, Wi-Fi configuration, connected devices, firewall rules, NAT port forwarding, QoS policies, parental controls, VPN instances, and system settings. Each page is a realistic representation of an embedded device UI.

The UPS management panel covers battery status, power load gauges, outlet control, and event logs — the kind of interface that runs on industrial power management hardware.

The invoice system handles invoice listing, detail view, and print layout, with client information blocks, line items, payment terms, and status management.

The common theme provides shared flows that appear across most web products: a complete authentication surface (login, register, forgot password, 2FA, email verification), account management pages, cart and checkout flows, and a full transactional email template library covering auth, billing, order, support, marketing, and system notification scenarios.

The API documentation theme is a server-rendered Swagger-style interface with endpoint listings, operation panels, parameter tables, response cards, schema viewers, and HTTP method badges.

Engineering Rigor

What distinguishes this project from a folder of EJS files is the engineering discipline applied to it.

A CSS variable token contract is enforced at the CI level. Every color, spacing reference, and design decision flows through semantic tokens defined in input.css. A shell script audits every .ejs and .ts file and fails the build if any raw hex value or arbitrary spacing unit appears outside the allowlist.

The escaped output policy treats <%- %> — EJS's raw unescaped output tag — as a security-significant decision. Every usage site is documented in an allowlist with a justification. A CI script verifies that no new unescaped usages appear without review.

A dead partial detector scans the entire modules/ and views/partials/ directories, extracts every include() call, and reports any partial not referenced anywhere. Running it reveals which components are load-bearing and which are safe to remove.

Dark mode is handled with an inline anti-flash script injected before first paint, reading localStorage.theme before any CSS loads. Asset versioning computes an MD5 hash of the compiled CSS at startup and appends it as a cache-busting query parameter. The component showcase itself includes sidebar search, layout switching, source code preview with copy, and per-component status badges (stable, beta, deprecated) — all without a client-side framework.

The Larger Context

This project is the server-rendered parallel to a Next.js component library developed alongside it. The two share vocabulary — the same token names, the same four-layer dependency model, the same component status system, the same CI audit concepts — but are implemented entirely differently. Where the Next.js project uses React, hooks, and Zustand, this one uses EJS includes, CSS-only responsive design, and vanilla JavaScript for the handful of interactions that genuinely require it.

The parallel is intentional. It demonstrates that component system discipline is not a React concept. It is an architecture concept.

Newsletter

Stay updated! Get all the latest and greatest posts delivered straight to your inbox