Template reference Color tokens, utility classes, and EJS helpers available when building a custom collector panel template.
All profiler templates share a single design system based on Tailwind CSS 4 (loaded via CDN) and a set of semantic CSS custom properties defined in _head.ejs. Any .ejs template registered through a custom collector automatically has access to every class and helper described here.
Building your first custom collector? Follow the Build a custom
collector tutorial first, then come back here as a reference
while writing your EJS template.
Tokens adapt automatically to the light/dark theme. Use the Tailwind utility name (e.g. text-foreground) in your template — never hardcode hex values.
Tailwind class Purpose bg-backgroundPage background bg-surfaceCard / panel background bg-surface-mutedDimmed surface (table header, code block background) bg-surface-activeActive / selected surface
Tailwind class Purpose text-foregroundPrimary content text text-foreground-secondarySecondary content (metadata, values) text-foreground-mutedLabels, column headers text-foreground-faintTimestamps, disabled states, placeholders
Tailwind class Purpose border-lineDefault border (cards, tables) border-line-subtleRow divider inside a table border-line-activeFocused / highlighted border
Tailwind class Purpose text-danger / bg-danger-bg / border-danger-lineError state — text, background, border border-danger-line-subtleSubtle danger border (stack trace separator) text-successSuccess state text-code-textMonospace code content
Tailwind class Purpose text-nest / bg-nest / border-nestNestJS brand red — active tab indicator, accent text-nest-lightLighter brand red for hover text-nest-darkDarker brand red for pressed states
Class Value Purpose text-2xs0.625rem (10px)Smallest label size — column headers, badges text-xs0.75rem (12px)Primary content in tables and panels font-mono— Monospace font for code, identifiers, URLs
Ready-to-use semantic badges. Apply them on a <span> together with px-1.5 py-0.5 rounded text-2xs font-bold tracking-wide.
Class Colour Use for badge-getGreen GET / read operations badge-postBlue POST / insert operations badge-putAmber PUT / update operations badge-patchOrange PATCH / partial update badge-deleteRed DELETE / remove operations badge-headPurple HEAD operations badge-optionsSlate OPTIONS operations badge-defaultSlate Unknown / fallback
Class Use for badge-2xx2xx success responses badge-3xx3xx redirects badge-4xx4xx client errors badge-5xx5xx server errors
Class Use for badge-logLOG badge-warnWARN badge-errorERROR badge-debugDEBUG badge-verboseVERBOSE badge-fatalFATAL
Colour-code a duration value based on thresholds.
Class Condition Colour dur-fast< 100 msGreen dur-medium100 – 500 msAmber dur-slow> 500 msRed dur-noneUnknown / undefined Faint grey
<%
const cls = dur < 100 ? 'dur-fast' : dur < 500 ? 'dur-medium' : 'dur-slow' ;
%>
< span class = "<%= cls %> text-xl font-bold tabular-nums" ><%= dur %>ms</ span >
These functions are automatically injected into every template.
Helper Signature Description toJson(value) → stringPretty-prints any value as indented JSON isoDate(timestamp: number) → stringFormats a Unix ms timestamp as YYYY-MM-DD HH:MM:SS timeOnly(timestamp: number) → stringFormats a Unix ms timestamp as HH:MM:SS.mmm highlightSql(sql: string) → HTML stringWraps SQL keywords in <span class="sql-keyword"> — use with <%- methodClass(method: string) → stringReturns the correct badge-* class for an HTTP method statusClass(status: number) → stringReturns the correct badge-* class for an HTTP status code logLevelClass(level: string) → stringReturns the correct badge-* class for a log level mb(bytes: number) → stringConverts bytes to a human-readable X.XX MB string kvTable(data: Record<string, unknown>) → HTML stringRenders a key/value table — use with <%-
< div class = "py-8 text-center bg-surface-muted border border-line rounded-lg" >
< p class = "text-foreground-muted text-sm" >No entries for this request.</ p >
</ div >
< div class = "flex items-center gap-4 text-xs text-foreground-muted mb-4" >
< span >< strong class = "text-foreground" ><%= items. length %></ strong > entries</ span >
< span >< strong class = "text-foreground" ><%= totalDuration %></ strong >ms total</ span >
</ div >
< div class = "rounded-lg border border-line overflow-hidden" >
< table class = "w-full" >
< thead >
< tr class = "bg-surface-muted border-b border-line" >
< th class = "text-left py-2.5 px-4 text-foreground-muted font-medium text-2xs uppercase tracking-widest" >Name</ th >
< th class = "text-right py-2.5 px-4 text-foreground-muted font-medium text-2xs uppercase tracking-widest w-24" >Duration</ th >
< th class = "text-left py-2.5 px-4 text-foreground-muted font-medium text-2xs uppercase tracking-widest w-20" >Time</ th >
</ tr >
</ thead >
< tbody class = "divide-y divide-line-subtle" >
<% for ( const item of items) { %>
< tr class = "hover:bg-surface-muted transition-colors" >
< td class = "py-2 px-4 text-foreground text-xs" ><%= item.name %></ td >
< td class = "py-2 px-4 text-right text-foreground-secondary text-xs tabular-nums" ><%= item.duration %>ms</ td >
< td class = "py-2 px-4 text-foreground-faint text-2xs tabular-nums" ><%= timeOnly(item.startedAt) %></ td >
</ tr >
<% } %>
</ tbody >
</ table >
</ div >
< span class = "px-1.5 py-0.5 rounded text-2xs font-bold tracking-wide badge-get" >GET</ span >
< pre class = "bg-surface-muted border border-line rounded-lg p-4 text-xs overflow-x-auto leading-relaxed" >
< code class = "language-json" ><%= toJson (value) %></ code >
</ pre >
Highlight.js runs automatically on DOMContentLoaded — any <code class="language-*"> block is highlighted.
< code class = "text-xs text-code-text leading-relaxed break-all" >
<%- highlightSql (query.sql) %>
</ code >
< style > .sql-keyword { color : #818cf8 ; font-weight : 600 ; }</ style >
<% if (item.error) { %>
< div class = "mt-1 text-danger text-2xs" >Error: <%= item.error %></ div >
<% } %>
< section class = "mb-6" >
< h2 class = "text-foreground-muted text-2xs uppercase tracking-widest font-semibold mb-3" >
My Section
</ h2 >
<!-- content -->
</ section >
All semantic token classes (text-foreground, bg-surface, border-line, badge classes, duration classes) adapt automatically — no extra dark: variants needed. When you need Tailwind colour palette classes (e.g. bg-blue-100) always add the corresponding dark: variant:
< span class = "bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300" >
INFO
</ span >